From ed2c974b5209848e1ebd7335c6d89827cc54938f Mon Sep 17 00:00:00 2001 From: Brennan Lamey <66885902+brennanjl@users.noreply.github.com> Date: Wed, 22 May 2024 12:18:44 -0500 Subject: [PATCH] Refactor parse (#728) * basic types and decimal package * unified parsers into single grammar * trying out new visitors * added ordering, aggregate checks * added better documentation * added generation, removed unused * rebase * bug fixes * working tests, addressed gavins feedback * added support for unnamed returns * wasm changes * fixed lint * pglive build tag --- cmd/kwil-cli/cmds/database/deploy.go | 2 +- cmd/kwil-cli/cmds/utils/parse.go | 4 +- core/go.mod | 3 + core/go.sum | 6 + core/types/decimal/decimal.go | 386 + core/types/decimal/decimal_test.go | 470 + core/types/schema.go | 177 +- core/types/validation/keywords.go | 3 + go.mod | 3 +- go.sum | 4 + internal/engine/ddl/procedure.go | 128 - internal/engine/execution/global.go | 39 +- internal/engine/execution/procedure.go | 78 +- internal/engine/execution/queries.go | 32 +- internal/engine/generate/actions.go | 177 + .../{ddl => generate}/foreign_procedure.go | 6 +- .../foreign_procedure_test.go | 8 +- internal/engine/{ddl => generate}/generate.go | 2 +- .../engine/{ddl => generate}/generate_test.go | 10 +- internal/engine/{ddl => generate}/index.go | 2 +- internal/engine/generate/metadata.go | 8 + internal/engine/generate/plpgsql.go | 992 + internal/engine/generate/procedure.go | 268 + .../{ddl => generate}/procedure_test.go | 20 +- internal/engine/generate/sql.go | 27 + internal/engine/{ddl => generate}/table.go | 2 +- internal/engine/{ddl => generate}/utils.go | 2 +- .../engine/integration/deployment_test.go | 30 +- internal/engine/integration/procedure_test.go | 200 + internal/engine/integration/schema_test.go | 10 +- .../integration/schemas/social_media.kf | 19 +- .../engine/integration/schemas/video_game.kf | 8 +- internal/sql/pg/db.go | 4 + internal/sql/pg/sql.go | 15 + parse/actions.go | 65 + parse/actions/actions.go | 288 - parse/actions/gen/action_lexer.go | 272 - parse/actions/gen/action_parser.go | 2721 --- .../actions/gen/actionparser_base_visitor.go | 68 - parse/actions/gen/actionparser_visitor.go | 54 - parse/actions/grammar/ActionLexer.g4 | 80 - parse/actions/grammar/ActionParser.g4 | 122 - parse/actions/grammar/generate.sh | 19 - parse/actions/parser/ast_builder.go | 358 - parse/actions/parser/parser.go | 73 - parse/actions/parser/parser_test.go | 272 - parse/actions/parser/statement.go | 44 - parse/analyze.go | 2488 ++ parse/analyze_test.go | 29 + parse/antlr.go | 1998 ++ parse/ast.go | 1139 + parse/contextual.go | 31 + parse/errors.go | 254 + parse/{metadata => }/functions.go | 208 +- parse/gen/kuneiform_lexer.go | 727 + parse/gen/kuneiform_parser.go | 19902 ++++++++++++++++ parse/gen/kuneiformparser_base_visitor.go | 440 + parse/gen/kuneiformparser_visitor.go | 333 + parse/go.mod | 2 + parse/go.sum | 10 + parse/grammar/KuneiformLexer.g4 | 179 + parse/grammar/KuneiformParser.g4 | 388 + parse/{kuneiform => }/grammar/generate.sh | 0 parse/kuneiform/.gitignore | 6 - parse/kuneiform/gen/kuneiform_lexer.go | 492 - parse/kuneiform/gen/kuneiform_parser.go | 5610 ----- .../gen/kuneiformparser_base_visitor.go | 124 - .../kuneiform/gen/kuneiformparser_visitor.go | 96 - parse/kuneiform/grammar/KuneiformLexer.g4 | 141 - parse/kuneiform/grammar/KuneiformParser.g4 | 136 - parse/kuneiform/parser.go | 635 - parse/kuneiform/parser_test.go | 647 - parse/metadata/metadata.go | 38 - parse/parse.go | 409 +- parse/parse_test.go | 1594 ++ parse/{sql => }/postgres/doc.go | 0 parse/{sql => }/postgres/parse.go | 0 parse/{sql => }/postgres/parse_cgo.go | 0 parse/{sql => }/postgres/parse_test.go | 2 +- parse/procedures/gen/procedure_lexer.go | 320 - parse/procedures/gen/procedure_parser.go | 4526 ---- .../gen/procedureparser_base_visitor.go | 140 - .../procedures/gen/procedureparser_visitor.go | 108 - parse/procedures/grammar/ProcedureLexer.g4 | 90 - parse/procedures/grammar/ProcedureParser.g4 | 79 - parse/procedures/grammar/generate.sh | 21 - parse/procedures/parser/parser.go | 88 - parse/procedures/parser/parser_test.go | 165 - parse/procedures/parser/tree.go | 564 - parse/procedures/parser/visitor.go | 634 - parse/procedures/procedures.go | 153 - parse/procedures/procedures_test.go | 537 - parse/procedures/visitors/clean/clean.go | 342 - .../procedures/visitors/generate/generate.go | 82 - parse/procedures/visitors/generate/visitor.go | 497 - .../procedures/visitors/traverse/traverse.go | 286 - parse/procedures/visitors/typing/typing.go | 946 - .../procedures/visitors/typing/typing_test.go | 115 - parse/sql/ast_builder.go | 1326 - parse/sql/error.go | 10 - parse/sql/error_listener.go | 80 - parse/sql/gen/sql_lexer.go | 553 - parse/sql/gen/sql_parser.go | 13050 ---------- parse/sql/gen/sqlparser_base_visitor.go | 320 - parse/sql/gen/sqlparser_visitor.go | 243 - parse/sql/grammar/SQLLexer.g4 | 156 - parse/sql/grammar/SQLParser.g4 | 393 - parse/sql/grammar/generate.sh | 19 - parse/sql/parser.go | 101 - parse/sql/parser_test.go | 2644 -- parse/sql/sqlanalyzer/analyzer.go | 169 - parse/sql/sqlanalyzer/analyzer_test.go | 210 - parse/sql/sqlanalyzer/clean/clean.go | 55 - parse/sql/sqlanalyzer/clean/errors.go | 35 - parse/sql/sqlanalyzer/clean/walker.go | 452 - parse/sql/sqlanalyzer/join/errors.go | 7 - parse/sql/sqlanalyzer/join/joins.go | 123 - parse/sql/sqlanalyzer/join/visitor.go | 27 - .../sql/sqlanalyzer/mutative/mutative_test.go | 59 - parse/sql/sqlanalyzer/mutative/walker.go | 31 - parse/sql/sqlanalyzer/mutativity.go | 20 - parse/sql/sqlanalyzer/order/README.md | 28 - parse/sql/sqlanalyzer/order/order.go | 484 - parse/sql/sqlanalyzer/order/order_test.go | 290 - parse/sql/sqlanalyzer/parameters/rename.go | 16 - parse/sql/sqlanalyzer/parameters/visitor.go | 47 - .../sqlanalyzer/parameters/visitor_test.go | 106 - parse/sql/sqlanalyzer/schema/walker.go | 82 - parse/sql/sqlanalyzer/schema/walker_test.go | 86 - parse/sql/sqlanalyzer/typing/errors.go | 12 - parse/sql/sqlanalyzer/typing/relation.go | 169 - parse/sql/sqlanalyzer/typing/typing.go | 290 - parse/sql/sqlanalyzer/typing/visitor.go | 1215 - parse/sql/sqlanalyzer/typing/visitor_test.go | 494 - parse/sql/sqlanalyzer/utils/column_search.go | 68 - parse/sql/sqlanalyzer/utils/utils.go | 55 - parse/sql/sqlanalyzer/utils/utils_test.go | 96 - parse/sql/tree/CTE.go | 45 - parse/sql/tree/CTE_test.go | 80 - parse/sql/tree/README.md | 828 - parse/sql/tree/ast.go | 36 - parse/sql/tree/ast_listener.go | 1366 -- parse/sql/tree/ast_visitor.go | 258 - parse/sql/tree/collate.go | 39 - parse/sql/tree/conflict-target.go | 42 - parse/sql/tree/conflict-target_test.go | 108 - parse/sql/tree/delete.go | 90 - parse/sql/tree/delete_test.go | 63 - parse/sql/tree/expression-join.go | 151 - parse/sql/tree/expression.go | 843 - parse/sql/tree/expression_test.go | 813 - parse/sql/tree/expressions.md | 318 - parse/sql/tree/group-by.go | 47 - parse/sql/tree/group-by_test.go | 76 - parse/sql/tree/indexed-column.go | 45 - parse/sql/tree/indexed-column_test.go | 84 - parse/sql/tree/insert.go | 176 - parse/sql/tree/insert_test.go | 241 - parse/sql/tree/join.go | 164 - parse/sql/tree/limit.go | 46 - parse/sql/tree/limit_test.go | 66 - parse/sql/tree/operators.go | 131 - parse/sql/tree/order-by.go | 132 - parse/sql/tree/order-by_test.go | 72 - parse/sql/tree/qualified-table-name.go | 63 - parse/sql/tree/qualified-table-name_test.go | 71 - parse/sql/tree/relation.go | 188 - parse/sql/tree/relation_test.go | 251 - parse/sql/tree/result-column.go | 83 - parse/sql/tree/result-column_test.go | 54 - parse/sql/tree/returning-clause.go | 77 - parse/sql/tree/returning-clause_test.go | 88 - parse/sql/tree/select.go | 224 - parse/sql/tree/select_test.go | 88 - parse/sql/tree/sql-writer/tokens.go | 384 - parse/sql/tree/sql-writer/writer.go | 89 - parse/sql/tree/sql-writer/writer_test.go | 29 - parse/sql/tree/update-set-clause.go | 51 - parse/sql/tree/update.go | 108 - parse/sql/tree/update_test.go | 92 - parse/sql/tree/upsert.go | 75 - parse/sql/tree/upsert_test.go | 86 - parse/sql/tree/utils.go | 20 - parse/sql/tree/utils_test.go | 26 - parse/sql/tree/walker.go | 48 - parse/types.go | 206 + parse/types/error_listener.go | 189 - parse/types/errors.go | 42 - parse/types/types.go | 198 - parse/util/procedure.go | 84 - parse/util/util.go | 24 - parse/util/util_test.go | 29 - parse/wasm/wasm.go | 12 +- .../test-data/invalid_sql_syntax.kf | 2 + .../test-data/invalid_sql_syntax_fixed.kf | 2 +- test/acceptance/test-data/test_db.kf | 8 +- test/acceptance/test-data/users.kf | 10 +- test/go.mod | 1 + test/go.sum | 3 + test/integration/kwild_test.go | 2 +- test/integration/test-data/dummy.kf | 4 +- .../test-data/invalid_sql_syntax_fixed.kf | 2 +- test/integration/test-data/test_db.kf | 2 +- test/specifications/utils.go | 9 +- test/stress/scheme.go | 2 +- 205 files changed, 33181 insertions(+), 55158 deletions(-) create mode 100644 core/types/decimal/decimal.go create mode 100644 core/types/decimal/decimal_test.go delete mode 100644 internal/engine/ddl/procedure.go create mode 100644 internal/engine/generate/actions.go rename internal/engine/{ddl => generate}/foreign_procedure.go (98%) rename internal/engine/{ddl => generate}/foreign_procedure_test.go (93%) rename internal/engine/{ddl => generate}/generate.go (97%) rename internal/engine/{ddl => generate}/generate_test.go (96%) rename internal/engine/{ddl => generate}/index.go (98%) create mode 100644 internal/engine/generate/metadata.go create mode 100644 internal/engine/generate/plpgsql.go create mode 100644 internal/engine/generate/procedure.go rename internal/engine/{ddl => generate}/procedure_test.go (82%) create mode 100644 internal/engine/generate/sql.go rename internal/engine/{ddl => generate}/table.go (99%) rename internal/engine/{ddl => generate}/utils.go (98%) create mode 100644 internal/engine/integration/procedure_test.go create mode 100644 parse/actions.go delete mode 100644 parse/actions/actions.go delete mode 100644 parse/actions/gen/action_lexer.go delete mode 100644 parse/actions/gen/action_parser.go delete mode 100644 parse/actions/gen/actionparser_base_visitor.go delete mode 100644 parse/actions/gen/actionparser_visitor.go delete mode 100644 parse/actions/grammar/ActionLexer.g4 delete mode 100644 parse/actions/grammar/ActionParser.g4 delete mode 100755 parse/actions/grammar/generate.sh delete mode 100644 parse/actions/parser/ast_builder.go delete mode 100644 parse/actions/parser/parser.go delete mode 100644 parse/actions/parser/parser_test.go delete mode 100644 parse/actions/parser/statement.go create mode 100644 parse/analyze.go create mode 100644 parse/analyze_test.go create mode 100644 parse/antlr.go create mode 100644 parse/ast.go create mode 100644 parse/contextual.go create mode 100644 parse/errors.go rename parse/{metadata => }/functions.go (55%) create mode 100644 parse/gen/kuneiform_lexer.go create mode 100644 parse/gen/kuneiform_parser.go create mode 100644 parse/gen/kuneiformparser_base_visitor.go create mode 100644 parse/gen/kuneiformparser_visitor.go create mode 100644 parse/grammar/KuneiformLexer.g4 create mode 100644 parse/grammar/KuneiformParser.g4 rename parse/{kuneiform => }/grammar/generate.sh (100%) delete mode 100644 parse/kuneiform/.gitignore delete mode 100644 parse/kuneiform/gen/kuneiform_lexer.go delete mode 100644 parse/kuneiform/gen/kuneiform_parser.go delete mode 100644 parse/kuneiform/gen/kuneiformparser_base_visitor.go delete mode 100644 parse/kuneiform/gen/kuneiformparser_visitor.go delete mode 100644 parse/kuneiform/grammar/KuneiformLexer.g4 delete mode 100644 parse/kuneiform/grammar/KuneiformParser.g4 delete mode 100644 parse/kuneiform/parser.go delete mode 100644 parse/kuneiform/parser_test.go delete mode 100644 parse/metadata/metadata.go create mode 100644 parse/parse_test.go rename parse/{sql => }/postgres/doc.go (100%) rename parse/{sql => }/postgres/parse.go (100%) rename parse/{sql => }/postgres/parse_cgo.go (100%) rename parse/{sql => }/postgres/parse_test.go (84%) delete mode 100644 parse/procedures/gen/procedure_lexer.go delete mode 100644 parse/procedures/gen/procedure_parser.go delete mode 100644 parse/procedures/gen/procedureparser_base_visitor.go delete mode 100644 parse/procedures/gen/procedureparser_visitor.go delete mode 100644 parse/procedures/grammar/ProcedureLexer.g4 delete mode 100644 parse/procedures/grammar/ProcedureParser.g4 delete mode 100755 parse/procedures/grammar/generate.sh delete mode 100644 parse/procedures/parser/parser.go delete mode 100644 parse/procedures/parser/parser_test.go delete mode 100644 parse/procedures/parser/tree.go delete mode 100644 parse/procedures/parser/visitor.go delete mode 100644 parse/procedures/procedures.go delete mode 100644 parse/procedures/procedures_test.go delete mode 100644 parse/procedures/visitors/clean/clean.go delete mode 100644 parse/procedures/visitors/generate/generate.go delete mode 100644 parse/procedures/visitors/generate/visitor.go delete mode 100644 parse/procedures/visitors/traverse/traverse.go delete mode 100644 parse/procedures/visitors/typing/typing.go delete mode 100644 parse/procedures/visitors/typing/typing_test.go delete mode 100644 parse/sql/ast_builder.go delete mode 100644 parse/sql/error.go delete mode 100644 parse/sql/error_listener.go delete mode 100644 parse/sql/gen/sql_lexer.go delete mode 100644 parse/sql/gen/sql_parser.go delete mode 100644 parse/sql/gen/sqlparser_base_visitor.go delete mode 100644 parse/sql/gen/sqlparser_visitor.go delete mode 100644 parse/sql/grammar/SQLLexer.g4 delete mode 100644 parse/sql/grammar/SQLParser.g4 delete mode 100755 parse/sql/grammar/generate.sh delete mode 100644 parse/sql/parser.go delete mode 100644 parse/sql/parser_test.go delete mode 100644 parse/sql/sqlanalyzer/analyzer.go delete mode 100644 parse/sql/sqlanalyzer/analyzer_test.go delete mode 100644 parse/sql/sqlanalyzer/clean/clean.go delete mode 100644 parse/sql/sqlanalyzer/clean/errors.go delete mode 100644 parse/sql/sqlanalyzer/clean/walker.go delete mode 100644 parse/sql/sqlanalyzer/join/errors.go delete mode 100644 parse/sql/sqlanalyzer/join/joins.go delete mode 100644 parse/sql/sqlanalyzer/join/visitor.go delete mode 100644 parse/sql/sqlanalyzer/mutative/mutative_test.go delete mode 100644 parse/sql/sqlanalyzer/mutative/walker.go delete mode 100644 parse/sql/sqlanalyzer/mutativity.go delete mode 100644 parse/sql/sqlanalyzer/order/README.md delete mode 100644 parse/sql/sqlanalyzer/order/order.go delete mode 100644 parse/sql/sqlanalyzer/order/order_test.go delete mode 100644 parse/sql/sqlanalyzer/parameters/rename.go delete mode 100644 parse/sql/sqlanalyzer/parameters/visitor.go delete mode 100644 parse/sql/sqlanalyzer/parameters/visitor_test.go delete mode 100644 parse/sql/sqlanalyzer/schema/walker.go delete mode 100644 parse/sql/sqlanalyzer/schema/walker_test.go delete mode 100644 parse/sql/sqlanalyzer/typing/errors.go delete mode 100644 parse/sql/sqlanalyzer/typing/relation.go delete mode 100644 parse/sql/sqlanalyzer/typing/typing.go delete mode 100644 parse/sql/sqlanalyzer/typing/visitor.go delete mode 100644 parse/sql/sqlanalyzer/typing/visitor_test.go delete mode 100644 parse/sql/sqlanalyzer/utils/column_search.go delete mode 100644 parse/sql/sqlanalyzer/utils/utils.go delete mode 100644 parse/sql/sqlanalyzer/utils/utils_test.go delete mode 100644 parse/sql/tree/CTE.go delete mode 100644 parse/sql/tree/CTE_test.go delete mode 100644 parse/sql/tree/README.md delete mode 100644 parse/sql/tree/ast.go delete mode 100644 parse/sql/tree/ast_listener.go delete mode 100644 parse/sql/tree/ast_visitor.go delete mode 100644 parse/sql/tree/collate.go delete mode 100644 parse/sql/tree/conflict-target.go delete mode 100644 parse/sql/tree/conflict-target_test.go delete mode 100644 parse/sql/tree/delete.go delete mode 100644 parse/sql/tree/delete_test.go delete mode 100644 parse/sql/tree/expression-join.go delete mode 100644 parse/sql/tree/expression.go delete mode 100644 parse/sql/tree/expression_test.go delete mode 100644 parse/sql/tree/expressions.md delete mode 100644 parse/sql/tree/group-by.go delete mode 100644 parse/sql/tree/group-by_test.go delete mode 100644 parse/sql/tree/indexed-column.go delete mode 100644 parse/sql/tree/indexed-column_test.go delete mode 100644 parse/sql/tree/insert.go delete mode 100644 parse/sql/tree/insert_test.go delete mode 100644 parse/sql/tree/join.go delete mode 100644 parse/sql/tree/limit.go delete mode 100644 parse/sql/tree/limit_test.go delete mode 100644 parse/sql/tree/operators.go delete mode 100644 parse/sql/tree/order-by.go delete mode 100644 parse/sql/tree/order-by_test.go delete mode 100644 parse/sql/tree/qualified-table-name.go delete mode 100644 parse/sql/tree/qualified-table-name_test.go delete mode 100644 parse/sql/tree/relation.go delete mode 100644 parse/sql/tree/relation_test.go delete mode 100644 parse/sql/tree/result-column.go delete mode 100644 parse/sql/tree/result-column_test.go delete mode 100644 parse/sql/tree/returning-clause.go delete mode 100644 parse/sql/tree/returning-clause_test.go delete mode 100644 parse/sql/tree/select.go delete mode 100644 parse/sql/tree/select_test.go delete mode 100644 parse/sql/tree/sql-writer/tokens.go delete mode 100644 parse/sql/tree/sql-writer/writer.go delete mode 100644 parse/sql/tree/sql-writer/writer_test.go delete mode 100644 parse/sql/tree/update-set-clause.go delete mode 100644 parse/sql/tree/update.go delete mode 100644 parse/sql/tree/update_test.go delete mode 100644 parse/sql/tree/upsert.go delete mode 100644 parse/sql/tree/upsert_test.go delete mode 100644 parse/sql/tree/utils.go delete mode 100644 parse/sql/tree/utils_test.go delete mode 100644 parse/sql/tree/walker.go create mode 100644 parse/types.go delete mode 100644 parse/types/error_listener.go delete mode 100644 parse/types/errors.go delete mode 100644 parse/types/types.go delete mode 100644 parse/util/procedure.go delete mode 100644 parse/util/util.go delete mode 100644 parse/util/util_test.go diff --git a/cmd/kwil-cli/cmds/database/deploy.go b/cmd/kwil-cli/cmds/database/deploy.go index af200df24..34f7dd4da 100644 --- a/cmd/kwil-cli/cmds/database/deploy.go +++ b/cmd/kwil-cli/cmds/database/deploy.go @@ -98,7 +98,7 @@ func UnmarshalKf(file *os.File) (*types.Schema, error) { return nil, fmt.Errorf("failed to read Kuneiform source file: %w", err) } - res, err := parse.ParseKuneiform(string(source)) + res, err := parse.ParseAndValidate(source) if err != nil { return nil, fmt.Errorf("failed to parse Kuneiform source file: %w", err) } diff --git a/cmd/kwil-cli/cmds/utils/parse.go b/cmd/kwil-cli/cmds/utils/parse.go index 2cc07d652..3fbf4db3a 100644 --- a/cmd/kwil-cli/cmds/utils/parse.go +++ b/cmd/kwil-cli/cmds/utils/parse.go @@ -26,7 +26,7 @@ func newParseCmd() *cobra.Command { return display.PrintErr(cmd, err) } - res, err := parse.ParseKuneiform(string(file)) + res, err := parse.ParseAndValidate(file) if err != nil { return display.PrintErr(cmd, err) } @@ -41,7 +41,7 @@ func newParseCmd() *cobra.Command { // schemaDisplay is a struct that will be used to display the schema. // It includes an error because the parser can return a schema even if there is an error. type schemaDisplay struct { - Result *parse.ParseResult + Result *parse.SchemaParseResult } func (s *schemaDisplay) MarshalJSON() ([]byte, error) { diff --git a/core/go.mod b/core/go.mod index 5bafdccce..0fb9304a0 100644 --- a/core/go.mod +++ b/core/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/antihax/optional v1.0.0 + github.com/cockroachdb/apd/v3 v3.2.1 github.com/cstockton/go-conv v1.0.0 github.com/decred/dcrd/certgen v1.1.2 github.com/ethereum/go-ethereum v1.14.3 @@ -17,6 +18,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.1 + gotest.tools v2.2.0+incompatible ) require ( @@ -30,6 +32,7 @@ require ( github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/supranational/blst v0.3.11 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/core/go.sum b/core/go.sum index 262873f6e..72f33f901 100644 --- a/core/go.sum +++ b/core/go.sum @@ -16,6 +16,8 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOF github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= @@ -81,6 +83,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= @@ -153,5 +157,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/core/types/decimal/decimal.go b/core/types/decimal/decimal.go new file mode 100644 index 000000000..fa23c553c --- /dev/null +++ b/core/types/decimal/decimal.go @@ -0,0 +1,386 @@ +// package Decimal implements a fixed-point decimal number. +// It is mostly a wrapper around github.com/cockroachdb/apd/v3, with some +// functionality that makes it easier to use in the context of Kwil. It enforces +// certain semantics of Postgres's decimal, such as precision and scale. +package decimal + +import ( + "database/sql" + "database/sql/driver" + "encoding/binary" + "fmt" + "strings" + + "github.com/cockroachdb/apd/v3" +) + +var ( + // context is the default context for the decimal. + // We can change this to have different precision/speed properties, + // but for now have it set to favor precision. + context = apd.Context{ + Precision: 1000, + MaxExponent: 2000, + MinExponent: -2000, + Traps: apd.DefaultTraps, + Rounding: apd.RoundHalfUp, + } +) + +// Decimal is a decimal number. It has a set precision and scale that +// will be used on all mathematical operations that are methods of the +// Decimal type. To perform mathematical operations with maximum precision +// and scale, use the math functions in this package instead of the methods. +type Decimal struct { + dec apd.Decimal + scale uint16 + precision uint16 +} + +// NewExplicit creates a new Decimal from a string, with an explicit precision and scale. +// The precision must be between 1 and 1000, and the scale must be between 0 and precision. +func NewExplicit(s string, precision, scale uint16) (*Decimal, error) { + dec := &Decimal{} + + if err := dec.SetPrecisionAndScale(precision, scale); err != nil { + return nil, err + } + + if err := dec.SetString(s); err != nil { + return nil, err + } + + return dec, nil +} + +// NewFromString creates a new Decimal from a string. It automatically infers the precision and scale. +func NewFromString(s string) (*Decimal, error) { + inferredPrecision, inferredScale := inferPrecisionAndScale(s) + + return NewExplicit(s, inferredPrecision, inferredScale) +} + +// SetString sets the value of the decimal from a string. +func (d *Decimal) SetString(s string) error { + res, _, err := d.context().NewFromString(s) + if err != nil { + return err + } + + d.dec = *res + + if err := d.enforceScale(); err != nil { + return err + } + + return nil +} + +// inferPrecisionAndScale infers the precision and scale from a string. +func inferPrecisionAndScale(s string) (precision, scale uint16) { + s = strings.TrimLeft(s, "-+") + parts := strings.Split(s, ".") + + // remove 0s from the left part, siince 001.23 is the same as 1.23 + parts[0] = strings.TrimLeft(parts[0], "0") + + intPart := uint16(len(parts[0])) + if len(parts) == 1 { + return intPart, 0 + } + + scale = uint16(len(parts[1])) + return intPart + scale, scale // precision is the sum of the two +} + +// Scale returns the scale of the decimal. +// This is the number of digits to the right of the decimal point. +// It will be a value between 0 and 1000 +func (d *Decimal) Scale() uint16 { + return d.scale +} + +// Precision returns the precision of the decimal. +// This is the number of significant digits in the decimal. +// It will be a value between 1 and 1000 +func (d *Decimal) Precision() uint16 { + return d.precision +} + +// IsNegative returns true if the decimal is negative. +func (d *Decimal) IsNegative() bool { + return d.dec.Negative +} + +// String returns the string representation of the decimal. +func (d *Decimal) String() string { + return d.dec.String() +} + +// setPrecision sets the precision of the decimal. +// The precision must be between 1 and 1000. +func (d *Decimal) setPrecision(precision uint16) error { + d.precision = precision + return nil +} + +// setScale sets the scale of the decimal. +// The scale must be between 0 and the precision. +func (d *Decimal) setScale(scale uint16) error { + d.scale = scale + //d.dec.Exponent = -int32(scale) + return d.enforceScale() +} + +// SetPrecisionAndScale sets the precision and scale of the decimal. +// The precision must be between 1 and 1000, and the scale must be between 0 and precision. +func (d *Decimal) SetPrecisionAndScale(precision, scale uint16) error { + if err := CheckPrecisionAndScale(precision, scale); err != nil { + return err + } + + if err := d.setPrecision(precision); err != nil { + return err + } + + return d.setScale(scale) +} + +// mathOp is a helper function for performing math operations on decimals. +// It will return a decimal with maximum precision and scale. +func mathOp(x, y *Decimal, op func(z, x, y *apd.Decimal) (apd.Condition, error)) (*Decimal, error) { + z := apd.New(0, 0) + _, err := op(z, &x.dec, &y.dec) + if err != nil { + return nil, err + } + + dec := &Decimal{ + dec: *z, + scale: uint16(-z.Exponent), + precision: 1000, + } + + return dec, nil +} + +// scaledMathOp is a helper function for performing math operations on decimals. +// It will enforce the scale of the result to the allotted scale of z. +func (z *Decimal) scaledMathOp(x, y *Decimal, op func(z, x, y *apd.Decimal) (apd.Condition, error)) (*Decimal, error) { + _, err := op(&z.dec, &x.dec, &y.dec) + if err != nil { + return nil, err + } + + if err := z.enforceScale(); err != nil { + return nil, err + } + + return z, nil +} + +// Add adds two decimals together. +// It stores the result in z, and returns it. +// It will use the precision and scale of z. +func (z *Decimal) Add(x, y *Decimal) (*Decimal, error) { + return z.scaledMathOp(x, y, z.context().Add) +} + +// Sub subtracts y from x. +// It stores the result in z, and returns it. +// It will use the precision and scale of z. +func (z *Decimal) Sub(x, y *Decimal) (*Decimal, error) { + return z.scaledMathOp(x, y, z.context().Sub) +} + +// Mul multiplies two decimals together. +// It stores the result in z, and returns it. +// It will use the precision and scale of z. +func (z *Decimal) Mul(x, y *Decimal) (*Decimal, error) { + return z.scaledMathOp(x, y, z.context().Mul) +} + +// Div divides x by y. +// It stores the result in z, and returns it. +// It will use the precision and scale of z. +func (z *Decimal) Div(x, y *Decimal) (*Decimal, error) { + return z.scaledMathOp(x, y, z.context().Quo) +} + +// Mod returns the remainder of x divided by y. +// It stores the result in z, and returns it. +// It will use the precision and scale of z. +func (z *Decimal) Mod(x, y *Decimal) (*Decimal, error) { + return z.scaledMathOp(x, y, z.context().Rem) +} + +// Cmp compares two decimals. +// It returns -1 if x < y, 0 if x == y, and 1 if x > y. +// It also sets z to the result of the comparison. +func (z *Decimal) Cmp(x *Decimal) (int, error) { + _, err := z.context().Cmp(&z.dec, &z.dec, &x.dec) + if err != nil { + return 0, err + } + + i64, err := z.Int64() + if err != nil { + return 0, err + } + + return int(i64), nil +} + +// Sign returns the sign of the decimal. +// It returns -1 if the decimal is negative, 0 if it is zero, and 1 if it is positive. +func (d *Decimal) Sign() int { + return d.dec.Sign() +} + +// Value implements the database/sql/driver.Valuer interface. It converts d to a +// string. +func (d *Decimal) Value() (driver.Value, error) { + return d.dec.Value() +} + +var _ driver.Valuer = &Decimal{} + +// Scan implements the database/sql.Scanner interface. +func (d *Decimal) Scan(src interface{}) error { + return d.dec.Scan(src) +} + +var _ sql.Scanner = &Decimal{} + +// Abs returns the absolute value of the decimal. +func (d *Decimal) Abs() (*Decimal, error) { + _, err := d.context().Abs(&d.dec, &d.dec) + return d, err +} + +// Neg negates the decimal. +func (d *Decimal) Neg() error { + _, err := d.context().Neg(&d.dec, &d.dec) + return err +} + +// Round rounds the decimal to the specified scale. +func (d *Decimal) Round(scale uint16) error { + if scale > 1000 { + return fmt.Errorf("scale too large: %d", scale) + } + + _, err := d.context().Quantize(&d.dec, &d.dec, -int32(scale)) + return err +} + +// Int64 returns the decimal as an int64. +func (d *Decimal) Int64() (int64, error) { + return d.dec.Int64() +} + +// Float64 returns the decimal as a float64. +func (d *Decimal) Float64() (float64, error) { + return d.dec.Float64() +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (d *Decimal) MarshalBinary() ([]byte, error) { + bts, err := d.dec.MarshalText() + if err != nil { + return nil, err + } + + var b [4]byte + binary.BigEndian.PutUint16(b[:2], d.precision) + binary.BigEndian.PutUint16(b[2:], d.scale) + + return append(b[:], bts...), nil +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +func (d *Decimal) UnmarshalBinary(data []byte) error { + if len(data) < 4 { + return fmt.Errorf("invalid binary data") + } + + d.precision = binary.BigEndian.Uint16(data[:2]) + d.scale = binary.BigEndian.Uint16(data[2:4]) + + return d.UnmarshalBinary(data[4:]) +} + +var ErrOverflow = fmt.Errorf("overflow") + +// context returns the context of the decimal. +func (d *Decimal) context() *apd.Context { + ctx := context.WithPrecision(uint32(d.precision)) + + // do we need to set the exponent here? + return ctx +} + +// enforceScale enforces scale on a decimal. +func (d *Decimal) enforceScale() error { + _, err := d.context().Quantize(&d.dec, &d.dec, -int32(d.scale)) + return err +} + +// Add adds two decimals together. +// It will return a decimal with maximum precision and scale. +func Add(x, y *Decimal) (*Decimal, error) { + return mathOp(x, y, context.Add) +} + +// Sub subtracts y from x. +// It will return a decimal with maximum precision and scale. +func Sub(x, y *Decimal) (*Decimal, error) { + return mathOp(x, y, context.Sub) +} + +// Mul multiplies two decimals together. +// It will return a decimal with maximum precision and scale. +func Mul(x, y *Decimal) (*Decimal, error) { + return mathOp(x, y, context.Mul) +} + +// Div divides x by y. +// It will return a decimal with maximum precision and scale. +func Div(x, y *Decimal) (*Decimal, error) { + return mathOp(x, y, context.Quo) +} + +// Mod returns the remainder of x divided by y. +// It will return a decimal with maximum precision and scale. +func Mod(x, y *Decimal) (*Decimal, error) { + return mathOp(x, y, context.Rem) +} + +// Cmp compares two decimals. +// It returns -1 if x < y, 0 if x == y, and 1 if x > y. +func Cmp(x, y *Decimal) (int64, error) { + z := apd.New(0, 0) + _, err := context.Cmp(z, &x.dec, &y.dec) + if err != nil { + return 0, err + } + + return z.Int64() +} + +// CheckPrecisionAndScale checks if the precision and scale are valid. +func CheckPrecisionAndScale(precision, scale uint16) error { + if precision < 1 { + return fmt.Errorf("precision must be at least 1: %d", precision) + } + + if precision > 1000 { + return fmt.Errorf("precision too large: %d", precision) + } + + if scale > precision { + return fmt.Errorf("scale must be less than or equal to precision: %d > %d", scale, precision) + } + + return nil +} diff --git a/core/types/decimal/decimal_test.go b/core/types/decimal/decimal_test.go new file mode 100644 index 000000000..33197f114 --- /dev/null +++ b/core/types/decimal/decimal_test.go @@ -0,0 +1,470 @@ +package decimal_test + +import ( + "testing" + + "github.com/kwilteam/kwil-db/core/types/decimal" + "github.com/stretchr/testify/require" + "gotest.tools/assert" +) + +func Test_NewParsedDecimal(t *testing.T) { + type testcase struct { + name string + decimal string + prec uint16 + scale uint16 + want string + err bool + } + + tests := []testcase{ + { + name: "basic", + decimal: "123.456", + prec: 6, + scale: 3, + want: "123.456", + }, + { + name: "no scale", + decimal: "1.456", + prec: 1, + scale: 0, + want: "1", + }, + { + name: "overflow", + decimal: "123.456", + prec: 5, + scale: 3, + err: true, + }, + { + name: "rounding", + decimal: "123.456", + prec: 5, + scale: 2, + want: "123.46", + }, + { + name: "negative", + decimal: "-123.456", + prec: 6, + scale: 3, + want: "-123.456", + }, + { + name: "round down", + decimal: "123.44", + prec: 4, + scale: 1, + want: "123.4", + }, + { + name: "round up", + decimal: "123.45", + prec: 4, + scale: 1, + want: "123.5", + }, + { + // while this is sort've unideal, it is expected, so keeping + // it as a test case. + name: "second-digit round with enough precision", + decimal: "123.449", + prec: 5, + scale: 1, + want: "123.5", + }, + { + name: "second-digit round with not enough precision", + decimal: "123.449", + prec: 4, + scale: 1, + want: "123.4", + }, + } + + // test cases for decimal creation + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d, err := decimal.NewExplicit(tt.decimal, tt.prec, tt.scale) + if tt.err { + require.Errorf(t, err, "result: %v", d) + return + } + if tt.err { + require.Error(t, err) + return + } + require.NoError(t, err) + + require.Equal(t, tt.want, d.String()) + }) + } +} + +func Test_DecimalParsing(t *testing.T) { + type testcase struct { + name string + in string + prec uint16 + scale uint16 + err bool + } + + tests := []testcase{ + { + name: "basic", + in: "123.456", + prec: 6, + scale: 3, + }, + { + name: "no decimal", + in: "1", + prec: 1, + scale: 0, + }, + { + name: "no int", + in: "0.456", + prec: 3, + scale: 3, + }, + { + name: "no decimal or int", + in: "", + err: true, + }, + { + name: "negative", + in: "-123.456", + prec: 6, + scale: 3, + }, + { + name: "positive", + in: "+123.456", + prec: 6, + scale: 3, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d, err := decimal.NewFromString(tt.in) + if tt.err { + require.Error(t, err) + return + } + require.NoError(t, err) + + require.Equal(t, tt.prec, d.Precision()) + require.Equal(t, tt.scale, d.Scale()) + }) + + } +} + +func Test_MulDecimal(t *testing.T) { + // happy path + a := "123.456" + b := "2.000" + + decA, err := decimal.NewFromString(a) + require.NoError(t, err) + + decB, err := decimal.NewFromString(b) + require.NoError(t, err) + + decMul, err := decA.Mul(decA, decB) + require.NoError(t, err) + + assert.Equal(t, "246.912", decMul.String()) + + // overflow + decA, err = decimal.NewFromString("123.456") + require.NoError(t, err) + + decB, err = decimal.NewFromString("10.000") + require.NoError(t, err) + + _, err = decA.Mul(decA, decB) + require.Error(t, err) + + // handle the overflow error + decA, err = decimal.NewFromString("123.456") + require.NoError(t, err) + + decB, err = decimal.NewFromString("10.000") + require.NoError(t, err) + + res := decimal.Decimal{} + err = res.SetPrecisionAndScale(6, 2) + require.NoError(t, err) + + _, err = res.Mul(decA, decB) + require.NoError(t, err) + + require.Equal(t, "1234.56", res.String()) +} + +func Test_DecimalMath(t *testing.T) { + type testcase struct { + name string + a string + b string + add string + sub string + div string + mod string + } + + tests := []testcase{ + { + name: "basic", + a: "111.111", + b: "222.222", + add: "333.333", + sub: "-111.111", + div: "0.500", + mod: "111.111", + }, + { + name: "negative", + a: "-111.111", + b: "222.222", + add: "111.111", + sub: "-333.333", + div: "-0.500", + mod: "-111.111", + }, + { + name: "different scale", + a: "111.111", + b: "222.222222", + add: "333.333222", + sub: "-111.111222", + div: "0.500000", + mod: "111.111000", + }, + { + name: "different precision", + a: "1.111", + b: "222.222", + add: "223.333", + sub: "-221.111", + div: "0.005", + mod: "1.111", + }, + { + name: "different precision and scale", + a: "11.11", + b: "2.2222", + add: "13.3322", + sub: "8.8878", + div: "4.9995", + mod: "2.2212", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var a *decimal.Decimal + var b *decimal.Decimal + // greatestScale is the greatest scale of the two decimals + var greatestScale uint16 + + // reset resets the a and b variables, + // since their pointers get shared between tests. + reset := func() { + var err error + a, err = decimal.NewFromString(tt.a) + require.NoError(t, err) + + b, err = decimal.NewFromString(tt.b) + require.NoError(t, err) + + if a.Scale() > b.Scale() { + greatestScale = a.Scale() + } else { + greatestScale = b.Scale() + } + } + reset() + + add, err := decimal.Add(a, b) + require.NoError(t, err) + eq(t, add, tt.add, greatestScale) + + reset() + + sub, err := decimal.Sub(a, b) + require.NoError(t, err) + eq(t, sub, tt.sub, greatestScale) + + reset() + + // we dont test mul here since it would likely overflow + + div, err := decimal.Div(a, b) + require.NoError(t, err) + d := div.String() + _ = d + eq(t, div, tt.div, greatestScale) + + reset() + + mod, err := decimal.Mod(a, b) + require.NoError(t, err) + eq(t, mod, tt.mod, greatestScale) + }) + } +} + +// eq checks that a decimal is equal to a string. +// It will round the decimal to the given scale. +func eq(t *testing.T, dec *decimal.Decimal, want string, round uint16) { + dec2, err := decimal.NewFromString(want) + require.NoError(t, err) + + old := dec.String() + + err = dec.Round(round) + require.NoError(t, err) + + err = dec2.Round(round) + require.NoError(t, err) + + // since dec will get overwritten by Cmp + got := dec.String() + + cmp, err := dec.Cmp(dec2) + require.NoError(t, err) + + require.Equalf(t, 0, cmp, "want: %s, got: %s, rounded from: %s", dec2.String(), got, old) +} + +func Test_AdjustPrecAndScale(t *testing.T) { + a, err := decimal.NewFromString("111.111") + require.NoError(t, err) + + err = a.SetPrecisionAndScale(9, 6) + require.NoError(t, err) + + require.Equal(t, "111.111000", a.String()) + + // set prec/scale back + err = a.SetPrecisionAndScale(6, 3) + require.NoError(t, err) + + require.Equal(t, "111.111", a.String()) + + // set prec/scale too low + err = a.SetPrecisionAndScale(3, 2) + require.Error(t, err) +} + +func Test_AdjustScaleMath(t *testing.T) { + a, err := decimal.NewFromString("111.111") + require.NoError(t, err) + + err = a.SetPrecisionAndScale(6, 3) + require.NoError(t, err) + + b, err := decimal.NewFromString("222.22") + require.NoError(t, err) + + _, err = a.Add(a, b) + require.NoError(t, err) + + require.Equal(t, "333.331", a.String()) + + // set prec/scale back + err = a.SetPrecisionAndScale(6, 2) + require.NoError(t, err) + + require.Equal(t, "333.33", a.String()) + + c, err := decimal.NewFromString("30.22") + require.NoError(t, err) + + _, err = a.Sub(a, c) + require.NoError(t, err) + + require.Equal(t, "303.11", a.String()) +} + +func Test_RemoveScale(t *testing.T) { + a, err := decimal.NewFromString("111.111") + require.NoError(t, err) + + err = a.SetPrecisionAndScale(6, 2) + require.NoError(t, err) + + require.Equal(t, "111.11", a.String()) + + err = a.SetPrecisionAndScale(6, 3) + require.NoError(t, err) + + require.Equal(t, "111.110", a.String()) +} + +func Test_DecimalCmp(t *testing.T) { + type testcase struct { + name string + a string + b string + want int + } + + tests := []testcase{ + { + name: "equal", + a: "123.456", + b: "123.456", + want: 0, + }, + { + name: "equal values, different scale", + a: "0123.456", + b: "123.456000", + want: 0, + }, + { + name: "different values, different scale", + a: "123.456001", + b: "123.456", + want: 1, + }, + { + name: "different values, different precision", + a: "123.456", + b: "1123.456", + want: -1, + }, + { + name: "negative", + a: "-123.456", + b: "123.456", + want: -1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a, err := decimal.NewFromString(tt.a) + require.NoError(t, err) + + b, err := decimal.NewFromString(tt.b) + require.NoError(t, err) + + cmp, err := a.Cmp(b) + require.NoError(t, err) + + require.Equal(t, tt.want, cmp) + }) + } +} diff --git a/core/types/schema.go b/core/types/schema.go index 4dba84179..69d8b7132 100644 --- a/core/types/schema.go +++ b/core/types/schema.go @@ -6,6 +6,7 @@ import ( "slices" "strings" + "github.com/kwilteam/kwil-db/core/types/decimal" "github.com/kwilteam/kwil-db/core/types/validation" "github.com/kwilteam/kwil-db/core/utils" ) @@ -24,8 +25,8 @@ type Schema struct { } // Clean validates rules about the data in the struct (naming conventions, syntax, etc.). -func (s *Schema) Clean() error { - err := cleanIdent(&s.Name) +func (s *Schema) Clean() (err error) { + err = cleanIdent(&s.Name) if err != nil { return err } @@ -118,6 +119,18 @@ func (s *Schema) FindTable(name string) (table *Table, found bool) { return nil, false } +// FindAction finds an action based on its name. +// It returns false if the action is not found. +func (s *Schema) FindAction(name string) (action *Action, found bool) { + for _, act := range s.Actions { + if strings.EqualFold(act.Name, name) { + return act, true + } + } + + return nil, false +} + // FindProcedure finds a procedure based on its name. // It returns false if the procedure is not found. func (s *Schema) FindProcedure(name string) (procedure *Procedure, found bool) { @@ -142,6 +155,18 @@ func (s *Schema) FindForeignProcedure(name string) (procedure *ForeignProcedure, return nil, false } +// FindExtensionImport finds an extension based on its alias. +// It returns false if the extension is not found. +func (s *Schema) FindExtensionImport(alias string) (extension *Extension, found bool) { + for _, ext := range s.Extensions { + if strings.EqualFold(ext.Alias, alias) { + return ext, true + } + } + + return nil, false +} + func (s *Schema) DBID() string { return utils.GenerateDBID(s.Name, s.Owner) } @@ -325,6 +350,17 @@ func (c *Column) Copy() *Column { return res } +// HasAttribute returns true if the column has the given attribute. +func (c *Column) HasAttribute(attr AttributeType) bool { + for _, a := range c.Attributes { + if a.Type == attr { + return true + } + } + + return false +} + func (c *Column) hasPrimary() bool { for _, attr := range c.Attributes { if attr.Type == PRIMARY_KEY { @@ -345,11 +381,11 @@ type Attribute struct { func (a *Attribute) Clean(col *Column) error { switch a.Type { case MIN, MAX: - if !col.Type.Equals(IntType) { + if !col.Type.EqualsStrict(IntType) { return fmt.Errorf("attribute %s is only valid for int columns", a.Type) } case MIN_LENGTH, MAX_LENGTH: - if !col.Type.Equals(TextType) { + if !col.Type.EqualsStrict(TextType) { return fmt.Errorf("attribute %s is only valid for text columns", a.Type) } } @@ -1062,14 +1098,30 @@ type DataType struct { Name string `json:"name"` // IsArray is true if the type is an array. IsArray bool `json:"is_array"` + // Metadata is the metadata of the type. + Metadata any `json:"metadata"` } // String returns the string representation of the type. func (c *DataType) String() string { + str := strings.Builder{} + str.WriteString(c.Name) if c.IsArray { - return c.Name + "[]" + return str.String() + "[]" + } + + if c.Name == DecimalStr { + data, ok := c.Metadata.([2]uint16) + if ok { + str.WriteString("(") + str.WriteString(fmt.Sprint(data[0])) + str.WriteString(",") + str.WriteString(fmt.Sprint(data[1])) + str.WriteString(")") + } } - return c.Name + + return str.String() } // PGString returns the string representation of the type in Postgres. @@ -1086,6 +1138,16 @@ func (c *DataType) PGString() (string, error) { scalar = "BYTEA" case uuidStr: scalar = "UUID" + case uint256Str: + scalar = "UINT256" + case DecimalStr: + data, ok := c.Metadata.([2]uint16) + if !ok { + // should never happen, since Clean() should have caught this + return "", fmt.Errorf("fixed type must have metadata of type [2]uint8") + } + + scalar = fmt.Sprintf("NUMERIC(%d,%d)", data[0], data[1]) case nullStr: return "", fmt.Errorf("cannot have null column type") case unknownStr: @@ -1102,9 +1164,35 @@ func (c *DataType) PGString() (string, error) { } func (c *DataType) Clean() error { - switch name := strings.ToLower(c.Name); name { - case intStr, textStr, boolStr, blobStr, uuidStr: // ok - c.Name = name + c.Name = strings.ToLower(c.Name) + switch c.Name { + case intStr, textStr, boolStr, blobStr, uuidStr, uint256Str: // ok + if c.Metadata != nil { + return fmt.Errorf("type %s cannot have metadata", c.Name) + } + + return nil + case DecimalStr: + data, ok := c.Metadata.([2]uint16) + if !ok { + return fmt.Errorf("fixed type must have metadata of type [2]uint8") + } + + err := decimal.CheckPrecisionAndScale(data[0], data[1]) + if err != nil { + return err + } + + return nil + case nullStr, unknownStr: + if c.IsArray { + return fmt.Errorf("type %s cannot be an array", c.Name) + } + + if c.Metadata != nil { + return fmt.Errorf("type %s cannot have metadata", c.Name) + } + return nil default: return fmt.Errorf("unknown type: %s", c.Name) @@ -1114,20 +1202,47 @@ func (c *DataType) Clean() error { // Copy returns a copy of the type. func (c *DataType) Copy() *DataType { return &DataType{ - Name: c.Name, - IsArray: c.IsArray, + Name: c.Name, + IsArray: c.IsArray, + Metadata: c.Metadata, } } -// Equals returns true if the type is equal to the other type. -// If either type is Unknown, it will return true. -func (c *DataType) Equals(other *DataType) bool { +// EqualsStrict returns true if the type is equal to the other type. +// The types must be exactly the same, including metadata. +func (c *DataType) EqualsStrict(other *DataType) bool { + // if unknown, return true. unknown is a special case used + // internally when type checking is disabled. if c.Name == unknownStr || other.Name == unknownStr { return true } - return strings.EqualFold(c.Name, other.Name) && c.IsArray == other.IsArray + + if c.IsArray != other.IsArray { + return false + } + + if c.Metadata != other.Metadata { + return false + } + + return strings.EqualFold(c.Name, other.Name) } +// Equals returns true if the type is equal to the other type, or if either type is null. +func (c *DataType) Equals(other *DataType) bool { + if c.Name == nullStr || other.Name == nullStr { + return true + } + + return c.EqualsStrict(other) +} + +func (c *DataType) IsNumeric() bool { + return c.Name == intStr || c.Name == DecimalStr || c.Name == uint256Str || c.Name == unknownStr +} + +// declared DataType constants. +// We do not have one for fixed because fixed types require metadata. var ( IntType = &DataType{ Name: intStr, @@ -1144,6 +1259,9 @@ var ( UUIDType = &DataType{ Name: uuidStr, } + Uint256Type = &DataType{ + Name: uint256Str, + } // NullType is a special type used internally NullType = &DataType{ Name: nullStr, @@ -1155,12 +1273,41 @@ var ( } ) +// ArrayType creates an array type of the given type. +// It panics if the type is already an array. +func ArrayType(t *DataType) *DataType { + if t.IsArray { + panic("cannot create an array of an array") + } + return &DataType{ + Name: t.Name, + IsArray: true, + Metadata: t.Metadata, + } +} + const ( textStr = "text" intStr = "int" boolStr = "bool" blobStr = "blob" uuidStr = "uuid" + uint256Str = "uint256" + // DecimalStr is a fixed point number. + DecimalStr = "fixed" nullStr = "null" unknownStr = "unknown" ) + +// NewDecimalType creates a new fixed point decimal type. +func NewDecimalType(precision, scale uint16) (*DataType, error) { + err := decimal.CheckPrecisionAndScale(precision, scale) + if err != nil { + return nil, err + } + + return &DataType{ + Name: DecimalStr, + Metadata: [2]uint16{precision, scale}, + }, nil +} diff --git a/core/types/validation/keywords.go b/core/types/validation/keywords.go index dbfcbf1b9..e4ac408e6 100644 --- a/core/types/validation/keywords.go +++ b/core/types/validation/keywords.go @@ -113,4 +113,7 @@ var reservedWords = map[string]struct{}{ "where": {}, "window": {}, "with": {}, + // below are keywords that are not restricted by postgres, but are + // restricted by kwil + "excluded": {}, } diff --git a/go.mod b/go.mod index fd4530e08..9c183cc37 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/ethereum/go-ethereum v1.14.3 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 + github.com/holiman/uint256 v1.2.4 github.com/jackc/pglogrepl v0.0.0-20240307033717-828fbfe908e9 github.com/jackc/pgx/v5 v5.5.5 github.com/jpillora/backoff v1.0.0 @@ -49,6 +50,7 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.0 // indirect + github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.0 // indirect @@ -89,7 +91,6 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/uint256 v1.2.4 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect diff --git a/go.sum b/go.sum index 04214d960..416445959 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0 github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= @@ -581,6 +583,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= diff --git a/internal/engine/ddl/procedure.go b/internal/engine/ddl/procedure.go deleted file mode 100644 index 723c10799..000000000 --- a/internal/engine/ddl/procedure.go +++ /dev/null @@ -1,128 +0,0 @@ -package ddl - -import ( - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/procedures" -) - -// GenerateProcedure generates the plpgsql code for a procedure. -// It takes a procedure and the body of the procedure and returns the plpgsql code for the procedure. -func GenerateProcedure(proc *procedures.AnalyzedProcedure, pgSchema string) (string, error) { - str := strings.Builder{} - str.WriteString("CREATE OR REPLACE FUNCTION ") - str.WriteString(fmt.Sprintf("%s.%s(", pgSchema, proc.Name)) - - // writing the function parameters - - // paramSet tracks the used params, and will not allow them - // to be redeclared in the DECLARE section. - paramSet := make(map[string]struct{}) - i := -1 - var field *types.NamedType - for i, field = range proc.Parameters { - if i != 0 { - str.WriteString(", ") - } - - paramSet[field.Name] = struct{}{} - - typ, err := field.Type.PGString() - if err != nil { - return "", err - } - - str.WriteString(fmt.Sprintf("%s %s", field.Name, typ)) - } - - hasOutReturns := false - // we need to write return types if there are any - if len(proc.Returns.Fields) > 0 && !proc.Returns.IsTable { - hasOutReturns = true - if i != -1 { - str.WriteString(", ") - } - - for i, field := range proc.Returns.Fields { - if i != 0 { - str.WriteString(", ") - } - - typ, err := field.Type.PGString() - if err != nil { - return "", err - } - - str.WriteString(fmt.Sprintf("OUT %s %s", field.Name, typ)) - } - } - - str.WriteString(") ") - - // writing the return type - if proc.Returns.IsTable && len(proc.Returns.Fields) > 0 { - str.WriteString("\nRETURNS ") - - str.WriteString("TABLE(") - for i, field := range proc.Returns.Fields { - if i != 0 { - str.WriteString(", ") - } - - typ, err := field.Type.PGString() - if err != nil { - return "", err - } - - str.WriteString(fmt.Sprintf("%s %s", field.Name, typ)) - } - str.WriteString(") ") - } else if !hasOutReturns { - str.WriteString("\nRETURNS void ") - } - - str.WriteString("AS $$\n") - - // writing the variable declarations - - // declaresTypes tracks if the DECLARE section is needed. - declaresTypes := false - declareSection := strings.Builder{} - if len(proc.DeclaredVariables) > 0 { - for _, declare := range proc.DeclaredVariables { - _, ok := paramSet[declare.Name] - if ok { - continue - } - - typ, err := declare.Type.PGString() - if err != nil { - return "", err - } - - declaresTypes = true - declareSection.WriteString(fmt.Sprintf("%s %s;\n", declare.Name, typ)) - } - } - if len(proc.LoopTargets) > 0 { - declaresTypes = true - for _, loopTarget := range proc.LoopTargets { - declareSection.WriteString(fmt.Sprintf("%s RECORD;\n", loopTarget)) - } - } - - if declaresTypes { - str.WriteString("DECLARE\n") - str.WriteString(declareSection.String()) - } - - // finishing the function - - str.WriteString("BEGIN\n") - str.WriteString(proc.Body) - str.WriteString("\nEND;\n$$ LANGUAGE plpgsql;") - - return str.String(), nil -} diff --git a/internal/engine/execution/global.go b/internal/engine/execution/global.go index d3a679972..2ae1e1e60 100644 --- a/internal/engine/execution/global.go +++ b/internal/engine/execution/global.go @@ -12,10 +12,10 @@ import ( "github.com/kwilteam/kwil-db/common/sql" "github.com/kwilteam/kwil-db/core/types" "github.com/kwilteam/kwil-db/extensions/precompiles" + "github.com/kwilteam/kwil-db/internal/engine/generate" "github.com/kwilteam/kwil-db/internal/sql/pg" "github.com/kwilteam/kwil-db/internal/sql/versioning" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer" - parseTypes "github.com/kwilteam/kwil-db/parse/types" + "github.com/kwilteam/kwil-db/parse" ) // GlobalContext is the context for the entire execution. @@ -328,22 +328,31 @@ func (g *GlobalContext) Execute(ctx context.Context, tx sql.DB, dbid, query stri return nil, ErrDatasetNotFound } - errLis := parseTypes.NewErrorListener() - - // We have to parse the query and ensure the dbid is used to derive schema. - // OR do we permit (or require) the schema to be specified in the query? It - // could go either way, but this ad hoc query function is questionable anyway. - parsed, err := sqlanalyzer.ApplyRules(query, - sqlanalyzer.AllRules, - dataset.schema, dbidSchema(dbid), errLis) + // errLis := parseTypes.NewErrorListener() + + // // We have to parse the query and ensure the dbid is used to derive schema. + // // OR do we permit (or require) the schema to be specified in the query? It + // // could go either way, but this ad hoc query function is questionable anyway. + // parsed, err := sqlanalyzer.ApplyRules(query, + // sqlanalyzer.AllRules, + // dataset.schema, dbidSchema(dbid), errLis) + // if err != nil { + // return nil, err + // } + // if errLis.Err() != nil { + // return nil, errLis.Err() + // } + res, err := parse.ParseSQL(query, dataset.schema) if err != nil { return nil, err } - if errLis.Err() != nil { - return nil, errLis.Err() + + sqlStmt, params, err := generate.WriteSQL(res.AST, true, dbidSchema(dbid)) + if err != nil { + return nil, err } - if parsed.Mutative { + if res.Mutative { txm, ok := tx.(sql.AccessModer) if !ok { return nil, errors.New("DB does not provide access mode needed for mutative statement") @@ -353,10 +362,10 @@ func (g *GlobalContext) Execute(ctx context.Context, tx sql.DB, dbid, query stri } } - args := orderAndCleanValueMap(values, parsed.ParameterOrder) + args := orderAndCleanValueMap(values, params) args = append([]any{pg.QueryModeExec}, args...) - return tx.Execute(ctx, parsed.Statement, args...) + return tx.Execute(ctx, sqlStmt, args...) } type dbQueryFn func(ctx context.Context, stmt string, args ...any) (*sql.ResultSet, error) diff --git a/internal/engine/execution/procedure.go b/internal/engine/execution/procedure.go index d2697b0ca..42a4209be 100644 --- a/internal/engine/execution/procedure.go +++ b/internal/engine/execution/procedure.go @@ -13,8 +13,8 @@ import ( "github.com/kwilteam/kwil-db/core/types" "github.com/kwilteam/kwil-db/extensions/precompiles" "github.com/kwilteam/kwil-db/internal/conv" + "github.com/kwilteam/kwil-db/internal/engine/generate" "github.com/kwilteam/kwil-db/internal/sql/pg" - "github.com/kwilteam/kwil-db/parse/actions" ) // MaxStackDepth is the limit on the number of nested procedure calls allowed. @@ -79,23 +79,16 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { preparedActions := make([]*preparedAction, len(schema.Actions)) - // converting statements to instructions - - parsedActions, parseErrs, err := actions.AnalyzeActions(schema, &actions.AnalyzeOpts{ - PGSchemaName: dbidSchema(schema.DBID()), - }) - if err != nil { - return nil, err - } - if parseErrs.Err() != nil { - return nil, parseErrs.Err() - } - - for idx, analyzedAction := range parsedActions { + for idx, action := range schema.Actions { instructions := make([]instruction, 0) + actionStmt, err := generate.GenerateActionBody(action, schema, dbidSchema(schema.DBID())) + if err != nil { + return nil, err + } + // add instructions for both owner only and view procedures - if analyzedAction.OwnerOnly { + if action.IsOwnerOnly() { instructions = append(instructions, instructionFunc(func(scope *precompiles.ProcedureContext, global *GlobalContext, db sql.DB) error { if !bytes.Equal(scope.Signer, owner) { return fmt.Errorf("cannot call owner procedure, not owner") @@ -105,7 +98,7 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { })) } - if !analyzedAction.IsView { + if !action.IsView() { instructions = append(instructions, instructionFunc(func(scope *precompiles.ProcedureContext, global *GlobalContext, db sql.DB) error { tx, ok := db.(sql.AccessModer) if !ok { @@ -119,12 +112,11 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { })) } - for _, parsedStmt := range analyzedAction.Statements { + for _, parsedStmt := range actionStmt { switch stmt := parsedStmt.(type) { default: return nil, fmt.Errorf("unknown statement type %T", stmt) - case *actions.ExtensionCall: - + case *generate.ActionExtensionCall: i := &callMethod{ Namespace: stmt.Extension, Method: stmt.Method, @@ -132,20 +124,13 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { Receivers: stmt.Receivers, } instructions = append(instructions, i) - case *actions.SQLStatement: - if stmt.Mutative && analyzedAction.IsView { - return nil, fmt.Errorf("view procedure cannot contain mutative statements") - } - + case *generate.ActionSQL: i := &dmlStmt{ SQLStatement: stmt.Statement, OrderedParameters: stmt.ParameterOrder, } instructions = append(instructions, i) - case *actions.ActionCall: - - // we must check if it is calling a view procedure or not - callingViewProcedure := false // callingViewProcedure tracks whether the called procedure is a view + case *generate.ActionCall: var calledAction *types.Action for _, p := range schema.Actions { @@ -158,17 +143,6 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { return nil, fmt.Errorf(`procedure "%s" not found`, stmt.Action) } - for _, mod := range calledAction.Modifiers { - if mod == types.ModifierView { - callingViewProcedure = true - break - } - } - - if analyzedAction.IsView && !callingViewProcedure { - return nil, fmt.Errorf("view procedures cannot call non-view procedures") - } - // we leave the namespace and receivers empty, since action calls can only // call actions within the same schema, and actions cannot return values. i := &callMethod{ @@ -180,10 +154,10 @@ func prepareActions(schema *types.Schema) ([]*preparedAction, error) { } preparedActions[idx] = &preparedAction{ - name: analyzedAction.Name, - public: analyzedAction.Public, - parameters: analyzedAction.Parameters, - view: analyzedAction.IsView, + name: action.Name, + public: action.Public, + parameters: action.Parameters, + view: action.IsView(), instructions: instructions, } } @@ -396,12 +370,12 @@ type evaluatable func(ctx context.Context, exec dbQueryFn, values map[string]any // See their execution in (*callMethod).execute inside the `range e.Args` to // collect the `inputs` passed to the call of a dataset method or other // "namespace" method, such as an extension method. -func makeExecutables(params []*actions.InlineExpression) []evaluatable { +func makeExecutables(params []*generate.InlineExpression) []evaluatable { var evaluatables []evaluatable for _, param := range params { // copy the param to avoid loop variable capture - param2 := &actions.InlineExpression{ + param2 := &generate.InlineExpression{ Statement: param.Statement, OrderedParams: param.OrderedParams, } @@ -532,15 +506,15 @@ func (p *preparedProcedure) coerceInputs(inputs []any) ([]any, error) { panic("passed array to coerceScalar") } - if typ.Equals(types.IntType) { + if typ.EqualsStrict(types.IntType) { return conv.Int(val) - } else if typ.Equals(types.TextType) { + } else if typ.EqualsStrict(types.TextType) { return conv.String(val) - } else if typ.Equals(types.BoolType) { + } else if typ.EqualsStrict(types.BoolType) { return conv.Bool(val) - } else if typ.Equals(types.BlobType) { + } else if typ.EqualsStrict(types.BlobType) { return conv.Blob(val) - } else if typ.Equals(types.UUIDType) { + } else if typ.EqualsStrict(types.UUIDType) { return conv.UUID(val) } @@ -583,7 +557,11 @@ func (p *preparedProcedure) coerceInputs(inputs []any) ([]any, error) { // shapeReturn takes a sql result and ensures it matches the expected return shape // of the procedure. It will modify the passed result to match the expected shape. func (p *preparedProcedure) shapeReturn(result *sql.ResultSet) error { + // in postgres, `select * from proc()`, where proc() returns nothing, + // will return a single empty column and row. We need to remove this. if p.returns == nil { + result.Columns = nil + result.Rows = nil return nil } diff --git a/internal/engine/execution/queries.go b/internal/engine/execution/queries.go index e19dabede..6c4695ecb 100644 --- a/internal/engine/execution/queries.go +++ b/internal/engine/execution/queries.go @@ -11,10 +11,9 @@ import ( "github.com/kwilteam/kwil-db/common" sql "github.com/kwilteam/kwil-db/common/sql" "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/internal/engine/ddl" + "github.com/kwilteam/kwil-db/internal/engine/generate" "github.com/kwilteam/kwil-db/internal/sql/pg" - "github.com/kwilteam/kwil-db/parse/metadata" - procedural "github.com/kwilteam/kwil-db/parse/procedures" + "github.com/kwilteam/kwil-db/parse" ) var ( @@ -183,7 +182,7 @@ func createSchema(ctx context.Context, tx sql.TxMaker, schema *types.Schema, txi } for _, table := range schema.Tables { - statements, err := ddl.GenerateDDL(schemaName, table) + statements, err := generate.GenerateDDL(schemaName, table) if err != nil { return err } @@ -196,21 +195,8 @@ func createSchema(ctx context.Context, tx sql.TxMaker, schema *types.Schema, txi } } - // for each procedure, we will sanitize it, - // type check, generate the PLPGSQL code, - // and then execute the generated code. - procs, errs, err := procedural.AnalyzeProcedures(schema, schemaName, &procedural.AnalyzeOptions{ - LogProcedureNameOnError: true, - }) - if err != nil { - return err - } - if errs.Err() != nil { - return errs.Err() - } - - for _, proc := range procs { - stmt, err := ddl.GenerateProcedure(proc, schemaName) + for _, proc := range schema.Procedures { + stmt, err := generate.GenerateProcedure(proc, schema, schemaName) if err != nil { return err } @@ -225,7 +211,7 @@ func createSchema(ctx context.Context, tx sql.TxMaker, schema *types.Schema, txi // The function ensures that, whatever target procedure is chosen at runtime, that // its input and output types are compatible with the expected types. for _, proc := range schema.ForeignProcedures { - stmt, err := ddl.GenerateForeignProcedure(proc) + stmt, err := generate.GenerateForeignProcedure(proc, schemaName) if err != nil { return err } @@ -338,17 +324,17 @@ func setContextualVars(ctx context.Context, db sql.DB, data *common.ExecutionDat // feature for setting session variables. For example, @caller // is accessed via current_setting('ctx.caller') - _, err := db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, metadata.PgSessionPrefix, metadata.CallerVar, data.Caller)) + _, err := db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, generate.PgSessionPrefix, parse.CallerVar, data.Caller)) if err != nil { return err } - _, err = db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, metadata.PgSessionPrefix, metadata.TxidVar, data.TxID)) + _, err = db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, generate.PgSessionPrefix, parse.TxidVar, data.TxID)) if err != nil { return err } - _, err = db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, metadata.PgSessionPrefix, metadata.SignerVar, hex.EncodeToString(data.Signer))) + _, err = db.Execute(ctx, fmt.Sprintf(`SET LOCAL %s.%s = '%s';`, generate.PgSessionPrefix, parse.SignerVar, hex.EncodeToString(data.Signer))) if err != nil { return err } diff --git a/internal/engine/generate/actions.go b/internal/engine/generate/actions.go new file mode 100644 index 000000000..021a18f82 --- /dev/null +++ b/internal/engine/generate/actions.go @@ -0,0 +1,177 @@ +package generate + +import ( + "fmt" + + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/parse" +) + +// this package handles generating code for actions. + +// GeneratedActionStmt is an interface for analyzed statements. +type GeneratedActionStmt interface { + generatedAction() +} + +// there are exactly three types of analyzed statements: +// - ActionExtensionCall: a statement that calls an extension +// - ActionCall: a statement that calls an action +// - ActionSQL: a statement that contains SQL + +// ActionExtensionCall is an analyzed statement that calls an action or extension. +type ActionExtensionCall struct { + // Extension is the name of the extension alias. + Extension string + // Method is the name of the method being called. + Method string + // Params are the parameters to the method. + Params []*InlineExpression + // Receivers are the receivers of the method. + Receivers []string +} + +func (c *ActionExtensionCall) generatedAction() {} + +// ActionCall is an analyzed statement that calls an action. +type ActionCall struct { + // Action is the name of the action being called. + Action string + // Params are the parameters to the action. + Params []*InlineExpression +} + +func (c *ActionCall) generatedAction() {} + +// ActionSQL is an analyzed statement that contains SQL. +type ActionSQL struct { + // Statement is the Statement statement that should be executed. + // It is deterministic. + Statement string + // ParameterOrder is a list of the parameters in the order they appear in the statement. + // This is set if the ReplaceNamedParameters flag is set. + // For example, if the statement is "SELECT * FROM table WHERE id = $id AND name = @caller", + // then the parameter order would be ["$id", "@caller"] + ParameterOrder []string +} + +func (s *ActionSQL) generatedAction() {} + +// InlineExpression is an expression that is inlined in an action or procedure call. +// For example, this can be "extension.call($id+1)" +type InlineExpression struct { + // Statement is the sql statement that is inlined. + Statement string + // OrderedParams is the order of the parameters in the statement. + OrderedParams []string +} + +// GenerateActionBody generates the body of an action. +// If the action is a VIEW and contains mutative SQL, it will return an error. +func GenerateActionBody(action *types.Action, schema *types.Schema, pgSchema string) (stmts []GeneratedActionStmt, err error) { + defer func() { + if r := recover(); r != nil { + var ok bool + err, ok = r.(error) + if !ok { + err = fmt.Errorf("panic: %v", r) + } + } + + // add action name to error + if err != nil { + err = fmt.Errorf("action %s: %w", action.Name, err) + } + }() + + res, err := parse.ParseAction(action, schema) + if err != nil { + return nil, err + } + + // syntax errors, as well as mutative SQL, will be thrown here. + if res.ParseErrs.Err() != nil { + return nil, res.ParseErrs.Err() + } + + g := &actionGenerator{ + sqlGenerator: sqlGenerator{ + pgSchema: pgSchema, + numberParameters: true, + }, + } + for _, stmt := range res.AST { + stmt.Accept(g) + } + + return g.actions, nil +} + +// actionGenerator is a struct that generates code for actions. +// it totally relies on the SQL generator, except for the action-specific +// visits and Variables, since it needs to rewrite the variables to be numbered. +type actionGenerator struct { + sqlGenerator + // actions is the order of all actions that are generated. + actions []GeneratedActionStmt +} + +func (a *actionGenerator) VisitActionStmtSQL(p0 *parse.ActionStmtSQL) any { + a.sqlGenerator.orderedParams = nil // reset order since it is a new statement + stmt := p0.SQL.Accept(a).(string) + + params := make([]string, len(a.sqlGenerator.orderedParams)) + copy(params, a.sqlGenerator.orderedParams) + + a.actions = append(a.actions, &ActionSQL{ + Statement: stmt + ";", + ParameterOrder: params, + }) + + return nil +} + +func (a *actionGenerator) VisitActionStmtExtensionCall(p0 *parse.ActionStmtExtensionCall) any { + inlines := make([]*InlineExpression, len(p0.Args)) + for i, arg := range p0.Args { + inlines[i] = a.createInline(arg) + } + + a.actions = append(a.actions, &ActionExtensionCall{ + Receivers: p0.Receivers, + Extension: p0.Extension, + Method: p0.Method, + Params: inlines, + }) + + return nil +} + +func (a *actionGenerator) VisitActionStmtActionCall(p0 *parse.ActionStmtActionCall) any { + inlines := make([]*InlineExpression, len(p0.Args)) + for i, arg := range p0.Args { + inlines[i] = a.createInline(arg) + } + + a.actions = append(a.actions, &ActionCall{ + Action: p0.Action, + Params: inlines, + }) + + return nil +} + +// createInline creates an inline from an expression +func (a *actionGenerator) createInline(p0 parse.Expression) *InlineExpression { + a.sqlGenerator.orderedParams = nil // reset order since it is a new statement + + str := p0.Accept(a).(string) + + params := make([]string, len(a.sqlGenerator.orderedParams)) + copy(params, a.sqlGenerator.orderedParams) + + return &InlineExpression{ + Statement: "SELECT " + str + ";", + OrderedParams: params, + } +} diff --git a/internal/engine/ddl/foreign_procedure.go b/internal/engine/generate/foreign_procedure.go similarity index 98% rename from internal/engine/ddl/foreign_procedure.go rename to internal/engine/generate/foreign_procedure.go index 11d4d09a1..24fc0fe20 100644 --- a/internal/engine/ddl/foreign_procedure.go +++ b/internal/engine/generate/foreign_procedure.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "fmt" @@ -99,11 +99,11 @@ $$ LANGUAGE plpgsql; // GenerateForeignProcedure generates a plpgsql function that allows the schema to dynamically // call procedures in other schemas, expecting certain inputs and return values. It will prefix // the generated function with _fp_ (for "foreign procedure"). -func GenerateForeignProcedure(proc *types.ForeignProcedure) (string, error) { +func GenerateForeignProcedure(proc *types.ForeignProcedure, pgSchema string) (string, error) { str := strings.Builder{} // first write the header - str.WriteString(fmt.Sprintf(`CREATE OR REPLACE FUNCTION _fp_%s(_dbid TEXT, _procedure TEXT`, proc.Name)) + str.WriteString(fmt.Sprintf(`CREATE OR REPLACE FUNCTION %s._fp_%s(_dbid TEXT, _procedure TEXT`, pgSchema, proc.Name)) // we now need to format the inputs. Inputs will be named _arg1, _arg2, etc. // we start at 1 since postgres is 1-indexed. diff --git a/internal/engine/ddl/foreign_procedure_test.go b/internal/engine/generate/foreign_procedure_test.go similarity index 93% rename from internal/engine/ddl/foreign_procedure_test.go rename to internal/engine/generate/foreign_procedure_test.go index 7f3b1fd79..524b40be6 100644 --- a/internal/engine/ddl/foreign_procedure_test.go +++ b/internal/engine/generate/foreign_procedure_test.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "strings" @@ -9,6 +9,8 @@ import ( "github.com/stretchr/testify/require" ) +var schemaName = "schema" + func Test_ForeignProcedureGen(t *testing.T) { type testcase struct { name string @@ -23,7 +25,7 @@ func Test_ForeignProcedureGen(t *testing.T) { Name: "test", }, want: ` -CREATE OR REPLACE FUNCTION _fp_test(_dbid TEXT, _procedure TEXT) RETURNS VOID AS $$ +CREATE OR REPLACE FUNCTION schema._fp_test(_dbid TEXT, _procedure TEXT) RETURNS VOID AS $$ DECLARE _schema_owner BYTEA; _is_view BOOLEAN; @@ -73,7 +75,7 @@ $$ LANGUAGE plpgsql;`, for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := GenerateForeignProcedure(test.procedure) + got, err := GenerateForeignProcedure(test.procedure, schemaName) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/internal/engine/ddl/generate.go b/internal/engine/generate/generate.go similarity index 97% rename from internal/engine/ddl/generate.go rename to internal/engine/generate/generate.go index abac4fcd4..4531cb222 100644 --- a/internal/engine/ddl/generate.go +++ b/internal/engine/generate/generate.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "fmt" diff --git a/internal/engine/ddl/generate_test.go b/internal/engine/generate/generate_test.go similarity index 96% rename from internal/engine/ddl/generate_test.go rename to internal/engine/generate/generate_test.go index d945043ca..3269ff7e2 100644 --- a/internal/engine/ddl/generate_test.go +++ b/internal/engine/generate/generate_test.go @@ -1,4 +1,4 @@ -package ddl_test +package generate_test import ( "strings" @@ -6,8 +6,8 @@ import ( "unicode" "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/internal/engine/ddl" - "github.com/kwilteam/kwil-db/parse/sql/postgres" + "github.com/kwilteam/kwil-db/internal/engine/generate" + "github.com/kwilteam/kwil-db/parse/postgres" "github.com/stretchr/testify/assert" ) @@ -218,7 +218,7 @@ func TestGenerateDDL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := ddl.GenerateDDL("dbid", tt.args.table) + got, err := generate.GenerateDDL("dbid", tt.args.table) if (err != nil) != tt.wantErr { t.Errorf("GenerateDDL() error = %v, wantErr %v", err, tt.wantErr) return @@ -268,7 +268,7 @@ func Test_PrimaryIndexModification(t *testing.T) { }, } - _, err := ddl.GenerateDDL("dbid", testTable) + _, err := generate.GenerateDDL("dbid", testTable) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/internal/engine/ddl/index.go b/internal/engine/generate/index.go similarity index 98% rename from internal/engine/ddl/index.go rename to internal/engine/generate/index.go index ecfbc6b5f..2e2cdb8ec 100644 --- a/internal/engine/ddl/index.go +++ b/internal/engine/generate/index.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "fmt" diff --git a/internal/engine/generate/metadata.go b/internal/engine/generate/metadata.go new file mode 100644 index 000000000..a1b4abc83 --- /dev/null +++ b/internal/engine/generate/metadata.go @@ -0,0 +1,8 @@ +package generate + +var ( + // PgSessionPrefix is the prefix for all session variables. + // It is used in combination with Postgre's current_setting function + // to set contextual variables. + PgSessionPrefix = "ctx" +) diff --git a/internal/engine/generate/plpgsql.go b/internal/engine/generate/plpgsql.go new file mode 100644 index 000000000..19f6301dd --- /dev/null +++ b/internal/engine/generate/plpgsql.go @@ -0,0 +1,992 @@ +package generate + +import ( + "fmt" + "strings" + + "github.com/holiman/uint256" + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/types/decimal" + "github.com/kwilteam/kwil-db/parse" +) + +/* + This file implements a visitor to generate Postgres compatible SQL and plpgsql +*/ + +// sqlVisitor creates Postgres compatible SQL from an AST +type sqlGenerator struct { + parse.UnimplementedSqlVisitor + // pgSchema is the schema name to prefix to the table names + pgSchema string + // numberParameters is a flag that indicates if we should number parameters as $1, $2, etc., + // instead of formatting their variable names. It should be set to true if we want to execute + // SQL directly against postgres, instead of using it in a procedure. + numberParameters bool + // orderedParams is the order of parameters in the order they appear in the statement. + // It is only set if numberParameters is true. For example, the statement SELECT $1, $2 + // would have orderedParams = ["$1", "$2"] + orderedParams []string +} + +func (s *sqlGenerator) VisitExpressionLiteral(p0 *parse.ExpressionLiteral) any { + str, err := formatPGLiteral(p0.Value) + if err != nil { + panic(err) + } + + if p0.GetTypeCast() != nil { + pgStr, err := p0.GetTypeCast().PGString() + if err != nil { + panic(err) + } + str += "::" + pgStr + } + + return str +} + +func (s *sqlGenerator) VisitExpressionFunctionCall(p0 *parse.ExpressionFunctionCall) any { + str := strings.Builder{} + + args := make([]string, len(p0.Args)) + for i, arg := range p0.Args { + args[i] = arg.Accept(s).(string) + } + + // if this is not a built-in function, we need to prefix it with + // the schema name, since it is a local procedure + fn, ok := parse.Functions[p0.Name] + if !ok { + // if not found, it is a local procedure + str.WriteString(s.pgSchema) + str.WriteString(".") + str.WriteString(p0.Name) + str.WriteString("(") + for i, arg := range args { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(arg) + } + str.WriteString(")") + typeCast(p0, &str) + return str.String() + } + + pgFmt, err := fn.PGFormat(args, p0.Distinct, p0.Star) + if err != nil { + panic(err) + } + str.WriteString(pgFmt) + + typeCast(p0, &str) + + return str.String() +} + +// typeCast adds a typecast to the string builder if the typecast is not nil +func typeCast(t interface{ GetTypeCast() *types.DataType }, s *strings.Builder) { + if t.GetTypeCast() != nil { + pgStr, err := t.GetTypeCast().PGString() + if err != nil { + panic(err) + } + + s.WriteString("::") + s.WriteString(pgStr) + } +} + +func (s *sqlGenerator) VisitExpressionForeignCall(p0 *parse.ExpressionForeignCall) any { + str := strings.Builder{} + str.WriteString(s.pgSchema) + str.WriteString(".") + str.WriteString(formatForeignProcedureName(p0.Name)) + str.WriteString("(") + for i, arg := range append(p0.ContextualArgs, p0.Args...) { + if i > 0 { + str.WriteString(", ") + } + + str.WriteString(arg.Accept(s).(string)) + } + str.WriteString(")") + + typeCast(p0, &str) + + return str.String() +} + +func (s *sqlGenerator) VisitExpressionVariable(p0 *parse.ExpressionVariable) any { + if s.numberParameters { + str := p0.String() + + // if it already exists, we write it as that index. + for i, v := range s.orderedParams { + if v == str { + return "$" + fmt.Sprint(i+1) + } + } + + // otherwise, we add it to the list. + // Postgres uses $1, $2, etc. for numbered parameters. + + s.orderedParams = append(s.orderedParams, str) + return "$" + fmt.Sprint(len(s.orderedParams)) + } + + str := strings.Builder{} + str.WriteString(formatVariable(p0)) + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionArrayAccess(p0 *parse.ExpressionArrayAccess) any { + str := strings.Builder{} + str.WriteString(p0.Array.Accept(s).(string)) + str.WriteString("[") + str.WriteString(p0.Index.Accept(s).(string)) + str.WriteString("]") + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionMakeArray(p0 *parse.ExpressionMakeArray) any { + str := strings.Builder{} + str.WriteString("ARRAY[") + for i, arg := range p0.Values { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(arg.Accept(s).(string)) + } + str.WriteString("]") + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionFieldAccess(p0 *parse.ExpressionFieldAccess) any { + str := strings.Builder{} + str.WriteString(p0.Record.Accept(s).(string)) + str.WriteString(".") + str.WriteString(p0.Field) + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionParenthesized(p0 *parse.ExpressionParenthesized) any { + str := strings.Builder{} + str.WriteString("(") + str.WriteString(p0.Inner.Accept(s).(string)) + str.WriteString(")") + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionComparison(p0 *parse.ExpressionComparison) any { + str := strings.Builder{} + str.WriteString(p0.Left.Accept(s).(string)) + str.WriteString(" ") + str.WriteString(string(p0.Operator)) + str.WriteString(p0.Right.Accept(s).(string)) + // compare cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionLogical(p0 *parse.ExpressionLogical) any { + str := strings.Builder{} + str.WriteString(p0.Left.Accept(s).(string)) + str.WriteString(" ") + str.WriteString(string(p0.Operator)) + str.WriteString(" ") + str.WriteString(p0.Right.Accept(s).(string)) + // logical cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionArithmetic(p0 *parse.ExpressionArithmetic) any { + str := strings.Builder{} + str.WriteString(p0.Left.Accept(s).(string)) + str.WriteString(" ") + str.WriteString(string(p0.Operator)) + str.WriteString(" ") + str.WriteString(p0.Right.Accept(s).(string)) + // cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionUnary(p0 *parse.ExpressionUnary) any { + str := strings.Builder{} + str.WriteString(string(p0.Operator)) + str.WriteString(p0.Expression.Accept(s).(string)) + // cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionColumn(p0 *parse.ExpressionColumn) any { + str := strings.Builder{} + if p0.Table != "" { + str.WriteString(p0.Table) + str.WriteString(".") + } + str.WriteString(p0.Column) + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionCollate(p0 *parse.ExpressionCollate) any { + str := strings.Builder{} + str.WriteString(p0.Expression.Accept(s).(string)) + str.WriteString(" COLLATE ") + str.WriteString(p0.Collation) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionStringComparison(p0 *parse.ExpressionStringComparison) any { + str := strings.Builder{} + str.WriteString(p0.Left.Accept(s).(string)) + str.WriteString(" ") + str.WriteString(string(p0.Operator)) + str.WriteString(" ") + str.WriteString(p0.Right.Accept(s).(string)) + // compare cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionIs(p0 *parse.ExpressionIs) any { + str := strings.Builder{} + str.WriteString(p0.Left.Accept(s).(string)) + str.WriteString(" IS ") + if p0.Not { + str.WriteString("NOT ") + } + if p0.Distinct { + str.WriteString("DISTINCT ") + } + str.WriteString(p0.Right.Accept(s).(string)) + // cannot be typecasted + return str.String() +} + +func (s *sqlGenerator) VisitExpressionIn(p0 *parse.ExpressionIn) any { + str := strings.Builder{} + str.WriteString(p0.Expression.Accept(s).(string)) + if p0.Not { + str.WriteString(" NOT") + } + str.WriteString(" IN (") + if len(p0.List) > 0 { + for i, arg := range p0.List { + if i > 0 { + str.WriteString(", ") + } + + str.WriteString(arg.Accept(s).(string)) + } + } else if p0.Subquery != nil { + str.WriteString(p0.Subquery.Accept(s).(string)) + } else { + panic("IN must specify list or subquery") + } + str.WriteString(")") + + return str.String() +} + +func (s *sqlGenerator) VisitExpressionBetween(p0 *parse.ExpressionBetween) any { + str := strings.Builder{} + str.WriteString(p0.Expression.Accept(s).(string)) + if p0.Not { + str.WriteString(" NOT") + } + str.WriteString(" BETWEEN ") + + str.WriteString(p0.Lower.Accept(s).(string)) + str.WriteString(" AND ") + str.WriteString(p0.Upper.Accept(s).(string)) + + return str.String() +} + +func (s *sqlGenerator) VisitExpressionSubquery(p0 *parse.ExpressionSubquery) any { + str := strings.Builder{} + if p0.Exists { + if p0.Not { + str.WriteString("NOT ") + } + str.WriteString("EXISTS ") + } + + str.WriteString("(") + str.WriteString(p0.Subquery.Accept(s).(string)) + str.WriteString(")") + typeCast(p0, &str) + return str.String() +} + +func (s *sqlGenerator) VisitExpressionCase(p0 *parse.ExpressionCase) any { + str := strings.Builder{} + str.WriteString("CASE") + if p0.Case != nil { + str.WriteString(" ") + str.WriteString(p0.Case.Accept(s).(string)) + } + for _, whenThen := range p0.WhenThen { + str.WriteString("\n WHEN ") + str.WriteString(whenThen[0].Accept(s).(string)) + str.WriteString("\n THEN ") + str.WriteString(whenThen[1].Accept(s).(string)) + } + if p0.Else != nil { + str.WriteString("\n ELSE ") + str.WriteString(p0.Else.Accept(s).(string)) + } + str.WriteString("\n END") + return str.String() +} + +func (s *sqlGenerator) VisitCommonTableExpression(p0 *parse.CommonTableExpression) any { + str := strings.Builder{} + str.WriteString(p0.Name) + if p0.Columns != nil { + str.WriteString(" (") + for i, col := range p0.Columns { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(col) + } + str.WriteString(")") + } + str.WriteString(" AS (") + str.WriteString(p0.Query.Accept(s).(string)) + str.WriteString(")") + return str.String() +} + +func (s *sqlGenerator) VisitSQLStatement(p0 *parse.SQLStatement) any { + str := strings.Builder{} + for i, cte := range p0.CTEs { + if i > 0 { + str.WriteString(", ") + } + if i == 0 { + str.WriteString("WITH ") + } + str.WriteString(cte.Accept(s).(string)) + } + str.WriteString("\n") + + str.WriteString(p0.SQL.Accept(s).(string)) + + return str.String() +} + +func (s *sqlGenerator) VisitSelectStatement(p0 *parse.SelectStatement) any { + str := strings.Builder{} + for i, core := range p0.SelectCores { + if i > 0 { + str.WriteString(" ") + str.WriteString(string(p0.CompoundOperators[i-1])) + str.WriteString(" ") + } + str.WriteString(core.Accept(s).(string)) + str.WriteString("\n") + } + + for i, order := range p0.Ordering { + if i == 0 { + str.WriteString("ORDER BY ") + } else { + str.WriteString(", ") + } + + str.WriteString(order.Accept(s).(string)) + } + + if p0.Limit != nil { + str.WriteString(" LIMIT ") + str.WriteString(p0.Limit.Accept(s).(string)) + } + + if p0.Offset != nil { + str.WriteString(" OFFSET ") + str.WriteString(p0.Offset.Accept(s).(string)) + } + + return str.String() +} + +func (s *sqlGenerator) VisitSelectCore(p0 *parse.SelectCore) any { + str := strings.Builder{} + str.WriteString("SELECT ") + if p0.Distinct { + str.WriteString("DISTINCT ") + } + + for i, resultColumn := range p0.Columns { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(resultColumn.Accept(s).(string)) + } + + if p0.From != nil { + str.WriteString("\nFROM ") + str.WriteString(p0.From.Accept(s).(string)) + } + + for _, join := range p0.Joins { + str.WriteString("\n") + str.WriteString(join.Accept(s).(string)) + } + + if p0.Where != nil { + str.WriteString("\nWHERE ") + str.WriteString(p0.Where.Accept(s).(string)) + } + + if p0.GroupBy != nil { + str.WriteString("\nGROUP BY ") + for i, groupBy := range p0.GroupBy { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(groupBy.Accept(s).(string)) + } + + if p0.Having != nil { + str.WriteString("\nHAVING ") + str.WriteString(p0.Having.Accept(s).(string)) + } + } + + return str.String() +} + +func (s *sqlGenerator) VisitResultColumnExpression(p0 *parse.ResultColumnExpression) any { + str := strings.Builder{} + str.WriteString(p0.Expression.Accept(s).(string)) + if p0.Alias != "" { + str.WriteString(" AS ") + str.WriteString(p0.Alias) + } + return str.String() +} + +func (s *sqlGenerator) VisitResultColumnWildcard(p0 *parse.ResultColumnWildcard) any { + str := strings.Builder{} + if p0.Table != "" { + str.WriteString(p0.Table) + str.WriteString(".") + } + str.WriteString("*") + return str.String() +} + +func (s *sqlGenerator) VisitRelationTable(p0 *parse.RelationTable) any { + str := strings.Builder{} + if s.pgSchema != "" { + str.WriteString(s.pgSchema) + str.WriteString(".") + } + str.WriteString(p0.Table) + if p0.Alias != "" { + str.WriteString(" AS ") + str.WriteString(p0.Alias) + } + return str.String() +} + +func (s *sqlGenerator) VisitRelationSubquery(p0 *parse.RelationSubquery) any { + str := strings.Builder{} + str.WriteString("(") + str.WriteString(p0.Subquery.Accept(s).(string)) + str.WriteString(") ") + if p0.Alias != "" { + str.WriteString("AS ") + str.WriteString(p0.Alias) + } + return str.String() +} + +func (s *sqlGenerator) VisitRelationFunctionCall(p0 *parse.RelationFunctionCall) any { + str := strings.Builder{} + str.WriteString(p0.FunctionCall.Accept(s).(string)) + str.WriteString(" ") + if p0.Alias != "" { + str.WriteString("AS ") + str.WriteString(p0.Alias) + } + return str.String() +} + +func (s *sqlGenerator) VisitJoin(p0 *parse.Join) any { + str := strings.Builder{} + str.WriteString(string(p0.Type)) + str.WriteString(" JOIN ") + str.WriteString(p0.Relation.Accept(s).(string)) + // we do not worry about on being nil, since Kwil + // forces the user to specify the join condition + // to prevent cartesian products + str.WriteString(" ON ") + str.WriteString(p0.On.Accept(s).(string)) + return str.String() +} + +func (s *sqlGenerator) VisitUpdateStatement(p0 *parse.UpdateStatement) any { + str := strings.Builder{} + str.WriteString("UPDATE ") + if s.pgSchema != "" { + str.WriteString(s.pgSchema) + str.WriteString(".") + } + str.WriteString(p0.Table) + if p0.Alias != "" { + str.WriteString(" AS ") + str.WriteString(p0.Alias) + } + str.WriteString("\nSET ") + for i, set := range p0.SetClause { + if i > 0 { + str.WriteString(",\n") + } + str.WriteString(set.Accept(s).(string)) + } + + if p0.From != nil { + str.WriteString("\nFROM ") + str.WriteString(p0.From.Accept(s).(string)) + } + + for _, join := range p0.Joins { + str.WriteString("\n") + str.WriteString(join.Accept(s).(string)) + } + + if p0.Where != nil { + str.WriteString("\nWHERE ") + str.WriteString(p0.Where.Accept(s).(string)) + } + + return str.String() +} + +func (s *sqlGenerator) VisitUpdateSetClause(p0 *parse.UpdateSetClause) any { + str := strings.Builder{} + str.WriteString(p0.Column) + str.WriteString(" = ") + str.WriteString(p0.Value.Accept(s).(string)) + return str.String() +} + +func (s *sqlGenerator) VisitDeleteStatement(p0 *parse.DeleteStatement) any { + str := strings.Builder{} + str.WriteString("DELETE FROM ") + + if s.pgSchema != "" { + str.WriteString(s.pgSchema) + str.WriteString(".") + } + + str.WriteString(p0.Table) + if p0.Alias != "" { + str.WriteString(" AS ") + str.WriteString(p0.Alias) + } + + if p0.From != nil { + str.WriteString("\nFROM ") + str.WriteString(p0.From.Accept(s).(string)) + } + + for _, join := range p0.Joins { + str.WriteString("\n") + str.WriteString(join.Accept(s).(string)) + } + + if p0.Where != nil { + str.WriteString("\nWHERE ") + str.WriteString(p0.Where.Accept(s).(string)) + } + + return str.String() +} + +func (s *sqlGenerator) VisitInsertStatement(p0 *parse.InsertStatement) any { + str := strings.Builder{} + str.WriteString("INSERT INTO ") + if s.pgSchema != "" { + str.WriteString(s.pgSchema) + str.WriteString(".") + } + + str.WriteString(p0.Table) + if p0.Alias != "" { + str.WriteString(" AS ") + str.WriteString(p0.Alias) + } + if len(p0.Columns) > 0 { + str.WriteString(" (") + + for i, col := range p0.Columns { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(col) + } + + str.WriteString(") ") + } + str.WriteString("\nVALUES ") + + for i, val := range p0.Values { + if i > 0 { + str.WriteString(",") + } + str.WriteString("\n(") + for j, v := range val { + if j > 0 { + str.WriteString(", ") + } + str.WriteString(v.Accept(s).(string)) + } + str.WriteString(")") + } + + if p0.Upsert != nil { + str.WriteString("\n") + str.WriteString(p0.Upsert.Accept(s).(string)) + } + + return str.String() +} + +func (s *sqlGenerator) VisitUpsertClause(p0 *parse.UpsertClause) any { + str := strings.Builder{} + str.WriteString("ON CONFLICT ") + if len(p0.ConflictColumns) > 0 { + str.WriteString("(") + for i, col := range p0.ConflictColumns { + if i > 0 { + str.WriteString(", ") + } + str.WriteString(col) + } + str.WriteString(")\n") + + if p0.ConflictWhere != nil { + str.WriteString("WHERE ") + str.WriteString(p0.ConflictWhere.Accept(s).(string)) + str.WriteString("\n") + } + } + + str.WriteString("DO ") + if p0.DoUpdate == nil { + str.WriteString("NOTHING") + } else { + str.WriteString("UPDATE SET") + for i, set := range p0.DoUpdate { + if i > 0 { + str.WriteString(",") + } + str.WriteString("\n ") + str.WriteString(set.Accept(s).(string)) + } + + if p0.UpdateWhere != nil { + str.WriteString("\nWHERE ") + str.WriteString(p0.UpdateWhere.Accept(s).(string)) + } + } + + return str.String() +} + +func (s *sqlGenerator) VisitOrderingTerm(p0 *parse.OrderingTerm) any { + str := strings.Builder{} + str.WriteString(p0.Expression.Accept(s).(string)) + + if p0.Order != "" { + str.WriteString(" ") + str.WriteString(string(p0.Order)) + } + + if p0.Nulls != "" { + str.WriteString(" NULLS ") + str.WriteString(string(p0.Nulls)) + } + + return str.String() +} + +// procedureGenerator is a visitor that generates plpgsql code. +type procedureGenerator struct { + sqlGenerator + // anonymousReceivers counts the amount of anonymous receivers + // we should declare. This will be cross-referenced with the + // analyzer to ensure we declare the correct amount. + anonymousReceivers int + // procedure is the procedure we are generating code for + procedure *types.Procedure +} + +var _ parse.ProcedureVisitor = &procedureGenerator{} + +func (p *procedureGenerator) VisitProcedureStmtDeclaration(p0 *parse.ProcedureStmtDeclaration) any { + // plpgsql declares variables at the top of the procedure + return "" +} + +func (p *procedureGenerator) VisitProcedureStmtAssignment(p0 *parse.ProcedureStmtAssign) any { + varName := p0.Variable.Accept(p).(string) + return varName + " := " + p0.Value.Accept(p).(string) + ";\n" +} + +func (p *procedureGenerator) VisitProcedureStmtCall(p0 *parse.ProcedureStmtCall) any { + call := p0.Call.Accept(p).(string) + + if len(p0.Receivers) == 0 { + return "PERFORM " + call + ";\n" + } + + s := strings.Builder{} + s.WriteString("SELECT * INTO ") + + for i, rec := range p0.Receivers { + if i > 0 { + s.WriteString(", ") + } + if rec == nil { + s.WriteString(formatAnonymousReceiver(p.anonymousReceivers)) + p.anonymousReceivers++ + } else { + s.WriteString(rec.Accept(p).(string)) + } + } + + s.WriteString(" FROM ") + s.WriteString(call) + s.WriteString(";\n") + return s.String() +} + +func (p *procedureGenerator) VisitProcedureStmtForLoop(p0 *parse.ProcedureStmtForLoop) any { + s := strings.Builder{} + // if we are iterating over an array, the syntax is different + switch v := p0.LoopTerm.(type) { + case *parse.LoopTermRange, *parse.LoopTermSQL: + s.WriteString("FOR ") + s.WriteString(p0.Receiver.Accept(p).(string)) + s.WriteString(" IN ") + s.WriteString(p0.LoopTerm.Accept(p).(string)) + case *parse.LoopTermVariable: + s.WriteString("FOREACH ") + s.WriteString(p0.Receiver.Accept(p).(string)) + s.WriteString(" IN ") + s.WriteString(p0.LoopTerm.Accept(p).(string)) + default: + panic("unknown loop term type: " + fmt.Sprintf("%T", v)) + } + + s.WriteString(" LOOP\n") + + for _, stmt := range p0.Body { + s.WriteString(stmt.Accept(p).(string)) + } + + s.WriteString("END LOOP;\n") + + return s.String() +} + +func (p *procedureGenerator) VisitLoopTermRange(p0 *parse.LoopTermRange) any { + s := strings.Builder{} + s.WriteString(p0.Start.Accept(p).(string)) + s.WriteString("..") + s.WriteString(p0.End.Accept(p).(string)) + return s.String() +} + +func (p *procedureGenerator) VisitLoopTermSQL(p0 *parse.LoopTermSQL) any { + return p0.Statement.Accept(p).(string) +} + +func (p *procedureGenerator) VisitLoopTermVariable(p0 *parse.LoopTermVariable) any { + return fmt.Sprintf("ARRAY %s", p0.Variable.Accept(p).(string)) +} + +func (p *procedureGenerator) VisitProcedureStmtIf(p0 *parse.ProcedureStmtIf) any { + s := strings.Builder{} + for i, clause := range p0.IfThens { + if i == 0 { + s.WriteString("IF ") + } else { + s.WriteString("ELSIF ") + } + + s.WriteString(clause.Accept(p).(string)) + } + + if p0.Else != nil { + s.WriteString("ELSE\n") + for _, stmt := range p0.Else { + + s.WriteString(stmt.Accept(p).(string)) + } + } + + s.WriteString("END IF;\n") + return s.String() +} + +func (p *procedureGenerator) VisitIfThen(p0 *parse.IfThen) any { + s := strings.Builder{} + s.WriteString(p0.If.Accept(p).(string)) + s.WriteString(" THEN\n") + for _, stmt := range p0.Then { + s.WriteString(stmt.Accept(p).(string)) + } + + return s.String() +} + +func (p *procedureGenerator) VisitProcedureStmtSQL(p0 *parse.ProcedureStmtSQL) any { + return p0.SQL.Accept(p).(string) + ";\n" +} + +func (p *procedureGenerator) VisitProcedureStmtBreak(p0 *parse.ProcedureStmtBreak) any { + return "EXIT;\n" +} + +func (p *procedureGenerator) VisitProcedureStmtReturn(p0 *parse.ProcedureStmtReturn) any { + if p0.SQL != nil { + return "RETURN QUERY " + p0.SQL.Accept(p).(string) + ";\n" + } + + s := strings.Builder{} + for i, expr := range p0.Values { + s.WriteString(formatReturnVar(i)) + s.WriteString(" := ") + s.WriteString(expr.Accept(p).(string)) + s.WriteString(";\n") + } + + s.WriteString("RETURN;") + return s.String() +} + +func (p *procedureGenerator) VisitProcedureStmtReturnNext(p0 *parse.ProcedureStmtReturnNext) any { + s := strings.Builder{} + for i, expr := range p0.Values { + // we do not format the return var for return next, but instead + // assign it to the column name directly + s.WriteString(p.procedure.Returns.Fields[i].Name) + s.WriteString(" := ") + s.WriteString(expr.Accept(p).(string)) + s.WriteString(";\n") + } + + s.WriteString("RETURN NEXT;\n") + return s.String() +} + +// formatPGLiteral formats a literal for user in postgres. +func formatPGLiteral(value any) (string, error) { + str := strings.Builder{} + switch v := value.(type) { + case string: // for text type + // escape single quotes + str.WriteString("'") + str.WriteString(strings.ReplaceAll(v, "'", "''")) + str.WriteString("'") + case int64, int, int32: // for int type + str.WriteString(fmt.Sprint(v)) + case types.UUID: + str.WriteString(v.String()) + case *uint256.Int: + str.WriteString(v.String()) + case *decimal.Decimal: + str.WriteString(v.String()) + case bool: // for bool type + if v { + str.WriteString("true") + } else { + str.WriteString("false") + } + case []byte: // for blob type: https://dba.stackexchange.com/questions/203358/how-do-i-write-a-hex-literal-in-postgresql + str.WriteString(fmt.Sprintf("E'\\\\x%x'", v)) + case nil: + str.WriteString("NULL") + default: + return "", fmt.Errorf("unsupported literal type: %T", v) + } + + return str.String(), nil +} + +// FormatProcedureName formats a procedure name for usage in postgres. This +// simply prepends the name with _fp_ +func formatForeignProcedureName(name string) string { + return "_fp_" + name +} + +// formatAnonymousReceiver creates a plpgsql variable name for anonymous receivers. +func formatAnonymousReceiver(index int) string { + return fmt.Sprintf("_anon_%d", index) +} + +// formatReturnVar formats a return variable name for usage in postgres. +func formatReturnVar(i int) string { + return fmt.Sprintf("_out_%d", i) +} + +// formatVariable formats an expression variable for usage in postgres. +func formatVariable(e *parse.ExpressionVariable) string { + switch e.Prefix { + case parse.VariablePrefixDollar: + return formatParameterName(e.Name) + case parse.VariablePrefixAt: + return formatContextualVariableName(e.Name) + default: + // should never happen + panic("invalid variable prefix: " + string(e.Prefix)) + } +} + +// formatParameterName formats a parameter name for usage in postgres. This +// simply prepends the name with _param_. It expects the name does not have +// the $ prefix +func formatParameterName(name string) string { + return "_param_" + name +} + +// formatContextualVariableName formats a contextual variable name for usage in postgres. +// This uses the current_setting function to get the value of the variable. It also +// removes the @ prefix. If the type is not a text type, it will also type cast it. +// The type casting is necessary since current_setting returns all values as text. +func formatContextualVariableName(name string) string { + str := fmt.Sprintf("current_setting('%s.%s')", PgSessionPrefix, name) + + dataType, ok := parse.SessionVars[name] + if !ok { + panic("unknown contextual variable: " + name) + } + + switch dataType { + case types.BlobType: + return fmt.Sprintf("%s::bytea", str) + case types.IntType: + return fmt.Sprintf("%s::int8", str) + case types.BoolType: + return fmt.Sprintf("%s::bool", str) + case types.UUIDType: + return fmt.Sprintf("%s::uuid", str) + case types.TextType: + return str + default: + panic("unallowed contextual variable type: " + dataType.String()) + } +} diff --git a/internal/engine/generate/procedure.go b/internal/engine/generate/procedure.go new file mode 100644 index 000000000..7ca8675c7 --- /dev/null +++ b/internal/engine/generate/procedure.go @@ -0,0 +1,268 @@ +package generate + +import ( + "fmt" + "strings" + + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/utils/order" + "github.com/kwilteam/kwil-db/parse" +) + +// GenerateProcedure generates the plpgsql code for a procedure. +func GenerateProcedure(proc *types.Procedure, schema *types.Schema, pgSchema string) (ddl string, err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("panic: %v", e) + } + + // annotate the error with the procedure name + if err != nil { + err = fmt.Errorf("procedure %s: %w", proc.Name, err) + } + }() + + res, err := parse.ParseProcedure(proc, schema) + if err != nil { + return "", err + } + + if res.ParseErrs.Err() != nil { + return "", res.ParseErrs.Err() + } + + vars := make([]*types.NamedType, len(proc.Parameters)) + for i, param := range proc.Parameters { + vars[i] = &types.NamedType{ + Name: formatParameterName(param.Name[1:]), + Type: param.Type, + } + } + + // we copy the return as to not modify it + // we need to write return types if there are any. + // If it returns a table, we do not want to change the column names, + // since it will change the result. However, if there are out variables, + // we want to format them + var ret types.ProcedureReturn + if proc.Returns != nil { + ret.IsTable = proc.Returns.IsTable + ret.Fields = make([]*types.NamedType, len(proc.Returns.Fields)) + for i, field := range proc.Returns.Fields { + if ret.IsTable { + ret.Fields[i] = field + } else { + ret.Fields[i] = &types.NamedType{ + Name: formatReturnVar(i), + Type: field.Type, + } + } + } + } + + analyzed := &analyzedProcedure{ + Name: proc.Name, + Parameters: vars, + Returns: ret, + IsView: proc.IsView(), + OwnerOnly: proc.IsOwnerOnly(), + } + + // we need to get the variables and anonymous variables (loop targets) + for _, v := range order.OrderMap(res.Variables) { + if v.Key[0] != '$' { + panic(fmt.Sprintf("internal bug: expected variable name to start with $, got name %s", v.Key)) + } + + analyzed.DeclaredVariables = append(analyzed.DeclaredVariables, &types.NamedType{ + Name: formatParameterName(v.Key[1:]), + Type: v.Value, + }) + } + + for _, v := range order.OrderMap(res.CompoundVariables) { + // TODO: this isn't a perfect solution. Only loop targets for + // SQL statements are put here. Loops targets over ranges and arrays + // would be raw variables. These should be declared as their base types, not RECORD. + if v.Key[0] != '$' { + panic(fmt.Sprintf("internal bug: expected variable name to start with $, got name %s", v.Key)) + } + analyzed.LoopTargets = append(analyzed.LoopTargets, formatParameterName(v.Key[1:])) + } + + // we need to visit the AST to get the generated body + sqlGen := &procedureGenerator{ + sqlGenerator: sqlGenerator{ + pgSchema: pgSchema, + }, + procedure: proc, + } + + str := strings.Builder{} + for _, stmt := range res.AST { + str.WriteString(stmt.Accept(sqlGen).(string)) + } + + // little sanity check: + if len(res.AnonymousReceivers) != sqlGen.anonymousReceivers { + return "", fmt.Errorf("internal bug: expected %d anonymous variables, got %d", sqlGen.anonymousReceivers, len(res.CompoundVariables)) + } + // append all anonymous variables to the declared variables + for i, v := range res.AnonymousReceivers { + analyzed.DeclaredVariables = append(analyzed.DeclaredVariables, &types.NamedType{ + Name: formatAnonymousReceiver(i), + Type: v, + }) + } + + analyzed.Body = str.String() + + return generateProcedureWrapper(analyzed, pgSchema) +} + +type analyzedProcedure struct { + // Name is the name of the procedure. + Name string + // Parameters are the parameters, in order, that the procedure is expecting. + // If no parameters are expected, this will be nil. + Parameters []*types.NamedType + // Returns is the expected return type(s) of the procedure. + // If no return is expected, this will be nil. + Returns types.ProcedureReturn + // DeclaredVariables are the variables that need to be declared. + DeclaredVariables []*types.NamedType + // LoopTargets is a list of all variables that are loop targets. + // They should be declared as RECORD in plpgsql. + LoopTargets []string + // Body is the plpgsql code for the procedure. + Body string + // IsView is true if the procedure is a view. + IsView bool + // OwnerOnly is true if the procedure is owner-only. + OwnerOnly bool +} + +// generateProcedureWrapper generates the plpgsql code for a procedure, not including the body. +// It takes a procedure and the body of the procedure and returns the plpgsql code that creates +// the procedure. +func generateProcedureWrapper(proc *analyzedProcedure, pgSchema string) (string, error) { + str := strings.Builder{} + str.WriteString("CREATE OR REPLACE FUNCTION ") + str.WriteString(fmt.Sprintf("%s.%s(", pgSchema, proc.Name)) + + // writing the function parameters + + // paramSet tracks the used params, and will not allow them + // to be redeclared in the DECLARE section. + paramSet := make(map[string]struct{}) + i := -1 + var field *types.NamedType + for i, field = range proc.Parameters { + if i != 0 { + str.WriteString(", ") + } + + paramSet[field.Name] = struct{}{} + + typ, err := field.Type.PGString() + if err != nil { + return "", err + } + + str.WriteString(fmt.Sprintf("%s %s", field.Name, typ)) + } + + hasOutReturns := false + if len(proc.Returns.Fields) > 0 && !proc.Returns.IsTable { + hasOutReturns = true + if i != -1 { + str.WriteString(", ") + } + + for i, field := range proc.Returns.Fields { + if i != 0 { + str.WriteString(", ") + } + + typ, err := field.Type.PGString() + if err != nil { + return "", err + } + + str.WriteString(fmt.Sprintf("OUT %s %s", field.Name, typ)) + } + } + + str.WriteString(") ") + + // writing the return type + if proc.Returns.IsTable && len(proc.Returns.Fields) > 0 { + str.WriteString("\nRETURNS ") + + str.WriteString("TABLE(") + for i, field := range proc.Returns.Fields { + if i != 0 { + str.WriteString(", ") + } + + typ, err := field.Type.PGString() + if err != nil { + return "", err + } + + str.WriteString(fmt.Sprintf("%s %s", field.Name, typ)) + } + str.WriteString(") ") + } else if !hasOutReturns { + str.WriteString("\nRETURNS void ") + } + + str.WriteString("AS $$\n") + + // we can only have conflict if we use RETURN TABLE. Since we don't allow + // direct assignment to columns like plpgsql, we always want these conflicts + // to refer to the columns. + // see: https://www.postgresql.org/docs/current/plpgsql-implementation.html + str.WriteString("#variable_conflict use_column\n") + + // writing the variable declarations + + // declaresTypes tracks if the DECLARE section is needed. + declaresTypes := false + declareSection := strings.Builder{} + if len(proc.DeclaredVariables) > 0 { + for _, declare := range proc.DeclaredVariables { + _, ok := paramSet[declare.Name] + if ok { + continue + } + + typ, err := declare.Type.PGString() + if err != nil { + return "", err + } + + declaresTypes = true + declareSection.WriteString(fmt.Sprintf("%s %s;\n", declare.Name, typ)) + } + } + if len(proc.LoopTargets) > 0 { + declaresTypes = true + for _, loopTarget := range proc.LoopTargets { + declareSection.WriteString(fmt.Sprintf("%s RECORD;\n", loopTarget)) + } + } + + if declaresTypes { + str.WriteString("DECLARE\n") + str.WriteString(declareSection.String()) + } + + // finishing the function + + str.WriteString("BEGIN\n") + str.WriteString(proc.Body) + str.WriteString("\nEND;\n$$ LANGUAGE plpgsql;") + + return str.String(), nil +} diff --git a/internal/engine/ddl/procedure_test.go b/internal/engine/generate/procedure_test.go similarity index 82% rename from internal/engine/ddl/procedure_test.go rename to internal/engine/generate/procedure_test.go index 1d228f86e..271d59d12 100644 --- a/internal/engine/ddl/procedure_test.go +++ b/internal/engine/generate/procedure_test.go @@ -1,12 +1,10 @@ -package ddl_test +package generate import ( "fmt" "testing" "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/internal/engine/ddl" - "github.com/kwilteam/kwil-db/parse/procedures" "github.com/stretchr/testify/assert" ) @@ -37,7 +35,7 @@ func Test_Procedure(t *testing.T) { }, returns: nil, decls: nil, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT) \nRETURNS void AS $$\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT) \nRETURNS void AS $$\n#variable_conflict use_column\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "multiple fields and return types", @@ -72,7 +70,7 @@ func Test_Procedure(t *testing.T) { }, }, decls: nil, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT[], field2 TEXT, OUT _out_0 TEXT[], OUT _out_1 BOOL) AS $$\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT[], field2 TEXT, OUT _out_0 TEXT[], OUT _out_1 BOOL) AS $$\n#variable_conflict use_column\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "no fields, multiple return types", @@ -95,7 +93,7 @@ func Test_Procedure(t *testing.T) { }, }, decls: nil, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(OUT _out_0 TEXT[], OUT _out_1 BOOL) AS $$\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(OUT _out_0 TEXT[], OUT _out_1 BOOL) AS $$\n#variable_conflict use_column\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "single field, single return type", @@ -114,7 +112,7 @@ func Test_Procedure(t *testing.T) { }, }, decls: nil, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT, OUT _out_0 TEXT) AS $$\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT, OUT _out_0 TEXT) AS $$\n#variable_conflict use_column\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "return table", @@ -148,7 +146,7 @@ func Test_Procedure(t *testing.T) { }, }, }, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure() \nRETURNS TABLE(field1 TEXT, field2 INT8[]) AS $$\nDECLARE\nlocal_type TEXT;\ncars INT8[];\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure() \nRETURNS TABLE(field1 TEXT, field2 INT8[]) AS $$\n#variable_conflict use_column\nDECLARE\nlocal_type TEXT;\ncars INT8[];\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "variable is declared as parameter", @@ -165,7 +163,7 @@ func Test_Procedure(t *testing.T) { Type: types.TextType, }, }, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT) \nRETURNS void AS $$\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure(field1 TEXT) \nRETURNS void AS $$\n#variable_conflict use_column\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, { name: "loops", @@ -175,7 +173,7 @@ func Test_Procedure(t *testing.T) { loopTargets: []string{ "loop1", }, - want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure() \nRETURNS void AS $$\nDECLARE\nloop1 RECORD;\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", + want: "CREATE OR REPLACE FUNCTION test_schema.test_procedure() \nRETURNS void AS $$\n#variable_conflict use_column\nDECLARE\nloop1 RECORD;\nBEGIN\ntest_body\nEND;\n$$ LANGUAGE plpgsql;", }, } @@ -198,7 +196,7 @@ func Test_Procedure(t *testing.T) { ret = *test.returns } - got, err := ddl.GenerateProcedure(&procedures.AnalyzedProcedure{ + got, err := generateProcedureWrapper(&analyzedProcedure{ Name: name, Parameters: test.fields, Returns: ret, diff --git a/internal/engine/generate/sql.go b/internal/engine/generate/sql.go new file mode 100644 index 000000000..e2881ff9b --- /dev/null +++ b/internal/engine/generate/sql.go @@ -0,0 +1,27 @@ +package generate + +import ( + "fmt" + + "github.com/kwilteam/kwil-db/parse" +) + +// WriteSQL converts a SQL node to a string. +// It can optionally rewrite named parameters to numbered parameters. +// If so, it returns the order of the parameters in the order they appear in the statement. +func WriteSQL(node *parse.SQLStatement, orderParams bool, pgSchema string) (stmt string, params []string, err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("panic: %v", e) + } + }() + sqlGen := &sqlGenerator{ + pgSchema: pgSchema, + } + if orderParams { + sqlGen.numberParameters = true + } + stmt = node.Accept(sqlGen).(string) + + return stmt + ";", sqlGen.orderedParams, nil +} diff --git a/internal/engine/ddl/table.go b/internal/engine/generate/table.go similarity index 99% rename from internal/engine/ddl/table.go rename to internal/engine/generate/table.go index 8fb73c1b6..65f9422d3 100644 --- a/internal/engine/ddl/table.go +++ b/internal/engine/generate/table.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "fmt" diff --git a/internal/engine/ddl/utils.go b/internal/engine/generate/utils.go similarity index 98% rename from internal/engine/ddl/utils.go rename to internal/engine/generate/utils.go index 7fb4cff29..2cd9948f0 100644 --- a/internal/engine/ddl/utils.go +++ b/internal/engine/generate/utils.go @@ -1,4 +1,4 @@ -package ddl +package generate import ( "fmt" diff --git a/internal/engine/integration/deployment_test.go b/internal/engine/integration/deployment_test.go index b68d7f64f..4fd77fef1 100644 --- a/internal/engine/integration/deployment_test.go +++ b/internal/engine/integration/deployment_test.go @@ -7,8 +7,7 @@ import ( "testing" "github.com/kwilteam/kwil-db/common" - "github.com/kwilteam/kwil-db/parse/kuneiform" - parseTypes "github.com/kwilteam/kwil-db/parse/types" + "github.com/kwilteam/kwil-db/parse" "github.com/stretchr/testify/require" ) @@ -38,7 +37,7 @@ func Test_Deployment(t *testing.T) { procedure mutate_in_view() public view { INSERT INTO users (id) VALUES (1); }`, - err: parseTypes.ErrReadOnlyProcedureContainsDML, + err: parse.ErrViewMutatesState, }, { name: "view procedure calls non-view", @@ -56,7 +55,7 @@ func Test_Deployment(t *testing.T) { procedure not_a_view() public { INSERT INTO users (id) VALUES (1); }`, - err: parseTypes.ErrReadOnlyProcedureCallsMutative, + err: parse.ErrViewMutatesState, }, { name: "empty procedure", @@ -68,25 +67,24 @@ func Test_Deployment(t *testing.T) { }, { name: "untyped variable", - procedure: `$intval := 1;`, - err: parseTypes.ErrUntypedVariable, + procedure: `$intval := 1;`, // this can infer the type }, { name: "undeclared variable", procedure: `$intval int := $a;`, - err: parseTypes.ErrUndeclaredVariable, + err: parse.ErrUndeclaredVariable, }, { name: "non-existent @ variable", procedure: `$id int := @ethereum_height;`, - err: parseTypes.ErrUnknownContextualVariable, + err: parse.ErrUnknownContextualVariable, }, { name: "unknown function", procedure: ` $int int := unknown_function(); `, - err: parseTypes.ErrUnknownFunctionOrProcedure, + err: parse.ErrUnknownFunctionOrProcedure, }, { name: "known procedure", @@ -98,7 +96,7 @@ func Test_Deployment(t *testing.T) { } procedure known_procedure_2() public { - for $row in select * from known_procedure() { + for $row in select * from known_procedure() as k { } } @@ -111,7 +109,7 @@ func Test_Deployment(t *testing.T) { break; } `, - err: parseTypes.ErrUnknownFunctionOrProcedure, + err: parse.ErrUnknownFunctionOrProcedure, }, { name: "various foreign procedures", @@ -125,7 +123,7 @@ func Test_Deployment(t *testing.T) { $int1 int := get_scalar['dbid', 'get_scalar'](1); $int2 int := get_named_scalar['dbid', 'get_scalar'](1); - return select * from get_tbl['dbid', 'get_table'](); + return select * from get_tbl['dbid', 'get_table']() as u; } `, }, @@ -176,12 +174,12 @@ func Test_Deployment(t *testing.T) { { name: "action references unknown foreign procedure", schema: `database select_join; - + action get_all() public view { select * from get_tbl['dbid', 'get_tbl'](); } `, - err: parseTypes.ErrUnknownFunctionOrProcedure, + err: parse.ErrUnknownFunctionOrProcedure, }, } @@ -219,10 +217,10 @@ func Test_Deployment(t *testing.T) { // we intentionally use the bare kuneiform parser and don't // perform extra checks because we want to test that the engine // catches these errors - parsed, _, _, err := kuneiform.Parse(schema) + parsed, err := parse.ParseSchema([]byte(schema)) require.NoError(t, err) - err = global.CreateDataset(ctx, tx, parsed, &common.TransactionData{ + err = global.CreateDataset(ctx, tx, parsed.Schema, &common.TransactionData{ Signer: owner, Caller: string(owner), TxID: "test", diff --git a/internal/engine/integration/procedure_test.go b/internal/engine/integration/procedure_test.go new file mode 100644 index 000000000..64de57faf --- /dev/null +++ b/internal/engine/integration/procedure_test.go @@ -0,0 +1,200 @@ +//go:build pglive + +package integration_test + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/kwilteam/kwil-db/common" + "github.com/kwilteam/kwil-db/parse" + "github.com/stretchr/testify/require" +) + +// This test is used to easily test procedure inputs/outputs and logic. +// All tests are given the same schema with a few tables and procedures, as well +// as mock data. The test is then able to define its own procedure, the inputs, +// outputs, and expected error (if any). +// TODO: we need to fix this test, which is currently not working. Since the parsing will +// be changing, I will leave it as is for now. +func Test_Procedures(t *testing.T) { + schema := ` + database ecclesia; + + table users { + id uuid primary key, + name text not null maxlen(100) minlen(4) unique, + wallet_address text not null + } + + table posts { + id uuid primary key, + user_id uuid not null, + content text not null maxlen(300), + foreign key (user_id) references users(id) + } + + procedure create_user($name text) public { + INSERT INTO users (id, name, wallet_address) + VALUES (uuid_generate_v5('985b93a4-2045-44d6-bde4-442a4e498bc6'::uuid, @txid), + $name, + @caller + ); + } + + procedure owns_user($wallet text, $name text) public view returns (owns bool) { + $exists bool := false; + for $row in SELECT * FROM users WHERE wallet_address = $wallet + AND name = $name { + $exists := true; + } + + return $exists; + } + + procedure id_from_name($name text) public view returns (id uuid) { + for $row in SELECT id FROM users WHERE name = $name { + return $row.id; + } + error('user not found'); + } + + procedure create_post($username text, $content text) public { + if owns_user(@caller, $username) == false { + error('caller does not own user'); + } + + INSERT INTO posts (id, user_id, content) + VALUES (uuid_generate_v5('985b93a4-2045-44d6-bde4-442a4e498bc6'::uuid, @txid), + id_from_name($username), + $content + ); + } + ` + + // maps usernames to post content. + initialData := map[string][]string{ + "satoshi": {"hello world", "goodbye world", "buy $btc to grow laser eyes"}, + "zeus": {"i am zeus", "i am the god of thunder", "i am the god of lightning"}, + "wendys_drive_through_lady": {"hi how can I help you", "no I don't know what the federal reserve is", "sir this is a wendys"}, + } + + type testcase struct { + name string + procedure string + inputs []any // can be nil + outputs [][]any // can be nil + err error // can be nil + } + + tests := []testcase{ + { + name: "basic test", + procedure: `procedure create_user2($name text) public { + INSERT INTO users (id, name, wallet_address) + VALUES (uuid_generate_v5('985b93a4-2045-44d6-bde4-442a4e498bc6'::uuid, @txid), + $name, + @caller + ); + }`, + inputs: []any{"test_user"}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + global, db, err := setup(t) + if err != nil { + t.Fatal(err) + } + defer cleanup(t, db) + + ctx := context.Background() + + tx, err := db.BeginOuterTx(ctx) + require.NoError(t, err) + defer tx.Rollback(ctx) + + // deploy schema + parsed, err := parse.ParseSchema([]byte(schema + test.procedure)) + require.NoError(t, err) + require.NoError(t, parsed.Err()) + + err = global.CreateDataset(ctx, tx, parsed.Schema, &common.TransactionData{ + Signer: []byte("deployer"), + Caller: "deployer", + TxID: "deploydb", + }) + require.NoError(t, err) + + // get dbid + dbs, err := global.ListDatasets([]byte("deployer")) + require.NoError(t, err) + require.Len(t, dbs, 1) + dbid := dbs[0].DBID + + // create initial data + for username, posts := range initialData { + _, err = global.Procedure(ctx, tx, &common.ExecutionData{ + TransactionData: common.TransactionData{ + Signer: []byte("username_signer"), + Caller: "username_caller", + TxID: "create_user_" + username, + }, + Dataset: dbid, + Procedure: "create_user", + Args: []any{username}, + }) + require.NoError(t, err) + + for i, post := range posts { + _, err = global.Procedure(ctx, tx, &common.ExecutionData{ + TransactionData: common.TransactionData{ + Signer: []byte("username_signer"), + Caller: "username_caller", + TxID: "create_post_" + username + "_" + fmt.Sprint(i), + }, + Dataset: dbid, + Procedure: "create_post", + Args: []any{username, post}, + }) + require.NoError(t, err) + } + } + + // parse out procedure name + procs := strings.Split(test.procedure, " ") + procedureName := strings.Split(procs[1], "(")[0] + procedureName = strings.TrimSpace(procedureName) + + // execute test procedure + res, err := global.Procedure(ctx, tx, &common.ExecutionData{ + TransactionData: common.TransactionData{ + Signer: []byte("test_signer"), + Caller: "test_caller", + TxID: "test", + }, + Dataset: dbid, + Procedure: procedureName, + Args: test.inputs, + }) + if test.err != nil { + require.Error(t, err) + require.ErrorIs(t, err, test.err) + return + } + require.NoError(t, err) + + require.Len(t, res.Rows, len(test.outputs)) + + for i, output := range test.outputs { + require.Len(t, res.Rows[i], len(output)) + for j, val := range output { + require.Equal(t, val, res.Rows[i][j]) + } + } + }) + } +} diff --git a/internal/engine/integration/schema_test.go b/internal/engine/integration/schema_test.go index 330fa35e8..49eab1c2b 100644 --- a/internal/engine/integration/schema_test.go +++ b/internal/engine/integration/schema_test.go @@ -183,10 +183,6 @@ func Test_Schemas(t *testing.T) { require.NoError(t, err) defer tx.Rollback(ctx) - readonly, err := db.BeginReadTx(ctx) - require.NoError(t, err) - defer readonly.Rollback(ctx) - tc.fn(t, global, tx) }) } @@ -199,11 +195,15 @@ func loadSchema(file string) (*types.Schema, error) { return nil, err } - db, err := parse.ParseKuneiform(string(d)) + db, err := parse.ParseAndValidate(d) if err != nil { return nil, err } + if db.Err() != nil { + return nil, db.Err() + } + return db.Schema, nil } diff --git a/internal/engine/integration/schemas/social_media.kf b/internal/engine/integration/schemas/social_media.kf index 025d07396..ca05e440a 100644 --- a/internal/engine/integration/schemas/social_media.kf +++ b/internal/engine/integration/schemas/social_media.kf @@ -23,11 +23,12 @@ table posts { // its user_id. It returns the user id and the new post count. If the user has not // yet posted, it will set the post count to 1 procedure increment_post_count($user_id uuid) private returns (post_count int) { - FOR $row IN insert into post_counts (user_id, post_count) + insert into post_counts (user_id, post_count) values ($user_id, 1) on conflict (user_id) do update - set post_count = post_count + 1 - returning post_count { + set post_count = post_counts.post_count + 1; + + for $row IN select post_count from post_counts where user_id = $user_id limit 1 { return $row.post_count; } } @@ -70,7 +71,7 @@ procedure get_recent_posts_by_size($username text, $size int, $limit int) public } $count int := 0; - for $row in get_recent_posts($username) { + for $row in select * from get_recent_posts($username) as a { if $count == $limit { break; } @@ -90,22 +91,22 @@ foreign procedure get_user($address text) returns (uuid, text) // table keyvalue is a kv table to track metadata // for foreign calls. table keyvalue { - key text primary, + k text primary, // key is a reserved word value text not null } procedure admin_set($key text, $value text) public owner { - insert into keyvalue (key, value) + insert into keyvalue (k, value) values ($key, $value) - on conflict (key) do update set value = $value; + on conflict (k) do update set value = $value; } procedure admin_get($key text) public view returns (value text) { - for $row in select value from keyvalue where key = $key { + for $row in select value from keyvalue where k = $key { return $row.value; } - error(format('admin has not set a value for key %s', $key)); + error(format('admin has not set a value for k %s', $key)); } // gets the user's id diff --git a/internal/engine/integration/schemas/video_game.kf b/internal/engine/integration/schemas/video_game.kf index ff0d22453..8ef15738b 100644 --- a/internal/engine/integration/schemas/video_game.kf +++ b/internal/engine/integration/schemas/video_game.kf @@ -58,18 +58,18 @@ foreign procedure get_user($address text) returns (uuid, text) // table keyvalue is a kv table to track metadata // for foreign calls. table keyvalue { - key text primary, + k text primary, value text not null } procedure admin_set($key text, $value text) public owner { - insert into keyvalue (key, value) + insert into keyvalue (k, value) values ($key, $value) - on conflict (key) do update set value = $value; + on conflict (k) do update set value = $value; } procedure admin_get($key text) public view returns (value text) { - for $row in select value from keyvalue where key = $key { + for $row in select value from keyvalue where k = $key { return $row.value; } diff --git a/internal/sql/pg/db.go b/internal/sql/pg/db.go index 72fd8335e..f71c1c222 100644 --- a/internal/sql/pg/db.go +++ b/internal/sql/pg/db.go @@ -155,6 +155,10 @@ func NewDB(ctx context.Context, cfg *DBConfig) (*DB, error) { return nil, fmt.Errorf("failed to create UUID extension: %w", err) } + if err = ensureUint256Domain(ctx, pool.writer); err != nil { + return nil, fmt.Errorf("failed to create uint256 domain: %w", err) + } + okSchema := cfg.SchemaFilter if okSchema == nil { okSchema = defaultSchemaFilter diff --git a/internal/sql/pg/sql.go b/internal/sql/pg/sql.go index 283d427f2..7116c3eae 100644 --- a/internal/sql/pg/sql.go +++ b/internal/sql/pg/sql.go @@ -65,6 +65,16 @@ END$$;` );` sqlCreateUUIDExtension = `CREATE EXTENSION IF NOT EXISTS "uuid-ossp";` + + // have to run this in a DO block because you cannot do CREATE DOMAIN IF NOT EXISTS + sqlCreateUint256Domain = ` + DO $$ BEGIN + CREATE DOMAIN uint256 AS NUMERIC(78) NOT NULL + CHECK (VALUE >= 0 AND VALUE < 2^256) + CHECK (SCALE(VALUE) = 0); + EXCEPTION + WHEN duplicate_object THEN null; + END $$;` ) func checkSuperuser(ctx context.Context, conn *pgx.Conn) error { @@ -100,6 +110,11 @@ func ensureUUIDExtension(ctx context.Context, conn *pgx.Conn) error { return err } +func ensureUint256Domain(ctx context.Context, conn *pgx.Conn) error { + _, err := conn.Exec(ctx, sqlCreateUint256Domain) + return err +} + type preparedTxn struct { XID uint32 `db:"transaction"` // type xid is a 32-bit integer GID string `db:"gid"` diff --git a/parse/actions.go b/parse/actions.go new file mode 100644 index 000000000..d2f23b9aa --- /dev/null +++ b/parse/actions.go @@ -0,0 +1,65 @@ +package parse + +import "github.com/kwilteam/kwil-db/core/types" + +type actionAnalyzer struct { + sqlAnalyzer + // Mutative is true if the action mutates state. + Mutative bool + // schema is the database schema that contains the action. + schema *types.Schema + // inSQL is true if the visitor is in an SQL statement. + inSQL bool +} + +var _ Visitor = (*actionAnalyzer)(nil) + +func (a *actionAnalyzer) VisitActionStmtSQL(p0 *ActionStmtSQL) any { + // we simply need to call the sql analyzer to make it check the statement + // and rewrite it to be deterministic. We can ignore the result. + a.inSQL = true + p0.SQL.Accept(&a.sqlAnalyzer) + a.inSQL = false + + if a.sqlAnalyzer.sqlResult.Mutative { + a.Mutative = true + } + + return nil +} + +func (a *actionAnalyzer) VisitActionStmtExtensionCall(p0 *ActionStmtExtensionCall) any { + for _, arg := range p0.Args { + arg.Accept(&a.sqlAnalyzer) + } + + _, ok := a.schema.FindExtensionImport(p0.Extension) + if !ok { + a.errs.AddErr(p0, ErrActionNotFound, p0.Extension) + } + + // we need to add all receivers to the known variables + for _, rec := range p0.Receivers { + a.blockContext.variables[rec] = types.UnknownType + } + + return nil +} + +func (a *actionAnalyzer) VisitActionStmtActionCall(p0 *ActionStmtActionCall) any { + for _, arg := range p0.Args { + arg.Accept(&a.sqlAnalyzer) + } + + act, ok := a.schema.FindAction(p0.Action) + if !ok { + a.errs.AddErr(p0, ErrActionNotFound, p0.Action) + return nil + } + + if !act.IsView() { + a.Mutative = true + } + + return nil +} diff --git a/parse/actions/actions.go b/parse/actions/actions.go deleted file mode 100644 index 75c3f285c..000000000 --- a/parse/actions/actions.go +++ /dev/null @@ -1,288 +0,0 @@ -package actions - -import ( - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - actparser "github.com/kwilteam/kwil-db/parse/actions/parser" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/clean" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/parameters" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// AnalyzeOpts are options for analyzing actions. -type AnalyzeOpts struct { - // PGSchemaName is the name of the Postgres schema. - // If not set, it will default to the passed schema dbid. - PGSchemaName string - // SchemaInfo contains position information for the schema. - // If not nil, it will use the position information to modify the error messages. - SchemaInfo *parseTypes.SchemaInfo -} - -// AnalyzeActions analyzes the actions in a schema. -// It will perform validation checks on statements, such as ensuring that -// all view actions do not modify state. It will make all sql statements deterministic. -func AnalyzeActions(schema *types.Schema, opts *AnalyzeOpts) ([]*AnalyzedAction, parseTypes.ParseErrors, error) { - if opts == nil { - opts = &AnalyzeOpts{} - } - - if opts.PGSchemaName == "" { - opts.PGSchemaName = schema.DBID() - } - - parseErrs := parseTypes.ParseErrors{} - - analyzed := make([]*AnalyzedAction, len(schema.Actions)) - for i, action := range schema.Actions { - // if schema info is provided, we will use it to modify the error messages. - errorListener := parseTypes.NewErrorListener() - startingLine := 1 - startingCol := 1 - if opts.SchemaInfo != nil { - actionPos, ok := opts.SchemaInfo.Blocks[action.Name] - if !ok { - // should never happen, this would be a bug in our code - return nil, nil, fmt.Errorf("could not find position for action %s", action.Name) - } - - startingLine = actionPos.StartLine - startingCol = actionPos.StartCol - } - - errorListener = errorListener.Child("action", startingLine, startingCol) - stmts, err := actparser.Parse(action.Body, errorListener) - if err != nil { - return nil, nil, err - } - - analyzedStmts := make([]AnalyzedStatement, len(stmts)) - - for j, stmt := range stmts { - analyzedStmt, err := convertStatement(stmt, schema, opts.PGSchemaName, errorListener) - if err != nil { - return nil, nil, err - } - analyzedStmts[j] = analyzedStmt - } - - analyzed[i] = &AnalyzedAction{ - Name: strings.ToLower(action.Name), - Public: action.Public, - IsView: action.IsView(), - OwnerOnly: action.IsOwnerOnly(), - Parameters: action.Parameters, - Statements: analyzedStmts, - } - - parseErrs.Add(errorListener.Errors()...) - } - - return analyzed, parseErrs, nil -} - -// convertStatement converts a statement from the actparser AST to an AnalyzedStatement. -func convertStatement(stmt actparser.ActionStmt, schema *types.Schema, pgSchemaName string, errLis parseTypes.NativeErrorListener) (AnalyzedStatement, error) { - switch stmt := stmt.(type) { - case *actparser.ExtensionCallStmt: - recs := make([]string, len(stmt.Receivers)) - for i, rec := range stmt.Receivers { - recs[i] = strings.ToLower(rec) - } - - params, err := prepareInlineExpressions(stmt.Args, schema, errLis) - if err != nil { - return nil, err - } - - return &ExtensionCall{ - Extension: strings.ToLower(stmt.Extension), - Method: strings.ToLower(stmt.Method), - Params: params, - Receivers: recs, - }, nil - case *actparser.ActionCallStmt: - // receivers and targets must be empty for actions. - // I am not really sure why these were ever added, as they - // were never supported - if stmt.Database != "" { - return nil, fmt.Errorf("cannot call actions in other databases") - } - if len(stmt.Receivers) > 0 { - return nil, fmt.Errorf("actions cannot specify return values") - } - - params, err := prepareInlineExpressions(stmt.Args, schema, errLis) - if err != nil { - return nil, err - } - - return &ActionCall{ - Action: strings.ToLower(stmt.Method), - Params: params, - }, nil - case *actparser.DMLStmt: - child := errLis.Child("action-sql", stmt.Node.StartLine, stmt.Node.StartCol) - // make the statement deterministic. - generated, err := sqlanalyzer.ApplyRules(stmt.Statement, sqlanalyzer.AllRules, schema, pgSchemaName, child) - if err != nil { - return nil, err - } - if child.Err() != nil { - errLis.Add(child.Errors()...) - } - - return &SQLStatement{ - Statement: generated.Statement, - Mutative: generated.Mutative, - ParameterOrder: generated.ParameterOrder, - }, nil - } - - return nil, fmt.Errorf("unknown statement type: %T", stmt) -} - -// AnalyzedAction contains the results of analyzing an action. -type AnalyzedAction struct { - // Name is the name of the action. - Name string - // Public is true if the action is public. - Public bool - // IsView is true if the action is a view. - IsView bool - // OwnerOnly is true if the action is owner-only. - OwnerOnly bool - // Parameters is a list of parameters for the action. - Parameters []string - // Statements are the statements in the action. - Statements []AnalyzedStatement -} - -// AnalyzedStatement is an interface for analyzed statements. -type AnalyzedStatement interface { - analyzedStmt() -} - -// there are exactly three types of analyzed statements: -// - ExtensionCall: a statement that calls an extension -// - ActionCall: a statement that calls an action -// - SQLStatement: a statement that contains SQL - -// ExtensionCall is an analyzed statement that calls an action or extension. -type ExtensionCall struct { - // Extension is the name of the extension alias. - Extension string - // Method is the name of the method being called. - Method string - // Params are the parameters to the method. - Params []*InlineExpression - // Receivers are the receivers of the method. - Receivers []string -} - -func (c *ExtensionCall) analyzedStmt() {} - -// ActionCall is an analyzed statement that calls an action. -type ActionCall struct { - // Action is the name of the action being called. - Action string - // Params are the parameters to the action. - Params []*InlineExpression -} - -func (c *ActionCall) analyzedStmt() {} - -// SQLStatement is an analyzed statement that contains SQL. -type SQLStatement struct { - // Statement is the Statement statement that should be executed. - // It is deterministic. - Statement string - // Mutative is true if the statement mutates state. - Mutative bool - // ParameterOrder is a list of the parameters in the order they appear in the statement. - // This is set if the ReplaceNamedParameters flag is set. - // For example, if the statement is "SELECT * FROM table WHERE id = $id AND name = @caller", - // then the parameter order would be ["$id", "@caller"] - ParameterOrder []string -} - -func (s *SQLStatement) analyzedStmt() {} - -// prepareInlineExpressions prepares inline expressions for analysis. -// It takes the expressions from the syntax tree, as well as the procedures -// that exist in the schema, which is necessary for validating the expressions. -func prepareInlineExpressions(exprs []tree.Expression, schema *types.Schema, errLis parseTypes.NativeErrorListener) ([]*InlineExpression, error) { - prepared := make([]*InlineExpression, len(exprs)) - for i, expr := range exprs { - // this is copied over from an old place in the engine. - switch e := expr.(type) { - case *tree.ExpressionBindParameter: - // This could be a special one that returns an evaluatable that - // ignores the passed ResultSetFunc since the value is - case *tree.ExpressionTextLiteral, *tree.ExpressionNumericLiteral, *tree.ExpressionBooleanLiteral, - *tree.ExpressionNullLiteral, *tree.ExpressionBlobLiteral, *tree.ExpressionUnary, - *tree.ExpressionBinaryComparison, *tree.ExpressionFunction, *tree.ExpressionArithmetic: - // Acceptable expression type. - default: - return nil, fmt.Errorf("unsupported expression type: %T", e) - } - - // clean expression, since it is submitted by the user - err := expr.Walk(clean.NewStatementCleaner(schema, errLis)) - if err != nil { - return nil, err - } - - // The schema walker is not necessary for inline expressions, since - // we do not support table references in inline expressions. - walker := sqlanalyzer.NewWalkerRecoverer(expr) - paramVisitor := parameters.NewParametersWalker() - err = walker.Walk(paramVisitor) - if err != nil { - return nil, fmt.Errorf("error replacing parameters: %w", err) - } - - // SELECT expr; -- prepare new value in receivers for subsequent - // statements This query needs to be run in "simple" execution mode - // rather than "extended" execution mode, which asks the database for - // OID (placeholder types) that it can't know since there's no FOR table. - selectTree := &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: expr, - }, - }, - }, - }, - }, - } - - stmt, err := tree.SafeToSQL(selectTree) - if err != nil { - return nil, err - } - - prepared[i] = &InlineExpression{ - Statement: stmt, - OrderedParams: paramVisitor.OrderedParameters, - } - } - return prepared, nil -} - -// InlineExpression is an expression that is inlined in an action or procedure call. -// For example, this can be "extension.call($id+1)" -type InlineExpression struct { - // Statement is the sql statement that is inlined. - Statement string - // OrderedParams is the order of the parameters in the statement. - OrderedParams []string -} diff --git a/parse/actions/gen/action_lexer.go b/parse/actions/gen/action_lexer.go deleted file mode 100644 index 010f7c43b..000000000 --- a/parse/actions/gen/action_lexer.go +++ /dev/null @@ -1,272 +0,0 @@ -// Code generated from ActionLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package actgrammar - -import ( - "fmt" - "github.com/antlr4-go/antlr/v4" - "sync" - "unicode" -) - -// Suppress unused import error -var _ = fmt.Printf -var _ = sync.Once{} -var _ = unicode.IsLetter - -type ActionLexer struct { - *antlr.BaseLexer - channelNames []string - modeNames []string - // TODO: EOF string -} - -var ActionLexerLexerStaticData struct { - once sync.Once - serializedATN []int32 - ChannelNames []string - ModeNames []string - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func actionlexerLexerInit() { - staticData := &ActionLexerLexerStaticData - staticData.ChannelNames = []string{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN", - } - staticData.ModeNames = []string{ - "DEFAULT_MODE", - } - staticData.LiteralNames = []string{ - "", "';'", "'('", "')'", "','", "'$'", "'@'", "'='", "'.'", "'+'", "'-'", - "'*'", "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'<>'", "", - "", "", "", "", "'not'", "'and'", "'or'", - } - staticData.SymbolicNames = []string{ - "", "SCOL", "L_PAREN", "R_PAREN", "COMMA", "DOLLAR", "AT", "ASSIGN", - "PERIOD", "PLUS", "MINUS", "STAR", "DIV", "MOD", "LT", "LT_EQ", "GT", - "GT_EQ", "SQL_NOT_EQ1", "SQL_NOT_EQ2", "SELECT_", "INSERT_", "UPDATE_", - "DELETE_", "WITH_", "NOT_", "AND_", "OR_", "SQL_KEYWORDS", "SQL_STMT", - "IDENTIFIER", "VARIABLE", "BLOCK_VARIABLE", "UNSIGNED_NUMBER_LITERAL", - "STRING_LITERAL", "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", - } - staticData.RuleNames = []string{ - "SCOL", "L_PAREN", "R_PAREN", "COMMA", "DOLLAR", "AT", "ASSIGN", "PERIOD", - "PLUS", "MINUS", "STAR", "DIV", "MOD", "LT", "LT_EQ", "GT", "GT_EQ", - "SQL_NOT_EQ1", "SQL_NOT_EQ2", "SELECT_", "INSERT_", "UPDATE_", "DELETE_", - "WITH_", "NOT_", "AND_", "OR_", "SQL_KEYWORDS", "SQL_STMT", "IDENTIFIER", - "VARIABLE", "BLOCK_VARIABLE", "UNSIGNED_NUMBER_LITERAL", "STRING_LITERAL", - "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", "WSNL", "DIGIT", - "DOUBLE_QUOTE_STRING_CHAR", "SINGLE_QUOTE_STRING_CHAR", "SINGLE_QUOTE_STRING", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 0, 38, 272, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, - 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, - 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, - 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, - 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, - 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, - 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, - 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, - 41, 2, 42, 7, 42, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, - 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, - 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, - 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, - 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, - 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, - 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, - 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, - 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 179, 8, 27, 1, - 28, 1, 28, 1, 28, 4, 28, 184, 8, 28, 11, 28, 12, 28, 185, 1, 29, 1, 29, - 5, 29, 190, 8, 29, 10, 29, 12, 29, 193, 9, 29, 1, 30, 1, 30, 1, 30, 1, - 31, 1, 31, 1, 31, 1, 32, 4, 32, 202, 8, 32, 11, 32, 12, 32, 203, 1, 33, - 1, 33, 1, 34, 4, 34, 209, 8, 34, 11, 34, 12, 34, 210, 1, 34, 1, 34, 1, - 35, 4, 35, 216, 8, 35, 11, 35, 12, 35, 217, 1, 35, 1, 35, 1, 36, 1, 36, - 1, 36, 1, 36, 5, 36, 226, 8, 36, 10, 36, 12, 36, 229, 9, 36, 1, 36, 1, - 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 240, 8, 37, - 10, 37, 12, 37, 243, 9, 37, 1, 37, 1, 37, 1, 38, 4, 38, 248, 8, 38, 11, - 38, 12, 38, 249, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 3, 40, 257, 8, 40, - 1, 41, 1, 41, 1, 41, 3, 41, 262, 8, 41, 1, 42, 1, 42, 5, 42, 266, 8, 42, - 10, 42, 12, 42, 269, 9, 42, 1, 42, 1, 42, 1, 227, 0, 43, 1, 1, 3, 2, 5, - 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, - 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, - 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, - 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 0, 79, - 0, 81, 0, 83, 0, 85, 0, 1, 0, 23, 2, 0, 83, 83, 115, 115, 2, 0, 69, 69, - 101, 101, 2, 0, 76, 76, 108, 108, 2, 0, 67, 67, 99, 99, 2, 0, 84, 84, 116, - 116, 2, 0, 73, 73, 105, 105, 2, 0, 78, 78, 110, 110, 2, 0, 82, 82, 114, - 114, 2, 0, 85, 85, 117, 117, 2, 0, 80, 80, 112, 112, 2, 0, 68, 68, 100, - 100, 2, 0, 65, 65, 97, 97, 2, 0, 87, 87, 119, 119, 2, 0, 72, 72, 104, 104, - 2, 0, 59, 59, 125, 125, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, - 95, 97, 122, 2, 0, 9, 9, 32, 32, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, - 13, 32, 32, 1, 0, 48, 57, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, - 10, 13, 13, 39, 39, 92, 92, 281, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, - 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, - 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, - 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, - 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, - 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, - 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, - 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, - 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, - 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, - 0, 0, 75, 1, 0, 0, 0, 1, 87, 1, 0, 0, 0, 3, 89, 1, 0, 0, 0, 5, 91, 1, 0, - 0, 0, 7, 93, 1, 0, 0, 0, 9, 95, 1, 0, 0, 0, 11, 97, 1, 0, 0, 0, 13, 99, - 1, 0, 0, 0, 15, 101, 1, 0, 0, 0, 17, 103, 1, 0, 0, 0, 19, 105, 1, 0, 0, - 0, 21, 107, 1, 0, 0, 0, 23, 109, 1, 0, 0, 0, 25, 111, 1, 0, 0, 0, 27, 113, - 1, 0, 0, 0, 29, 115, 1, 0, 0, 0, 31, 118, 1, 0, 0, 0, 33, 120, 1, 0, 0, - 0, 35, 123, 1, 0, 0, 0, 37, 126, 1, 0, 0, 0, 39, 129, 1, 0, 0, 0, 41, 136, - 1, 0, 0, 0, 43, 143, 1, 0, 0, 0, 45, 150, 1, 0, 0, 0, 47, 157, 1, 0, 0, - 0, 49, 162, 1, 0, 0, 0, 51, 166, 1, 0, 0, 0, 53, 170, 1, 0, 0, 0, 55, 178, - 1, 0, 0, 0, 57, 180, 1, 0, 0, 0, 59, 187, 1, 0, 0, 0, 61, 194, 1, 0, 0, - 0, 63, 197, 1, 0, 0, 0, 65, 201, 1, 0, 0, 0, 67, 205, 1, 0, 0, 0, 69, 208, - 1, 0, 0, 0, 71, 215, 1, 0, 0, 0, 73, 221, 1, 0, 0, 0, 75, 235, 1, 0, 0, - 0, 77, 247, 1, 0, 0, 0, 79, 251, 1, 0, 0, 0, 81, 256, 1, 0, 0, 0, 83, 261, - 1, 0, 0, 0, 85, 263, 1, 0, 0, 0, 87, 88, 5, 59, 0, 0, 88, 2, 1, 0, 0, 0, - 89, 90, 5, 40, 0, 0, 90, 4, 1, 0, 0, 0, 91, 92, 5, 41, 0, 0, 92, 6, 1, - 0, 0, 0, 93, 94, 5, 44, 0, 0, 94, 8, 1, 0, 0, 0, 95, 96, 5, 36, 0, 0, 96, - 10, 1, 0, 0, 0, 97, 98, 5, 64, 0, 0, 98, 12, 1, 0, 0, 0, 99, 100, 5, 61, - 0, 0, 100, 14, 1, 0, 0, 0, 101, 102, 5, 46, 0, 0, 102, 16, 1, 0, 0, 0, - 103, 104, 5, 43, 0, 0, 104, 18, 1, 0, 0, 0, 105, 106, 5, 45, 0, 0, 106, - 20, 1, 0, 0, 0, 107, 108, 5, 42, 0, 0, 108, 22, 1, 0, 0, 0, 109, 110, 5, - 47, 0, 0, 110, 24, 1, 0, 0, 0, 111, 112, 5, 37, 0, 0, 112, 26, 1, 0, 0, - 0, 113, 114, 5, 60, 0, 0, 114, 28, 1, 0, 0, 0, 115, 116, 5, 60, 0, 0, 116, - 117, 5, 61, 0, 0, 117, 30, 1, 0, 0, 0, 118, 119, 5, 62, 0, 0, 119, 32, - 1, 0, 0, 0, 120, 121, 5, 62, 0, 0, 121, 122, 5, 61, 0, 0, 122, 34, 1, 0, - 0, 0, 123, 124, 5, 33, 0, 0, 124, 125, 5, 61, 0, 0, 125, 36, 1, 0, 0, 0, - 126, 127, 5, 60, 0, 0, 127, 128, 5, 62, 0, 0, 128, 38, 1, 0, 0, 0, 129, - 130, 7, 0, 0, 0, 130, 131, 7, 1, 0, 0, 131, 132, 7, 2, 0, 0, 132, 133, - 7, 1, 0, 0, 133, 134, 7, 3, 0, 0, 134, 135, 7, 4, 0, 0, 135, 40, 1, 0, - 0, 0, 136, 137, 7, 5, 0, 0, 137, 138, 7, 6, 0, 0, 138, 139, 7, 0, 0, 0, - 139, 140, 7, 1, 0, 0, 140, 141, 7, 7, 0, 0, 141, 142, 7, 4, 0, 0, 142, - 42, 1, 0, 0, 0, 143, 144, 7, 8, 0, 0, 144, 145, 7, 9, 0, 0, 145, 146, 7, - 10, 0, 0, 146, 147, 7, 11, 0, 0, 147, 148, 7, 4, 0, 0, 148, 149, 7, 1, - 0, 0, 149, 44, 1, 0, 0, 0, 150, 151, 7, 10, 0, 0, 151, 152, 7, 1, 0, 0, - 152, 153, 7, 2, 0, 0, 153, 154, 7, 1, 0, 0, 154, 155, 7, 4, 0, 0, 155, - 156, 7, 1, 0, 0, 156, 46, 1, 0, 0, 0, 157, 158, 7, 12, 0, 0, 158, 159, - 7, 5, 0, 0, 159, 160, 7, 4, 0, 0, 160, 161, 7, 13, 0, 0, 161, 48, 1, 0, - 0, 0, 162, 163, 5, 110, 0, 0, 163, 164, 5, 111, 0, 0, 164, 165, 5, 116, - 0, 0, 165, 50, 1, 0, 0, 0, 166, 167, 5, 97, 0, 0, 167, 168, 5, 110, 0, - 0, 168, 169, 5, 100, 0, 0, 169, 52, 1, 0, 0, 0, 170, 171, 5, 111, 0, 0, - 171, 172, 5, 114, 0, 0, 172, 54, 1, 0, 0, 0, 173, 179, 3, 39, 19, 0, 174, - 179, 3, 41, 20, 0, 175, 179, 3, 43, 21, 0, 176, 179, 3, 45, 22, 0, 177, - 179, 3, 47, 23, 0, 178, 173, 1, 0, 0, 0, 178, 174, 1, 0, 0, 0, 178, 175, - 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 178, 177, 1, 0, 0, 0, 179, 56, 1, 0, - 0, 0, 180, 181, 3, 55, 27, 0, 181, 183, 3, 77, 38, 0, 182, 184, 8, 14, - 0, 0, 183, 182, 1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 183, 1, 0, 0, 0, - 185, 186, 1, 0, 0, 0, 186, 58, 1, 0, 0, 0, 187, 191, 7, 15, 0, 0, 188, - 190, 7, 16, 0, 0, 189, 188, 1, 0, 0, 0, 190, 193, 1, 0, 0, 0, 191, 189, - 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 60, 1, 0, 0, 0, 193, 191, 1, 0, - 0, 0, 194, 195, 3, 9, 4, 0, 195, 196, 3, 59, 29, 0, 196, 62, 1, 0, 0, 0, - 197, 198, 3, 11, 5, 0, 198, 199, 3, 59, 29, 0, 199, 64, 1, 0, 0, 0, 200, - 202, 3, 79, 39, 0, 201, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 201, - 1, 0, 0, 0, 203, 204, 1, 0, 0, 0, 204, 66, 1, 0, 0, 0, 205, 206, 3, 85, - 42, 0, 206, 68, 1, 0, 0, 0, 207, 209, 7, 17, 0, 0, 208, 207, 1, 0, 0, 0, - 209, 210, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, - 212, 1, 0, 0, 0, 212, 213, 6, 34, 0, 0, 213, 70, 1, 0, 0, 0, 214, 216, - 7, 18, 0, 0, 215, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 215, 1, 0, - 0, 0, 217, 218, 1, 0, 0, 0, 218, 219, 1, 0, 0, 0, 219, 220, 6, 35, 0, 0, - 220, 72, 1, 0, 0, 0, 221, 222, 5, 47, 0, 0, 222, 223, 5, 42, 0, 0, 223, - 227, 1, 0, 0, 0, 224, 226, 9, 0, 0, 0, 225, 224, 1, 0, 0, 0, 226, 229, - 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 227, 225, 1, 0, 0, 0, 228, 230, 1, 0, - 0, 0, 229, 227, 1, 0, 0, 0, 230, 231, 5, 42, 0, 0, 231, 232, 5, 47, 0, - 0, 232, 233, 1, 0, 0, 0, 233, 234, 6, 36, 0, 0, 234, 74, 1, 0, 0, 0, 235, - 236, 5, 47, 0, 0, 236, 237, 5, 47, 0, 0, 237, 241, 1, 0, 0, 0, 238, 240, - 8, 18, 0, 0, 239, 238, 1, 0, 0, 0, 240, 243, 1, 0, 0, 0, 241, 239, 1, 0, - 0, 0, 241, 242, 1, 0, 0, 0, 242, 244, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, - 244, 245, 6, 37, 0, 0, 245, 76, 1, 0, 0, 0, 246, 248, 7, 19, 0, 0, 247, - 246, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 250, - 1, 0, 0, 0, 250, 78, 1, 0, 0, 0, 251, 252, 7, 20, 0, 0, 252, 80, 1, 0, - 0, 0, 253, 257, 8, 21, 0, 0, 254, 255, 5, 92, 0, 0, 255, 257, 9, 0, 0, - 0, 256, 253, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 82, 1, 0, 0, 0, 258, - 262, 8, 22, 0, 0, 259, 260, 5, 92, 0, 0, 260, 262, 9, 0, 0, 0, 261, 258, - 1, 0, 0, 0, 261, 259, 1, 0, 0, 0, 262, 84, 1, 0, 0, 0, 263, 267, 5, 39, - 0, 0, 264, 266, 3, 83, 41, 0, 265, 264, 1, 0, 0, 0, 266, 269, 1, 0, 0, - 0, 267, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 270, 1, 0, 0, 0, 269, - 267, 1, 0, 0, 0, 270, 271, 5, 39, 0, 0, 271, 86, 1, 0, 0, 0, 13, 0, 178, - 185, 191, 203, 210, 217, 227, 241, 249, 256, 261, 267, 1, 0, 1, 0, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// ActionLexerInit initializes any static state used to implement ActionLexer. By default the -// static state used to implement the lexer is lazily initialized during the first call to -// NewActionLexer(). You can call this function if you wish to initialize the static state ahead -// of time. -func ActionLexerInit() { - staticData := &ActionLexerLexerStaticData - staticData.once.Do(actionlexerLexerInit) -} - -// NewActionLexer produces a new lexer instance for the optional input antlr.CharStream. -func NewActionLexer(input antlr.CharStream) *ActionLexer { - ActionLexerInit() - l := new(ActionLexer) - l.BaseLexer = antlr.NewBaseLexer(input) - staticData := &ActionLexerLexerStaticData - l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - l.channelNames = staticData.ChannelNames - l.modeNames = staticData.ModeNames - l.RuleNames = staticData.RuleNames - l.LiteralNames = staticData.LiteralNames - l.SymbolicNames = staticData.SymbolicNames - l.GrammarFileName = "ActionLexer.g4" - // TODO: l.EOF = antlr.TokenEOF - - return l -} - -// ActionLexer tokens. -const ( - ActionLexerSCOL = 1 - ActionLexerL_PAREN = 2 - ActionLexerR_PAREN = 3 - ActionLexerCOMMA = 4 - ActionLexerDOLLAR = 5 - ActionLexerAT = 6 - ActionLexerASSIGN = 7 - ActionLexerPERIOD = 8 - ActionLexerPLUS = 9 - ActionLexerMINUS = 10 - ActionLexerSTAR = 11 - ActionLexerDIV = 12 - ActionLexerMOD = 13 - ActionLexerLT = 14 - ActionLexerLT_EQ = 15 - ActionLexerGT = 16 - ActionLexerGT_EQ = 17 - ActionLexerSQL_NOT_EQ1 = 18 - ActionLexerSQL_NOT_EQ2 = 19 - ActionLexerSELECT_ = 20 - ActionLexerINSERT_ = 21 - ActionLexerUPDATE_ = 22 - ActionLexerDELETE_ = 23 - ActionLexerWITH_ = 24 - ActionLexerNOT_ = 25 - ActionLexerAND_ = 26 - ActionLexerOR_ = 27 - ActionLexerSQL_KEYWORDS = 28 - ActionLexerSQL_STMT = 29 - ActionLexerIDENTIFIER = 30 - ActionLexerVARIABLE = 31 - ActionLexerBLOCK_VARIABLE = 32 - ActionLexerUNSIGNED_NUMBER_LITERAL = 33 - ActionLexerSTRING_LITERAL = 34 - ActionLexerWS = 35 - ActionLexerTERMINATOR = 36 - ActionLexerBLOCK_COMMENT = 37 - ActionLexerLINE_COMMENT = 38 -) diff --git a/parse/actions/gen/action_parser.go b/parse/actions/gen/action_parser.go deleted file mode 100644 index 41a1541f6..000000000 --- a/parse/actions/gen/action_parser.go +++ /dev/null @@ -1,2721 +0,0 @@ -// Code generated from ActionParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package actgrammar // ActionParser -import ( - "fmt" - "strconv" - "sync" - - "github.com/antlr4-go/antlr/v4" -) - -// Suppress unused import errors -var _ = fmt.Printf -var _ = strconv.Itoa -var _ = sync.Once{} - -type ActionParser struct { - *antlr.BaseParser -} - -var ActionParserParserStaticData struct { - once sync.Once - serializedATN []int32 - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func actionparserParserInit() { - staticData := &ActionParserParserStaticData - staticData.LiteralNames = []string{ - "", "';'", "'('", "')'", "','", "'$'", "'@'", "'='", "'.'", "'+'", "'-'", - "'*'", "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'<>'", "", - "", "", "", "", "'not'", "'and'", "'or'", - } - staticData.SymbolicNames = []string{ - "", "SCOL", "L_PAREN", "R_PAREN", "COMMA", "DOLLAR", "AT", "ASSIGN", - "PERIOD", "PLUS", "MINUS", "STAR", "DIV", "MOD", "LT", "LT_EQ", "GT", - "GT_EQ", "SQL_NOT_EQ1", "SQL_NOT_EQ2", "SELECT_", "INSERT_", "UPDATE_", - "DELETE_", "WITH_", "NOT_", "AND_", "OR_", "SQL_KEYWORDS", "SQL_STMT", - "IDENTIFIER", "VARIABLE", "BLOCK_VARIABLE", "UNSIGNED_NUMBER_LITERAL", - "STRING_LITERAL", "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", - } - staticData.RuleNames = []string{ - "statement", "literal_value", "action_name", "stmt", "sql_stmt", "call_stmt", - "call_receivers", "call_body", "variable", "block_var", "extension_call_name", - "fn_name", "sfn_name", "fn_arg_list", "fn_arg_expr", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 1, 38, 146, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, - 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 1, 0, 4, 0, - 32, 8, 0, 11, 0, 12, 0, 33, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, - 3, 3, 3, 44, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 3, 5, 52, 8, 5, - 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 5, 6, 60, 8, 6, 10, 6, 12, 6, 63, 9, - 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, - 1, 10, 1, 10, 1, 11, 1, 11, 3, 11, 80, 8, 11, 1, 12, 1, 12, 1, 13, 3, 13, - 85, 8, 13, 1, 13, 1, 13, 5, 13, 89, 8, 13, 10, 13, 12, 13, 92, 9, 13, 1, - 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 103, - 8, 14, 10, 14, 12, 14, 106, 9, 14, 1, 14, 3, 14, 109, 8, 14, 1, 14, 1, - 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 121, - 8, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, - 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 141, - 8, 14, 10, 14, 12, 14, 144, 9, 14, 1, 14, 0, 1, 28, 15, 0, 2, 4, 6, 8, - 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 0, 5, 1, 0, 33, 34, 1, 0, 9, 10, - 1, 0, 11, 13, 1, 0, 14, 17, 2, 0, 7, 7, 18, 19, 152, 0, 31, 1, 0, 0, 0, - 2, 37, 1, 0, 0, 0, 4, 39, 1, 0, 0, 0, 6, 43, 1, 0, 0, 0, 8, 45, 1, 0, 0, - 0, 10, 51, 1, 0, 0, 0, 12, 56, 1, 0, 0, 0, 14, 64, 1, 0, 0, 0, 16, 69, - 1, 0, 0, 0, 18, 71, 1, 0, 0, 0, 20, 73, 1, 0, 0, 0, 22, 79, 1, 0, 0, 0, - 24, 81, 1, 0, 0, 0, 26, 84, 1, 0, 0, 0, 28, 120, 1, 0, 0, 0, 30, 32, 3, - 6, 3, 0, 31, 30, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 31, 1, 0, 0, 0, 33, - 34, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 36, 5, 0, 0, 1, 36, 1, 1, 0, 0, - 0, 37, 38, 7, 0, 0, 0, 38, 3, 1, 0, 0, 0, 39, 40, 5, 30, 0, 0, 40, 5, 1, - 0, 0, 0, 41, 44, 3, 8, 4, 0, 42, 44, 3, 10, 5, 0, 43, 41, 1, 0, 0, 0, 43, - 42, 1, 0, 0, 0, 44, 7, 1, 0, 0, 0, 45, 46, 5, 29, 0, 0, 46, 47, 5, 1, 0, - 0, 47, 9, 1, 0, 0, 0, 48, 49, 3, 12, 6, 0, 49, 50, 5, 7, 0, 0, 50, 52, - 1, 0, 0, 0, 51, 48, 1, 0, 0, 0, 51, 52, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, - 53, 54, 3, 14, 7, 0, 54, 55, 5, 1, 0, 0, 55, 11, 1, 0, 0, 0, 56, 61, 3, - 16, 8, 0, 57, 58, 5, 4, 0, 0, 58, 60, 3, 16, 8, 0, 59, 57, 1, 0, 0, 0, - 60, 63, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 13, 1, - 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, 65, 3, 22, 11, 0, 65, 66, 5, 2, 0, 0, - 66, 67, 3, 26, 13, 0, 67, 68, 5, 3, 0, 0, 68, 15, 1, 0, 0, 0, 69, 70, 5, - 31, 0, 0, 70, 17, 1, 0, 0, 0, 71, 72, 5, 32, 0, 0, 72, 19, 1, 0, 0, 0, - 73, 74, 5, 30, 0, 0, 74, 75, 5, 8, 0, 0, 75, 76, 5, 30, 0, 0, 76, 21, 1, - 0, 0, 0, 77, 80, 3, 20, 10, 0, 78, 80, 3, 4, 2, 0, 79, 77, 1, 0, 0, 0, - 79, 78, 1, 0, 0, 0, 80, 23, 1, 0, 0, 0, 81, 82, 5, 30, 0, 0, 82, 25, 1, - 0, 0, 0, 83, 85, 3, 28, 14, 0, 84, 83, 1, 0, 0, 0, 84, 85, 1, 0, 0, 0, - 85, 90, 1, 0, 0, 0, 86, 87, 5, 4, 0, 0, 87, 89, 3, 28, 14, 0, 88, 86, 1, - 0, 0, 0, 89, 92, 1, 0, 0, 0, 90, 88, 1, 0, 0, 0, 90, 91, 1, 0, 0, 0, 91, - 27, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 93, 94, 6, 14, -1, 0, 94, 121, 3, 2, - 1, 0, 95, 121, 3, 16, 8, 0, 96, 121, 3, 18, 9, 0, 97, 98, 3, 24, 12, 0, - 98, 108, 5, 2, 0, 0, 99, 104, 3, 28, 14, 0, 100, 101, 5, 4, 0, 0, 101, - 103, 3, 28, 14, 0, 102, 100, 1, 0, 0, 0, 103, 106, 1, 0, 0, 0, 104, 102, - 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 109, 1, 0, 0, 0, 106, 104, 1, 0, - 0, 0, 107, 109, 5, 11, 0, 0, 108, 99, 1, 0, 0, 0, 108, 107, 1, 0, 0, 0, - 108, 109, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 111, 5, 3, 0, 0, 111, - 121, 1, 0, 0, 0, 112, 113, 5, 2, 0, 0, 113, 114, 3, 28, 14, 0, 114, 115, - 5, 3, 0, 0, 115, 121, 1, 0, 0, 0, 116, 117, 7, 1, 0, 0, 117, 121, 3, 28, - 14, 8, 118, 119, 5, 25, 0, 0, 119, 121, 3, 28, 14, 3, 120, 93, 1, 0, 0, - 0, 120, 95, 1, 0, 0, 0, 120, 96, 1, 0, 0, 0, 120, 97, 1, 0, 0, 0, 120, - 112, 1, 0, 0, 0, 120, 116, 1, 0, 0, 0, 120, 118, 1, 0, 0, 0, 121, 142, - 1, 0, 0, 0, 122, 123, 10, 7, 0, 0, 123, 124, 7, 2, 0, 0, 124, 141, 3, 28, - 14, 8, 125, 126, 10, 6, 0, 0, 126, 127, 7, 1, 0, 0, 127, 141, 3, 28, 14, - 7, 128, 129, 10, 5, 0, 0, 129, 130, 7, 3, 0, 0, 130, 141, 3, 28, 14, 6, - 131, 132, 10, 4, 0, 0, 132, 133, 7, 4, 0, 0, 133, 141, 3, 28, 14, 5, 134, - 135, 10, 2, 0, 0, 135, 136, 5, 26, 0, 0, 136, 141, 3, 28, 14, 3, 137, 138, - 10, 1, 0, 0, 138, 139, 5, 27, 0, 0, 139, 141, 3, 28, 14, 2, 140, 122, 1, - 0, 0, 0, 140, 125, 1, 0, 0, 0, 140, 128, 1, 0, 0, 0, 140, 131, 1, 0, 0, - 0, 140, 134, 1, 0, 0, 0, 140, 137, 1, 0, 0, 0, 141, 144, 1, 0, 0, 0, 142, - 140, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 29, 1, 0, 0, 0, 144, 142, 1, - 0, 0, 0, 12, 33, 43, 51, 61, 79, 84, 90, 104, 108, 120, 140, 142, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// ActionParserInit initializes any static state used to implement ActionParser. By default the -// static state used to implement the parser is lazily initialized during the first call to -// NewActionParser(). You can call this function if you wish to initialize the static state ahead -// of time. -func ActionParserInit() { - staticData := &ActionParserParserStaticData - staticData.once.Do(actionparserParserInit) -} - -// NewActionParser produces a new parser instance for the optional input antlr.TokenStream. -func NewActionParser(input antlr.TokenStream) *ActionParser { - ActionParserInit() - this := new(ActionParser) - this.BaseParser = antlr.NewBaseParser(input) - staticData := &ActionParserParserStaticData - this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - this.RuleNames = staticData.RuleNames - this.LiteralNames = staticData.LiteralNames - this.SymbolicNames = staticData.SymbolicNames - this.GrammarFileName = "ActionParser.g4" - - return this -} - -// ActionParser tokens. -const ( - ActionParserEOF = antlr.TokenEOF - ActionParserSCOL = 1 - ActionParserL_PAREN = 2 - ActionParserR_PAREN = 3 - ActionParserCOMMA = 4 - ActionParserDOLLAR = 5 - ActionParserAT = 6 - ActionParserASSIGN = 7 - ActionParserPERIOD = 8 - ActionParserPLUS = 9 - ActionParserMINUS = 10 - ActionParserSTAR = 11 - ActionParserDIV = 12 - ActionParserMOD = 13 - ActionParserLT = 14 - ActionParserLT_EQ = 15 - ActionParserGT = 16 - ActionParserGT_EQ = 17 - ActionParserSQL_NOT_EQ1 = 18 - ActionParserSQL_NOT_EQ2 = 19 - ActionParserSELECT_ = 20 - ActionParserINSERT_ = 21 - ActionParserUPDATE_ = 22 - ActionParserDELETE_ = 23 - ActionParserWITH_ = 24 - ActionParserNOT_ = 25 - ActionParserAND_ = 26 - ActionParserOR_ = 27 - ActionParserSQL_KEYWORDS = 28 - ActionParserSQL_STMT = 29 - ActionParserIDENTIFIER = 30 - ActionParserVARIABLE = 31 - ActionParserBLOCK_VARIABLE = 32 - ActionParserUNSIGNED_NUMBER_LITERAL = 33 - ActionParserSTRING_LITERAL = 34 - ActionParserWS = 35 - ActionParserTERMINATOR = 36 - ActionParserBLOCK_COMMENT = 37 - ActionParserLINE_COMMENT = 38 -) - -// ActionParser rules. -const ( - ActionParserRULE_statement = 0 - ActionParserRULE_literal_value = 1 - ActionParserRULE_action_name = 2 - ActionParserRULE_stmt = 3 - ActionParserRULE_sql_stmt = 4 - ActionParserRULE_call_stmt = 5 - ActionParserRULE_call_receivers = 6 - ActionParserRULE_call_body = 7 - ActionParserRULE_variable = 8 - ActionParserRULE_block_var = 9 - ActionParserRULE_extension_call_name = 10 - ActionParserRULE_fn_name = 11 - ActionParserRULE_sfn_name = 12 - ActionParserRULE_fn_arg_list = 13 - ActionParserRULE_fn_arg_expr = 14 -) - -// IStatementContext is an interface to support dynamic dispatch. -type IStatementContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - EOF() antlr.TerminalNode - AllStmt() []IStmtContext - Stmt(i int) IStmtContext - - // IsStatementContext differentiates from other interfaces. - IsStatementContext() -} - -type StatementContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStatementContext() *StatementContext { - var p = new(StatementContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_statement - return p -} - -func InitEmptyStatementContext(p *StatementContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_statement -} - -func (*StatementContext) IsStatementContext() {} - -func NewStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StatementContext { - var p = new(StatementContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_statement - - return p -} - -func (s *StatementContext) GetParser() antlr.Parser { return s.parser } - -func (s *StatementContext) EOF() antlr.TerminalNode { - return s.GetToken(ActionParserEOF, 0) -} - -func (s *StatementContext) AllStmt() []IStmtContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStmtContext); ok { - len++ - } - } - - tst := make([]IStmtContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStmtContext); ok { - tst[i] = t.(IStmtContext) - i++ - } - } - - return tst -} - -func (s *StatementContext) Stmt(i int) IStmtContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmtContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStmtContext) -} - -func (s *StatementContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *StatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *StatementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitStatement(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Statement() (localctx IStatementContext) { - localctx = NewStatementContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 0, ActionParserRULE_statement) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(31) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ok := true; ok; ok = ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&3758096384) != 0) { - { - p.SetState(30) - p.Stmt() - } - - p.SetState(33) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(35) - p.Match(ActionParserEOF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ILiteral_valueContext is an interface to support dynamic dispatch. -type ILiteral_valueContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - STRING_LITERAL() antlr.TerminalNode - UNSIGNED_NUMBER_LITERAL() antlr.TerminalNode - - // IsLiteral_valueContext differentiates from other interfaces. - IsLiteral_valueContext() -} - -type Literal_valueContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyLiteral_valueContext() *Literal_valueContext { - var p = new(Literal_valueContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_literal_value - return p -} - -func InitEmptyLiteral_valueContext(p *Literal_valueContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_literal_value -} - -func (*Literal_valueContext) IsLiteral_valueContext() {} - -func NewLiteral_valueContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Literal_valueContext { - var p = new(Literal_valueContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_literal_value - - return p -} - -func (s *Literal_valueContext) GetParser() antlr.Parser { return s.parser } - -func (s *Literal_valueContext) STRING_LITERAL() antlr.TerminalNode { - return s.GetToken(ActionParserSTRING_LITERAL, 0) -} - -func (s *Literal_valueContext) UNSIGNED_NUMBER_LITERAL() antlr.TerminalNode { - return s.GetToken(ActionParserUNSIGNED_NUMBER_LITERAL, 0) -} - -func (s *Literal_valueContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Literal_valueContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Literal_valueContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitLiteral_value(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Literal_value() (localctx ILiteral_valueContext) { - localctx = NewLiteral_valueContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 2, ActionParserRULE_literal_value) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(37) - _la = p.GetTokenStream().LA(1) - - if !(_la == ActionParserUNSIGNED_NUMBER_LITERAL || _la == ActionParserSTRING_LITERAL) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IAction_nameContext is an interface to support dynamic dispatch. -type IAction_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsAction_nameContext differentiates from other interfaces. - IsAction_nameContext() -} - -type Action_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyAction_nameContext() *Action_nameContext { - var p = new(Action_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_action_name - return p -} - -func InitEmptyAction_nameContext(p *Action_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_action_name -} - -func (*Action_nameContext) IsAction_nameContext() {} - -func NewAction_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Action_nameContext { - var p = new(Action_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_action_name - - return p -} - -func (s *Action_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Action_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ActionParserIDENTIFIER, 0) -} - -func (s *Action_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Action_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Action_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitAction_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Action_name() (localctx IAction_nameContext) { - localctx = NewAction_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 4, ActionParserRULE_action_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(39) - p.Match(ActionParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStmtContext is an interface to support dynamic dispatch. -type IStmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Sql_stmt() ISql_stmtContext - Call_stmt() ICall_stmtContext - - // IsStmtContext differentiates from other interfaces. - IsStmtContext() -} - -type StmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStmtContext() *StmtContext { - var p = new(StmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_stmt - return p -} - -func InitEmptyStmtContext(p *StmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_stmt -} - -func (*StmtContext) IsStmtContext() {} - -func NewStmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StmtContext { - var p = new(StmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_stmt - - return p -} - -func (s *StmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *StmtContext) Sql_stmt() ISql_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISql_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISql_stmtContext) -} - -func (s *StmtContext) Call_stmt() ICall_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_stmtContext) -} - -func (s *StmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *StmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *StmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitStmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Stmt() (localctx IStmtContext) { - localctx = NewStmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 6, ActionParserRULE_stmt) - p.SetState(43) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case ActionParserSQL_STMT: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(41) - p.Sql_stmt() - } - - case ActionParserIDENTIFIER, ActionParserVARIABLE: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(42) - p.Call_stmt() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISql_stmtContext is an interface to support dynamic dispatch. -type ISql_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - SQL_STMT() antlr.TerminalNode - SCOL() antlr.TerminalNode - - // IsSql_stmtContext differentiates from other interfaces. - IsSql_stmtContext() -} - -type Sql_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySql_stmtContext() *Sql_stmtContext { - var p = new(Sql_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_sql_stmt - return p -} - -func InitEmptySql_stmtContext(p *Sql_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_sql_stmt -} - -func (*Sql_stmtContext) IsSql_stmtContext() {} - -func NewSql_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_stmtContext { - var p = new(Sql_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_sql_stmt - - return p -} - -func (s *Sql_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Sql_stmtContext) SQL_STMT() antlr.TerminalNode { - return s.GetToken(ActionParserSQL_STMT, 0) -} - -func (s *Sql_stmtContext) SCOL() antlr.TerminalNode { - return s.GetToken(ActionParserSCOL, 0) -} - -func (s *Sql_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Sql_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Sql_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitSql_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Sql_stmt() (localctx ISql_stmtContext) { - localctx = NewSql_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 8, ActionParserRULE_sql_stmt) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(45) - p.Match(ActionParserSQL_STMT) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(46) - p.Match(ActionParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICall_stmtContext is an interface to support dynamic dispatch. -type ICall_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Call_body() ICall_bodyContext - SCOL() antlr.TerminalNode - Call_receivers() ICall_receiversContext - ASSIGN() antlr.TerminalNode - - // IsCall_stmtContext differentiates from other interfaces. - IsCall_stmtContext() -} - -type Call_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCall_stmtContext() *Call_stmtContext { - var p = new(Call_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_stmt - return p -} - -func InitEmptyCall_stmtContext(p *Call_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_stmt -} - -func (*Call_stmtContext) IsCall_stmtContext() {} - -func NewCall_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Call_stmtContext { - var p = new(Call_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_call_stmt - - return p -} - -func (s *Call_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Call_stmtContext) Call_body() ICall_bodyContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_bodyContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_bodyContext) -} - -func (s *Call_stmtContext) SCOL() antlr.TerminalNode { - return s.GetToken(ActionParserSCOL, 0) -} - -func (s *Call_stmtContext) Call_receivers() ICall_receiversContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_receiversContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_receiversContext) -} - -func (s *Call_stmtContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(ActionParserASSIGN, 0) -} - -func (s *Call_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Call_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Call_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitCall_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Call_stmt() (localctx ICall_stmtContext) { - localctx = NewCall_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 10, ActionParserRULE_call_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(51) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == ActionParserVARIABLE { - { - p.SetState(48) - p.Call_receivers() - } - { - p.SetState(49) - p.Match(ActionParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(53) - p.Call_body() - } - { - p.SetState(54) - p.Match(ActionParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICall_receiversContext is an interface to support dynamic dispatch. -type ICall_receiversContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllVariable() []IVariableContext - Variable(i int) IVariableContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsCall_receiversContext differentiates from other interfaces. - IsCall_receiversContext() -} - -type Call_receiversContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCall_receiversContext() *Call_receiversContext { - var p = new(Call_receiversContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_receivers - return p -} - -func InitEmptyCall_receiversContext(p *Call_receiversContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_receivers -} - -func (*Call_receiversContext) IsCall_receiversContext() {} - -func NewCall_receiversContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Call_receiversContext { - var p = new(Call_receiversContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_call_receivers - - return p -} - -func (s *Call_receiversContext) GetParser() antlr.Parser { return s.parser } - -func (s *Call_receiversContext) AllVariable() []IVariableContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IVariableContext); ok { - len++ - } - } - - tst := make([]IVariableContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IVariableContext); ok { - tst[i] = t.(IVariableContext) - i++ - } - } - - return tst -} - -func (s *Call_receiversContext) Variable(i int) IVariableContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IVariableContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IVariableContext) -} - -func (s *Call_receiversContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(ActionParserCOMMA) -} - -func (s *Call_receiversContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(ActionParserCOMMA, i) -} - -func (s *Call_receiversContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Call_receiversContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Call_receiversContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitCall_receivers(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Call_receivers() (localctx ICall_receiversContext) { - localctx = NewCall_receiversContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 12, ActionParserRULE_call_receivers) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(56) - p.Variable() - } - p.SetState(61) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ActionParserCOMMA { - { - p.SetState(57) - p.Match(ActionParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(58) - p.Variable() - } - - p.SetState(63) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICall_bodyContext is an interface to support dynamic dispatch. -type ICall_bodyContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Fn_name() IFn_nameContext - L_PAREN() antlr.TerminalNode - Fn_arg_list() IFn_arg_listContext - R_PAREN() antlr.TerminalNode - - // IsCall_bodyContext differentiates from other interfaces. - IsCall_bodyContext() -} - -type Call_bodyContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCall_bodyContext() *Call_bodyContext { - var p = new(Call_bodyContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_body - return p -} - -func InitEmptyCall_bodyContext(p *Call_bodyContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_call_body -} - -func (*Call_bodyContext) IsCall_bodyContext() {} - -func NewCall_bodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Call_bodyContext { - var p = new(Call_bodyContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_call_body - - return p -} - -func (s *Call_bodyContext) GetParser() antlr.Parser { return s.parser } - -func (s *Call_bodyContext) Fn_name() IFn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFn_nameContext) -} - -func (s *Call_bodyContext) L_PAREN() antlr.TerminalNode { - return s.GetToken(ActionParserL_PAREN, 0) -} - -func (s *Call_bodyContext) Fn_arg_list() IFn_arg_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFn_arg_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFn_arg_listContext) -} - -func (s *Call_bodyContext) R_PAREN() antlr.TerminalNode { - return s.GetToken(ActionParserR_PAREN, 0) -} - -func (s *Call_bodyContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Call_bodyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Call_bodyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitCall_body(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Call_body() (localctx ICall_bodyContext) { - localctx = NewCall_bodyContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 14, ActionParserRULE_call_body) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(64) - p.Fn_name() - } - { - p.SetState(65) - p.Match(ActionParserL_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(66) - p.Fn_arg_list() - } - { - p.SetState(67) - p.Match(ActionParserR_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IVariableContext is an interface to support dynamic dispatch. -type IVariableContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - VARIABLE() antlr.TerminalNode - - // IsVariableContext differentiates from other interfaces. - IsVariableContext() -} - -type VariableContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyVariableContext() *VariableContext { - var p = new(VariableContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_variable - return p -} - -func InitEmptyVariableContext(p *VariableContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_variable -} - -func (*VariableContext) IsVariableContext() {} - -func NewVariableContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableContext { - var p = new(VariableContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_variable - - return p -} - -func (s *VariableContext) GetParser() antlr.Parser { return s.parser } - -func (s *VariableContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ActionParserVARIABLE, 0) -} - -func (s *VariableContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *VariableContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *VariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitVariable(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Variable() (localctx IVariableContext) { - localctx = NewVariableContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 16, ActionParserRULE_variable) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(69) - p.Match(ActionParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IBlock_varContext is an interface to support dynamic dispatch. -type IBlock_varContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - BLOCK_VARIABLE() antlr.TerminalNode - - // IsBlock_varContext differentiates from other interfaces. - IsBlock_varContext() -} - -type Block_varContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyBlock_varContext() *Block_varContext { - var p = new(Block_varContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_block_var - return p -} - -func InitEmptyBlock_varContext(p *Block_varContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_block_var -} - -func (*Block_varContext) IsBlock_varContext() {} - -func NewBlock_varContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Block_varContext { - var p = new(Block_varContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_block_var - - return p -} - -func (s *Block_varContext) GetParser() antlr.Parser { return s.parser } - -func (s *Block_varContext) BLOCK_VARIABLE() antlr.TerminalNode { - return s.GetToken(ActionParserBLOCK_VARIABLE, 0) -} - -func (s *Block_varContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Block_varContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Block_varContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitBlock_var(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Block_var() (localctx IBlock_varContext) { - localctx = NewBlock_varContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 18, ActionParserRULE_block_var) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(71) - p.Match(ActionParserBLOCK_VARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExtension_call_nameContext is an interface to support dynamic dispatch. -type IExtension_call_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllIDENTIFIER() []antlr.TerminalNode - IDENTIFIER(i int) antlr.TerminalNode - PERIOD() antlr.TerminalNode - - // IsExtension_call_nameContext differentiates from other interfaces. - IsExtension_call_nameContext() -} - -type Extension_call_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExtension_call_nameContext() *Extension_call_nameContext { - var p = new(Extension_call_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_extension_call_name - return p -} - -func InitEmptyExtension_call_nameContext(p *Extension_call_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_extension_call_name -} - -func (*Extension_call_nameContext) IsExtension_call_nameContext() {} - -func NewExtension_call_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Extension_call_nameContext { - var p = new(Extension_call_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_extension_call_name - - return p -} - -func (s *Extension_call_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Extension_call_nameContext) AllIDENTIFIER() []antlr.TerminalNode { - return s.GetTokens(ActionParserIDENTIFIER) -} - -func (s *Extension_call_nameContext) IDENTIFIER(i int) antlr.TerminalNode { - return s.GetToken(ActionParserIDENTIFIER, i) -} - -func (s *Extension_call_nameContext) PERIOD() antlr.TerminalNode { - return s.GetToken(ActionParserPERIOD, 0) -} - -func (s *Extension_call_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Extension_call_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Extension_call_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitExtension_call_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Extension_call_name() (localctx IExtension_call_nameContext) { - localctx = NewExtension_call_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 20, ActionParserRULE_extension_call_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(73) - p.Match(ActionParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(74) - p.Match(ActionParserPERIOD) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(75) - p.Match(ActionParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFn_nameContext is an interface to support dynamic dispatch. -type IFn_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Extension_call_name() IExtension_call_nameContext - Action_name() IAction_nameContext - - // IsFn_nameContext differentiates from other interfaces. - IsFn_nameContext() -} - -type Fn_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyFn_nameContext() *Fn_nameContext { - var p = new(Fn_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_name - return p -} - -func InitEmptyFn_nameContext(p *Fn_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_name -} - -func (*Fn_nameContext) IsFn_nameContext() {} - -func NewFn_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Fn_nameContext { - var p = new(Fn_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_fn_name - - return p -} - -func (s *Fn_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Fn_nameContext) Extension_call_name() IExtension_call_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExtension_call_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExtension_call_nameContext) -} - -func (s *Fn_nameContext) Action_name() IAction_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IAction_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IAction_nameContext) -} - -func (s *Fn_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Fn_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Fn_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitFn_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Fn_name() (localctx IFn_nameContext) { - localctx = NewFn_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 22, ActionParserRULE_fn_name) - p.SetState(79) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) { - case 1: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(77) - p.Extension_call_name() - } - - case 2: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(78) - p.Action_name() - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISfn_nameContext is an interface to support dynamic dispatch. -type ISfn_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsSfn_nameContext differentiates from other interfaces. - IsSfn_nameContext() -} - -type Sfn_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySfn_nameContext() *Sfn_nameContext { - var p = new(Sfn_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_sfn_name - return p -} - -func InitEmptySfn_nameContext(p *Sfn_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_sfn_name -} - -func (*Sfn_nameContext) IsSfn_nameContext() {} - -func NewSfn_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sfn_nameContext { - var p = new(Sfn_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_sfn_name - - return p -} - -func (s *Sfn_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Sfn_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ActionParserIDENTIFIER, 0) -} - -func (s *Sfn_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Sfn_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Sfn_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitSfn_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Sfn_name() (localctx ISfn_nameContext) { - localctx = NewSfn_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 24, ActionParserRULE_sfn_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(81) - p.Match(ActionParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFn_arg_listContext is an interface to support dynamic dispatch. -type IFn_arg_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllFn_arg_expr() []IFn_arg_exprContext - Fn_arg_expr(i int) IFn_arg_exprContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsFn_arg_listContext differentiates from other interfaces. - IsFn_arg_listContext() -} - -type Fn_arg_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyFn_arg_listContext() *Fn_arg_listContext { - var p = new(Fn_arg_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_arg_list - return p -} - -func InitEmptyFn_arg_listContext(p *Fn_arg_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_arg_list -} - -func (*Fn_arg_listContext) IsFn_arg_listContext() {} - -func NewFn_arg_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Fn_arg_listContext { - var p = new(Fn_arg_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_fn_arg_list - - return p -} - -func (s *Fn_arg_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Fn_arg_listContext) AllFn_arg_expr() []IFn_arg_exprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IFn_arg_exprContext); ok { - len++ - } - } - - tst := make([]IFn_arg_exprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IFn_arg_exprContext); ok { - tst[i] = t.(IFn_arg_exprContext) - i++ - } - } - - return tst -} - -func (s *Fn_arg_listContext) Fn_arg_expr(i int) IFn_arg_exprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFn_arg_exprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IFn_arg_exprContext) -} - -func (s *Fn_arg_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(ActionParserCOMMA) -} - -func (s *Fn_arg_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(ActionParserCOMMA, i) -} - -func (s *Fn_arg_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Fn_arg_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Fn_arg_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitFn_arg_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Fn_arg_list() (localctx IFn_arg_listContext) { - localctx = NewFn_arg_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 26, ActionParserRULE_fn_arg_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(84) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&33319552516) != 0 { - { - p.SetState(83) - p.fn_arg_expr(0) - } - - } - p.SetState(90) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ActionParserCOMMA { - { - p.SetState(86) - p.Match(ActionParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(87) - p.fn_arg_expr(0) - } - - p.SetState(92) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFn_arg_exprContext is an interface to support dynamic dispatch. -type IFn_arg_exprContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetElevate_expr returns the elevate_expr rule contexts. - GetElevate_expr() IFn_arg_exprContext - - // GetUnary_expr returns the unary_expr rule contexts. - GetUnary_expr() IFn_arg_exprContext - - // SetElevate_expr sets the elevate_expr rule contexts. - SetElevate_expr(IFn_arg_exprContext) - - // SetUnary_expr sets the unary_expr rule contexts. - SetUnary_expr(IFn_arg_exprContext) - - // Getter signatures - Literal_value() ILiteral_valueContext - Variable() IVariableContext - Block_var() IBlock_varContext - Sfn_name() ISfn_nameContext - L_PAREN() antlr.TerminalNode - R_PAREN() antlr.TerminalNode - STAR() antlr.TerminalNode - AllFn_arg_expr() []IFn_arg_exprContext - Fn_arg_expr(i int) IFn_arg_exprContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - MINUS() antlr.TerminalNode - PLUS() antlr.TerminalNode - NOT_() antlr.TerminalNode - DIV() antlr.TerminalNode - MOD() antlr.TerminalNode - LT() antlr.TerminalNode - LT_EQ() antlr.TerminalNode - GT() antlr.TerminalNode - GT_EQ() antlr.TerminalNode - ASSIGN() antlr.TerminalNode - SQL_NOT_EQ1() antlr.TerminalNode - SQL_NOT_EQ2() antlr.TerminalNode - AND_() antlr.TerminalNode - OR_() antlr.TerminalNode - - // IsFn_arg_exprContext differentiates from other interfaces. - IsFn_arg_exprContext() -} - -type Fn_arg_exprContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - elevate_expr IFn_arg_exprContext - unary_expr IFn_arg_exprContext -} - -func NewEmptyFn_arg_exprContext() *Fn_arg_exprContext { - var p = new(Fn_arg_exprContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_arg_expr - return p -} - -func InitEmptyFn_arg_exprContext(p *Fn_arg_exprContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ActionParserRULE_fn_arg_expr -} - -func (*Fn_arg_exprContext) IsFn_arg_exprContext() {} - -func NewFn_arg_exprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Fn_arg_exprContext { - var p = new(Fn_arg_exprContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ActionParserRULE_fn_arg_expr - - return p -} - -func (s *Fn_arg_exprContext) GetParser() antlr.Parser { return s.parser } - -func (s *Fn_arg_exprContext) GetElevate_expr() IFn_arg_exprContext { return s.elevate_expr } - -func (s *Fn_arg_exprContext) GetUnary_expr() IFn_arg_exprContext { return s.unary_expr } - -func (s *Fn_arg_exprContext) SetElevate_expr(v IFn_arg_exprContext) { s.elevate_expr = v } - -func (s *Fn_arg_exprContext) SetUnary_expr(v IFn_arg_exprContext) { s.unary_expr = v } - -func (s *Fn_arg_exprContext) Literal_value() ILiteral_valueContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ILiteral_valueContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ILiteral_valueContext) -} - -func (s *Fn_arg_exprContext) Variable() IVariableContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IVariableContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IVariableContext) -} - -func (s *Fn_arg_exprContext) Block_var() IBlock_varContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IBlock_varContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IBlock_varContext) -} - -func (s *Fn_arg_exprContext) Sfn_name() ISfn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISfn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISfn_nameContext) -} - -func (s *Fn_arg_exprContext) L_PAREN() antlr.TerminalNode { - return s.GetToken(ActionParserL_PAREN, 0) -} - -func (s *Fn_arg_exprContext) R_PAREN() antlr.TerminalNode { - return s.GetToken(ActionParserR_PAREN, 0) -} - -func (s *Fn_arg_exprContext) STAR() antlr.TerminalNode { - return s.GetToken(ActionParserSTAR, 0) -} - -func (s *Fn_arg_exprContext) AllFn_arg_expr() []IFn_arg_exprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IFn_arg_exprContext); ok { - len++ - } - } - - tst := make([]IFn_arg_exprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IFn_arg_exprContext); ok { - tst[i] = t.(IFn_arg_exprContext) - i++ - } - } - - return tst -} - -func (s *Fn_arg_exprContext) Fn_arg_expr(i int) IFn_arg_exprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFn_arg_exprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IFn_arg_exprContext) -} - -func (s *Fn_arg_exprContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(ActionParserCOMMA) -} - -func (s *Fn_arg_exprContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(ActionParserCOMMA, i) -} - -func (s *Fn_arg_exprContext) MINUS() antlr.TerminalNode { - return s.GetToken(ActionParserMINUS, 0) -} - -func (s *Fn_arg_exprContext) PLUS() antlr.TerminalNode { - return s.GetToken(ActionParserPLUS, 0) -} - -func (s *Fn_arg_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(ActionParserNOT_, 0) -} - -func (s *Fn_arg_exprContext) DIV() antlr.TerminalNode { - return s.GetToken(ActionParserDIV, 0) -} - -func (s *Fn_arg_exprContext) MOD() antlr.TerminalNode { - return s.GetToken(ActionParserMOD, 0) -} - -func (s *Fn_arg_exprContext) LT() antlr.TerminalNode { - return s.GetToken(ActionParserLT, 0) -} - -func (s *Fn_arg_exprContext) LT_EQ() antlr.TerminalNode { - return s.GetToken(ActionParserLT_EQ, 0) -} - -func (s *Fn_arg_exprContext) GT() antlr.TerminalNode { - return s.GetToken(ActionParserGT, 0) -} - -func (s *Fn_arg_exprContext) GT_EQ() antlr.TerminalNode { - return s.GetToken(ActionParserGT_EQ, 0) -} - -func (s *Fn_arg_exprContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(ActionParserASSIGN, 0) -} - -func (s *Fn_arg_exprContext) SQL_NOT_EQ1() antlr.TerminalNode { - return s.GetToken(ActionParserSQL_NOT_EQ1, 0) -} - -func (s *Fn_arg_exprContext) SQL_NOT_EQ2() antlr.TerminalNode { - return s.GetToken(ActionParserSQL_NOT_EQ2, 0) -} - -func (s *Fn_arg_exprContext) AND_() antlr.TerminalNode { - return s.GetToken(ActionParserAND_, 0) -} - -func (s *Fn_arg_exprContext) OR_() antlr.TerminalNode { - return s.GetToken(ActionParserOR_, 0) -} - -func (s *Fn_arg_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Fn_arg_exprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Fn_arg_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ActionParserVisitor: - return t.VisitFn_arg_expr(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ActionParser) Fn_arg_expr() (localctx IFn_arg_exprContext) { - return p.fn_arg_expr(0) -} - -func (p *ActionParser) fn_arg_expr(_p int) (localctx IFn_arg_exprContext) { - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() - - _parentState := p.GetState() - localctx = NewFn_arg_exprContext(p, p.GetParserRuleContext(), _parentState) - var _prevctx IFn_arg_exprContext = localctx - var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. - _startState := 28 - p.EnterRecursionRule(localctx, 28, ActionParserRULE_fn_arg_expr, _p) - var _la int - - var _alt int - - p.EnterOuterAlt(localctx, 1) - p.SetState(120) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case ActionParserUNSIGNED_NUMBER_LITERAL, ActionParserSTRING_LITERAL: - { - p.SetState(94) - p.Literal_value() - } - - case ActionParserVARIABLE: - { - p.SetState(95) - p.Variable() - } - - case ActionParserBLOCK_VARIABLE: - { - p.SetState(96) - p.Block_var() - } - - case ActionParserIDENTIFIER: - { - p.SetState(97) - p.Sfn_name() - } - { - p.SetState(98) - p.Match(ActionParserL_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(108) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - switch p.GetTokenStream().LA(1) { - case ActionParserL_PAREN, ActionParserPLUS, ActionParserMINUS, ActionParserNOT_, ActionParserIDENTIFIER, ActionParserVARIABLE, ActionParserBLOCK_VARIABLE, ActionParserUNSIGNED_NUMBER_LITERAL, ActionParserSTRING_LITERAL: - { - p.SetState(99) - p.fn_arg_expr(0) - } - p.SetState(104) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ActionParserCOMMA { - { - p.SetState(100) - p.Match(ActionParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(101) - p.fn_arg_expr(0) - } - - p.SetState(106) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - - case ActionParserSTAR: - { - p.SetState(107) - p.Match(ActionParserSTAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case ActionParserR_PAREN: - - default: - } - { - p.SetState(110) - p.Match(ActionParserR_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case ActionParserL_PAREN: - { - p.SetState(112) - p.Match(ActionParserL_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(113) - - var _x = p.fn_arg_expr(0) - - localctx.(*Fn_arg_exprContext).elevate_expr = _x - } - { - p.SetState(114) - p.Match(ActionParserR_PAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case ActionParserPLUS, ActionParserMINUS: - { - p.SetState(116) - _la = p.GetTokenStream().LA(1) - - if !(_la == ActionParserPLUS || _la == ActionParserMINUS) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(117) - - var _x = p.fn_arg_expr(8) - - localctx.(*Fn_arg_exprContext).unary_expr = _x - } - - case ActionParserNOT_: - { - p.SetState(118) - p.Match(ActionParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(119) - - var _x = p.fn_arg_expr(3) - - localctx.(*Fn_arg_exprContext).unary_expr = _x - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(142) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - if p.GetParseListeners() != nil { - p.TriggerExitRuleEvent() - } - _prevctx = localctx - p.SetState(140) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 10, p.GetParserRuleContext()) { - case 1: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(122) - - if !(p.Precpred(p.GetParserRuleContext(), 7)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 7)", "")) - goto errorExit - } - { - p.SetState(123) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&14336) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(124) - p.fn_arg_expr(8) - } - - case 2: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(125) - - if !(p.Precpred(p.GetParserRuleContext(), 6)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) - goto errorExit - } - { - p.SetState(126) - _la = p.GetTokenStream().LA(1) - - if !(_la == ActionParserPLUS || _la == ActionParserMINUS) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(127) - p.fn_arg_expr(7) - } - - case 3: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(128) - - if !(p.Precpred(p.GetParserRuleContext(), 5)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) - goto errorExit - } - { - p.SetState(129) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&245760) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(130) - p.fn_arg_expr(6) - } - - case 4: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(131) - - if !(p.Precpred(p.GetParserRuleContext(), 4)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) - goto errorExit - } - { - p.SetState(132) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&786560) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(133) - p.fn_arg_expr(5) - } - - case 5: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(134) - - if !(p.Precpred(p.GetParserRuleContext(), 2)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) - goto errorExit - } - { - p.SetState(135) - p.Match(ActionParserAND_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(136) - p.fn_arg_expr(3) - } - - case 6: - localctx = NewFn_arg_exprContext(p, _parentctx, _parentState) - p.PushNewRecursionContext(localctx, _startState, ActionParserRULE_fn_arg_expr) - p.SetState(137) - - if !(p.Precpred(p.GetParserRuleContext(), 1)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) - goto errorExit - } - { - p.SetState(138) - p.Match(ActionParserOR_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(139) - p.fn_arg_expr(2) - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - - } - p.SetState(144) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.UnrollRecursionContexts(_parentctx) - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -func (p *ActionParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { - switch ruleIndex { - case 14: - var t *Fn_arg_exprContext = nil - if localctx != nil { - t = localctx.(*Fn_arg_exprContext) - } - return p.Fn_arg_expr_Sempred(t, predIndex) - - default: - panic("No predicate with index: " + fmt.Sprint(ruleIndex)) - } -} - -func (p *ActionParser) Fn_arg_expr_Sempred(localctx antlr.RuleContext, predIndex int) bool { - switch predIndex { - case 0: - return p.Precpred(p.GetParserRuleContext(), 7) - - case 1: - return p.Precpred(p.GetParserRuleContext(), 6) - - case 2: - return p.Precpred(p.GetParserRuleContext(), 5) - - case 3: - return p.Precpred(p.GetParserRuleContext(), 4) - - case 4: - return p.Precpred(p.GetParserRuleContext(), 2) - - case 5: - return p.Precpred(p.GetParserRuleContext(), 1) - - default: - panic("No predicate with index: " + fmt.Sprint(predIndex)) - } -} diff --git a/parse/actions/gen/actionparser_base_visitor.go b/parse/actions/gen/actionparser_base_visitor.go deleted file mode 100644 index 94f8eb78d..000000000 --- a/parse/actions/gen/actionparser_base_visitor.go +++ /dev/null @@ -1,68 +0,0 @@ -// Code generated from ActionParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package actgrammar // ActionParser -import "github.com/antlr4-go/antlr/v4" - -type BaseActionParserVisitor struct { - *antlr.BaseParseTreeVisitor -} - -func (v *BaseActionParserVisitor) VisitStatement(ctx *StatementContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitLiteral_value(ctx *Literal_valueContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitAction_name(ctx *Action_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitStmt(ctx *StmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitSql_stmt(ctx *Sql_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitCall_stmt(ctx *Call_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitCall_receivers(ctx *Call_receiversContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitCall_body(ctx *Call_bodyContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitVariable(ctx *VariableContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitBlock_var(ctx *Block_varContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitExtension_call_name(ctx *Extension_call_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitFn_name(ctx *Fn_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitSfn_name(ctx *Sfn_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitFn_arg_list(ctx *Fn_arg_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseActionParserVisitor) VisitFn_arg_expr(ctx *Fn_arg_exprContext) interface{} { - return v.VisitChildren(ctx) -} diff --git a/parse/actions/gen/actionparser_visitor.go b/parse/actions/gen/actionparser_visitor.go deleted file mode 100644 index dd49f7043..000000000 --- a/parse/actions/gen/actionparser_visitor.go +++ /dev/null @@ -1,54 +0,0 @@ -// Code generated from ActionParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package actgrammar // ActionParser -import "github.com/antlr4-go/antlr/v4" - -// A complete Visitor for a parse tree produced by ActionParser. -type ActionParserVisitor interface { - antlr.ParseTreeVisitor - - // Visit a parse tree produced by ActionParser#statement. - VisitStatement(ctx *StatementContext) interface{} - - // Visit a parse tree produced by ActionParser#literal_value. - VisitLiteral_value(ctx *Literal_valueContext) interface{} - - // Visit a parse tree produced by ActionParser#action_name. - VisitAction_name(ctx *Action_nameContext) interface{} - - // Visit a parse tree produced by ActionParser#stmt. - VisitStmt(ctx *StmtContext) interface{} - - // Visit a parse tree produced by ActionParser#sql_stmt. - VisitSql_stmt(ctx *Sql_stmtContext) interface{} - - // Visit a parse tree produced by ActionParser#call_stmt. - VisitCall_stmt(ctx *Call_stmtContext) interface{} - - // Visit a parse tree produced by ActionParser#call_receivers. - VisitCall_receivers(ctx *Call_receiversContext) interface{} - - // Visit a parse tree produced by ActionParser#call_body. - VisitCall_body(ctx *Call_bodyContext) interface{} - - // Visit a parse tree produced by ActionParser#variable. - VisitVariable(ctx *VariableContext) interface{} - - // Visit a parse tree produced by ActionParser#block_var. - VisitBlock_var(ctx *Block_varContext) interface{} - - // Visit a parse tree produced by ActionParser#extension_call_name. - VisitExtension_call_name(ctx *Extension_call_nameContext) interface{} - - // Visit a parse tree produced by ActionParser#fn_name. - VisitFn_name(ctx *Fn_nameContext) interface{} - - // Visit a parse tree produced by ActionParser#sfn_name. - VisitSfn_name(ctx *Sfn_nameContext) interface{} - - // Visit a parse tree produced by ActionParser#fn_arg_list. - VisitFn_arg_list(ctx *Fn_arg_listContext) interface{} - - // Visit a parse tree produced by ActionParser#fn_arg_expr. - VisitFn_arg_expr(ctx *Fn_arg_exprContext) interface{} -} diff --git a/parse/actions/grammar/ActionLexer.g4 b/parse/actions/grammar/ActionLexer.g4 deleted file mode 100644 index 9a8e75331..000000000 --- a/parse/actions/grammar/ActionLexer.g4 +++ /dev/null @@ -1,80 +0,0 @@ -/* - * A ANTLR4 grammar for Action. ONLY temporary. - * Developed by the Kuneiform team. -*/ - -lexer grammar ActionLexer; - -// symbols -SCOL: ';'; -L_PAREN: '('; -R_PAREN: ')'; -COMMA: ','; -DOLLAR: '$'; -AT: '@'; -ASSIGN: '='; -PERIOD: '.'; -//// sql scalar function expressions symbols -//// probably a different Lexical mode is a good idea -PLUS: '+'; -MINUS: '-'; -STAR: '*'; -DIV: '/'; -MOD: '%'; -LT: '<'; -LT_EQ: '<='; -GT: '>'; -GT_EQ: '>='; -SQL_NOT_EQ1: '!='; -SQL_NOT_EQ2: '<>'; -//// - -// keywords -// sql keywords -SELECT_: [sS][eE][lL][eE][cC][tT]; -INSERT_: [iI][nN][sS][eE][rR][tT]; -UPDATE_: [uU][pP][dD][aA][tT][eE]; -DELETE_: [dD][eE][lL][eE][tT][eE]; -WITH_: [wW][iI][tT][hH] ; - -//// scalar functions expressions keyworkds -//// probably a different Lexical mode is a good idea -NOT_: 'not'; -AND_: 'and'; -OR_: 'or'; -//// - -SQL_KEYWORDS: SELECT_ | INSERT_ | UPDATE_ | DELETE_ | WITH_; -// we only need sql statement as a whole, sql-parser will parse it -SQL_STMT: SQL_KEYWORDS WSNL ~[;}]+; - -// literals -IDENTIFIER: - [a-zA-Z] [a-zA-Z_0-9]* -; - -VARIABLE: DOLLAR IDENTIFIER; -BLOCK_VARIABLE: AT IDENTIFIER; - -UNSIGNED_NUMBER_LITERAL: - DIGIT+ -; - -STRING_LITERAL: - SINGLE_QUOTE_STRING -; - -WS: [ \t]+ -> channel(HIDDEN); -TERMINATOR: [\r\n]+ -> channel(HIDDEN); -BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); -LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); - -// fragments -fragment WSNL: [ \t\r\n]+; // whitespace with new line -fragment DIGIT: [0-9]; - -fragment DOUBLE_QUOTE_STRING_CHAR: ~["\r\n\\] | ('\\' .); -fragment SINGLE_QUOTE_STRING_CHAR: ~['\r\n\\] | ('\\' .); - -//fragment DOUBLE_QUOTE_STRING: '"' DOUBLE_QUOTE_STRING_CHAR* '"'; -fragment SINGLE_QUOTE_STRING: '\'' SINGLE_QUOTE_STRING_CHAR* '\''; \ No newline at end of file diff --git a/parse/actions/grammar/ActionParser.g4 b/parse/actions/grammar/ActionParser.g4 deleted file mode 100644 index d1a316c97..000000000 --- a/parse/actions/grammar/ActionParser.g4 +++ /dev/null @@ -1,122 +0,0 @@ -/* - * A ANTLR4 grammar for Action. ONLY temporary. - * Developed by the Kuneiform team. -*/ - -parser grammar ActionParser; - -options { - tokenVocab=ActionLexer; -} - -statement: - stmt+ EOF -; - -literal_value: - STRING_LITERAL - | UNSIGNED_NUMBER_LITERAL -; - -// NOTE: this is temporary, this will be same as `ext_call_name` -// but we don't support call external action yet. -action_name: - IDENTIFIER -; - -stmt: - sql_stmt - | call_stmt -; - -sql_stmt: - SQL_STMT SCOL -; - -call_stmt: - (call_receivers ASSIGN)? - call_body SCOL -; - -call_receivers: - variable (COMMA variable)* -; - -// use expr in the future, limit syntax for now -call_body: - fn_name - L_PAREN fn_arg_list R_PAREN -; - -variable: - VARIABLE -; - -block_var: - BLOCK_VARIABLE -; - -extension_call_name: - IDENTIFIER PERIOD IDENTIFIER -; - -//external_action_name: -// IDENTIFIER PERIOD IDENTIFIER -//; - -// function name -fn_name: - extension_call_name - | action_name -// | external_action_name -; - -// scalar function, it is meant to be same as SQL scalar function name -sfn_name: - IDENTIFIER -; - -//fn_arg: -// literal_value -// | variable_name -// | block_variable_name -//; - -fn_arg_list: -// fn_arg? (COMMA fn_arg)* - fn_arg_expr? (COMMA fn_arg_expr)* -; - -// NOTE: this will only be used inside fn_arg_list, his is based on sqlparser's expr. -// This is only meant to support the most basic expressions. -// -// binary operators precedence: highest to lowest: -// * / % -// + - -// < <= > >= -// == != <> -// = -// AND -// OR -fn_arg_expr: - // primary expressions(don't fit in operator pattern), order is irrelevant - literal_value - | variable - | block_var - // scalar functions - | sfn_name L_PAREN ( (fn_arg_expr (COMMA fn_arg_expr)*) | STAR )? R_PAREN - // order is relevant for below expressions - | L_PAREN elevate_expr=fn_arg_expr R_PAREN - | ( MINUS | PLUS ) unary_expr=fn_arg_expr - // binary operators - | fn_arg_expr ( STAR | DIV | MOD ) fn_arg_expr - | fn_arg_expr ( PLUS | MINUS) fn_arg_expr - | fn_arg_expr ( LT | LT_EQ | GT | GT_EQ ) fn_arg_expr - | fn_arg_expr ( ASSIGN | SQL_NOT_EQ1 | SQL_NOT_EQ2 ) fn_arg_expr - // logical operators - | NOT_ unary_expr=fn_arg_expr - | fn_arg_expr AND_ fn_arg_expr - | fn_arg_expr OR_ fn_arg_expr -; - -// future expr, replace whole `call_body`? \ No newline at end of file diff --git a/parse/actions/grammar/generate.sh b/parse/actions/grammar/generate.sh deleted file mode 100755 index 9c346f944..000000000 --- a/parse/actions/grammar/generate.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -set -e - -cd "$(dirname "$0")" - -target=${1:-Go} -package=${2:-actgrammar} -output_dir=${3:-../gen} - -antlr_bin=antlr-4.13.1-complete.jar - -if [ ! -f $antlr_bin ]; then - echo "Downloading antlr4 jar file..." - curl -O https://www.antlr.org/download/${antlr_bin} -fi - -alias antlr4='java -Xmx500M -cp "./${antlr_bin}:$CLASSPATH" org.antlr.v4.Tool' -antlr4 -Dlanguage="${target}" -visitor -no-listener -package "${package}" -o "${output_dir}" *.g4 \ No newline at end of file diff --git a/parse/actions/parser/ast_builder.go b/parse/actions/parser/ast_builder.go deleted file mode 100644 index 2fd4c85c2..000000000 --- a/parse/actions/parser/ast_builder.go +++ /dev/null @@ -1,358 +0,0 @@ -package actparser - -import ( - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/antlr4-go/antlr/v4" - - actgrammar "github.com/kwilteam/kwil-db/parse/actions/gen" - "github.com/kwilteam/kwil-db/parse/metadata" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -// astBuilder is the visitor to build the ast from the parse tree -type astBuilder struct { - actgrammar.BaseActionParserVisitor - // @yaiba NOTE: may need schema to distinguish extension and action - - trace bool - errs parseTypes.AntlrErrorListener -} - -var _ actgrammar.ActionParserVisitor = &astBuilder{} - -//func (v *astBuilder) getPos(ctx antlr.ParserRuleContext) *tree.Position { -// if !v.trackPos { -// return nil -// } -// -// return &tree.Position{ -// StartLine: ctx.GetStart().GetLine(), -// StartColumn: ctx.GetStart().GetColumn(), -// EndLine: ctx.GetStop().GetLine(), -// EndColumn: ctx.GetStop().GetColumn(), -// } -//} - -// Visit dispatch to the visit method of the ctx -// e.g. if the tree is a ParseContext, then dispatch call VisitParse. -// Overwrite is needed, -// refer to https://github.com/antlr/antlr4/pull/1841#issuecomment-576791512 -func (v *astBuilder) Visit(tree antlr.ParseTree) interface{} { - if v.trace { - fmt.Printf("visit tree: %v, %s\n", reflect.TypeOf(tree), tree.GetText()) - } - return tree.Accept(v) -} - -// VisitChildren visits the children of the specified node. -// Overwrite is needed, -// refer to https://github.com/antlr/antlr4/pull/1841#issuecomment-576791512 -// calling function need to convert the result to asts -func (v *astBuilder) VisitChildren(node antlr.RuleNode) interface{} { - var result []ActionStmt - n := node.GetChildCount() - for i := 0; i < n; i++ { - child := node.GetChild(i) - if !v.shouldVisitNextChild(child, result) { - if v.trace { - fmt.Printf("should not visit next child: %v,\n", reflect.TypeOf(child)) - } - break - } - c := child.(antlr.ParseTree) - childResult := v.Visit(c).(ActionStmt) - result = append(result, childResult) - } - return result -} - -func (v *astBuilder) shouldVisitNextChild(node antlr.Tree, currentResult interface{}) bool { - if _, ok := node.(antlr.TerminalNode); ok { - return false - } - - return true -} - -// VisitStatement is called when start parsing, return []types.ActionStmt -func (v *astBuilder) VisitStatement(ctx *actgrammar.StatementContext) interface{} { - stmtCount := len(ctx.AllStmt()) - stmts := make([]ActionStmt, stmtCount) - - for i, stmtCtx := range ctx.AllStmt() { - if stmtCtx.Call_stmt() != nil { - stmts[i] = v.Visit(stmtCtx.Call_stmt()).(ActionStmt) - } else { - stmts[i] = v.Visit(stmtCtx.Sql_stmt()).(ActionStmt) - } - } - - return stmts -} - -// VisitSql_stmt is called when parse sql statement, return *types.DMLStmt -func (v *astBuilder) VisitSql_stmt(ctx *actgrammar.Sql_stmtContext) interface{} { - stmt := ctx.GetText() - d := &DMLStmt{Statement: stmt} - d.Set(ctx) - return d -} - -// VisitCall_stmt is called when parse call statement, return *types.CallStmt -func (v *astBuilder) VisitCall_stmt(ctx *actgrammar.Call_stmtContext) interface{} { - // `a.b` is only for extension calls for now - fnName := ctx.Call_body().Fn_name().GetText() - if ctx.Call_body().Fn_name().Extension_call_name() != nil { - // NOTE: in the future, if we support call external action, then the - // extension_call and action_call could be the same syntax, need a better - // way to distinguish them. A naive way is to check the function name with - // the list of extensions we have in current Kuneiform. - - // extension call - stmt := &ExtensionCallStmt{ - Extension: strings.Split(fnName, ".")[0], - Method: strings.Split(fnName, ".")[1], - } - - if ctx.Call_receivers() != nil { - stmt.Receivers = v.Visit(ctx.Call_receivers()).([]string) - } - - if len(ctx.Call_body().Fn_arg_list().AllFn_arg_expr()) > 0 { - stmt.Args = v.Visit(ctx.Call_body().Fn_arg_list()).([]tree.Expression) - } - - stmt.Set(ctx) - - return stmt - - } else { - // action call - stmt := &ActionCallStmt{ - Method: fnName, - } - - if len(ctx.Call_body().Fn_arg_list().AllFn_arg_expr()) > 0 { - stmt.Args = v.Visit(ctx.Call_body().Fn_arg_list()).([]tree.Expression) - } - - stmt.Set(ctx) - - return stmt - } -} - -// VisitCall_receivers is called when parse call receivers, return []string -func (v *astBuilder) VisitCall_receivers(ctx *actgrammar.Call_receiversContext) interface{} { - receivers := make([]string, len(ctx.AllVariable())) - for i, varCtx := range ctx.AllVariable() { - receivers[i] = varCtx.GetText() - } - return receivers -} - -// VisitFn_arg_list is called when parse function argument list, return []tree.Expression -func (v *astBuilder) VisitFn_arg_list(ctx *actgrammar.Fn_arg_listContext) interface{} { - args := make([]tree.Expression, len(ctx.AllFn_arg_expr())) - for i, argCtx := range ctx.AllFn_arg_expr() { - args[i] = v.Visit(argCtx).(tree.Expression) - } - return args -} - -// VisitFn_arg_expr is called when parse function argument expression return tree.Expression -// NOTE: this is a subset of util.KFSqliteVisitor.VisitExpr -func (v *astBuilder) VisitFn_arg_expr(ctx *actgrammar.Fn_arg_exprContext) interface{} { - return v.visitFn_arg_expr(ctx) -} - -func (v *astBuilder) visitFn_arg_expr(ctx actgrammar.IFn_arg_exprContext) tree.Expression { - if ctx == nil { - return nil - } - - // order is important, map to expr definition in Antlr sql-grammar(not exactly) - switch { - // primary expressions - case ctx.Literal_value() != nil: - // a bit of a hack, but this is to work around the act parser being separate from the sql parser - // if it has single quotes, it's a string literal - // if it has no quotes, we will attempt to convert it to a number - // if neither of these work, we will panic - literal := ctx.Literal_value().GetText() - if strings.HasPrefix(literal, "'") && strings.HasSuffix(literal, "'") { - return &tree.ExpressionTextLiteral{Value: literal[1 : len(literal)-1]} - } else { - i, err := strconv.ParseInt(literal, 10, 64) - if err == nil { - return &tree.ExpressionNumericLiteral{Value: i} - } - } - v.errs.RuleErr(ctx.Literal_value(), parseTypes.ParseErrorTypeSyntax, fmt.Errorf("cannot recognize literal '%s'", literal)) - return &tree.ExpressionNullLiteral{} // just to avoid nil panic - // sql bind parameter - case ctx.Variable() != nil: - return &tree.ExpressionBindParameter{Parameter: ctx.Variable().GetText()} - case ctx.Block_var() != nil: - return &tree.ExpressionBindParameter{Parameter: ctx.Block_var().GetText()} - case ctx.GetElevate_expr() != nil: - expr := v.visitFn_arg_expr(ctx.GetElevate_expr()) - switch t := expr.(type) { - case *tree.ExpressionTextLiteral: - t.Wrapped = true - case *tree.ExpressionNumericLiteral: - t.Wrapped = true - case *tree.ExpressionBindParameter: - t.Wrapped = true - case *tree.ExpressionUnary: - t.Wrapped = true - case *tree.ExpressionBinaryComparison: - t.Wrapped = true - case *tree.ExpressionFunction: - t.Wrapped = true - case *tree.ExpressionArithmetic: - t.Wrapped = true - default: - panic(fmt.Sprintf("unknown expression type %T", expr)) - } - return expr - // unary operators - case ctx.MINUS() != nil && ctx.GetUnary_expr() != nil: - return &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: v.visitFn_arg_expr(ctx.GetUnary_expr()), - } - case ctx.PLUS() != nil && ctx.GetUnary_expr() != nil: - return &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorPlus, - Operand: v.visitFn_arg_expr(ctx.GetUnary_expr()), - } - // binary opertors - // artithmetic operators - // TODO: this was where ctx.STAR() != nil was - case ctx.STAR() != nil: - return &tree.ExpressionArithmetic{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ArithmeticOperatorMultiply, - } - case ctx.DIV() != nil: - return &tree.ExpressionArithmetic{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ArithmeticOperatorDivide, - } - case ctx.MOD() != nil: - return &tree.ExpressionArithmetic{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ArithmeticOperatorModulus, - } - case ctx.PLUS() != nil: - return &tree.ExpressionArithmetic{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ArithmeticOperatorAdd, - } - case ctx.MINUS() != nil: - return &tree.ExpressionArithmetic{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ArithmeticOperatorSubtract, - } - // compare operators - case ctx.LT() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorLessThan, - } - case ctx.LT_EQ() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorLessThanOrEqual, - } - case ctx.GT() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorGreaterThan, - } - case ctx.GT_EQ() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorGreaterThanOrEqual, - } - case ctx.ASSIGN() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorEqual, - } - case ctx.SQL_NOT_EQ1() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorNotEqual, - } - case ctx.SQL_NOT_EQ2() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - Operator: tree.ComparisonOperatorNotEqualDiamond, - } - // unary op NOT - case ctx.NOT_() != nil && ctx.GetUnary_expr() != nil: - return &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: v.visitFn_arg_expr(ctx.GetUnary_expr()), - } - case ctx.AND_() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Operator: tree.LogicalOperatorAnd, - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - } - case ctx.OR_() != nil: - return &tree.ExpressionBinaryComparison{ - Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - Operator: tree.LogicalOperatorOr, - Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - } - case ctx.Sfn_name() != nil: - expr := &tree.ExpressionFunction{ - Inputs: make([]tree.Expression, len(ctx.AllFn_arg_expr())), - } - expr.Function = util.ExtractSQLName(ctx.Sfn_name().GetText()) - - // this is a really ugly dependency; not quite circular, so it is ok. - // Since we likely will not make many changes to actions (in favor of procedures), - // it is ok for now - _, ok := metadata.Functions[strings.ToLower(expr.Function)] - if !ok { - v.errs.RuleErr(ctx.Sfn_name(), parseTypes.ParseErrorTypeSyntax, fmt.Errorf("function %s does not exist", expr.Function)) - return &tree.ExpressionNullLiteral{} - } - - for i, e := range ctx.AllFn_arg_expr() { - expr.Inputs[i] = v.visitFn_arg_expr(e) - } - return expr - //case ctx.STAR() != nil: - // return &tree.ExpressionArithmetic{ - // Left: v.visitFn_arg_expr(ctx.Fn_arg_expr(0)), - // Right: v.visitFn_arg_expr(ctx.Fn_arg_expr(1)), - // Operator: tree.ArithmeticOperatorMultiply, - // } - default: - panic(fmt.Sprintf("cannot recognize expr '%s'", ctx.GetText())) - } -} diff --git a/parse/actions/parser/parser.go b/parse/actions/parser/parser.go deleted file mode 100644 index 35ce94b85..000000000 --- a/parse/actions/parser/parser.go +++ /dev/null @@ -1,73 +0,0 @@ -// Package actparser contains the parser for the statements inside the kuneiform -// action block. -// This package is only temporary, to reduce the need to change our public -// kuneiform schema. Once our schema is stable, we will remove this package, and -// put actual Stmt types to kuneiform schema (so engine doesn't need to parse). -// -// By having this package, we can just check the syntax of the action block -// without parsing, then pass the whole statement to the engine. The engine will -// parse the statements to its needs. -package actparser - -import ( - "fmt" - "runtime" - - "github.com/antlr4-go/antlr/v4" - - actgrammar "github.com/kwilteam/kwil-db/parse/actions/gen" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// Parse parses multiple action statements and returns a slice of ActionStmt. -// This is to maintain compatibility with the old function signature. -func Parse(stmt string, errLis parseTypes.AntlrErrorListener) (asts []ActionStmt, err error) { - var visitor *astBuilder - - stream := antlr.NewInputStream(stmt) - lexer := actgrammar.NewActionLexer(stream) - tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) - p := actgrammar.NewActionParser(tokenStream) - - // remove default error visitor - lexer.RemoveErrorListeners() - lexer.AddErrorListener(errLis) - p.RemoveErrorListeners() - p.AddErrorListener(errLis) - - p.BuildParseTrees = true - - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("panic: %v", e) - } - - // if there is a panic, it is likely due to a syntax error - // check for parse errors and return them first - if errLis.Err() != nil { - // if there is an error listener error, we should swallow the panic - // If the issue persists until after the user has fixed the parse errors, - // the panic will be returned in the else block. - err = nil - } else { - // if there are no parse errors, then there is a bug. - // we should return the panic with a stack trace. - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - - err = fmt.Errorf("%w\n\n%s", err, buf[:stackSize]) - } - } - }() - - visitor = &astBuilder{ - errs: errLis, - } - - parseTree := p.Statement() - result := visitor.Visit(parseTree) - return result.([]ActionStmt), err -} diff --git a/parse/actions/parser/parser_test.go b/parse/actions/parser/parser_test.go deleted file mode 100644 index 056d0db79..000000000 --- a/parse/actions/parser/parser_test.go +++ /dev/null @@ -1,272 +0,0 @@ -package actparser_test - -import ( - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - actparser "github.com/kwilteam/kwil-db/parse/actions/parser" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -func Test_ParseMany(t *testing.T) { - stmt := ` - $id = action_x(2, '3'); - INSERT INTO users (id, name) VALUES ($id, 'test'); - ` - - errLis := parseTypes.NewErrorListener() - - got, err := actparser.Parse(stmt, errLis) - assert.NoError(t, err) - - assert.Len(t, got, 2) -} - -func TestParseActionStmt(t *testing.T) { - tests := []struct { - name string - input string - expect actparser.ActionStmt - }{ - { - name: "action_call", - // both `-2` and `- 2` will be parsed as ExpressionUnary - input: `action_xx(2, '3', $a, @b, -2, 1 + - 2, (1 * 2) + 3, 1 <= 2, 1 and $c, abs($c), abs(upper($c)));`, - expect: &actparser.ActionCallStmt{ - Method: "action_xx", - Args: []tree.Expression{ - &tree.ExpressionNumericLiteral{Value: 2}, - &tree.ExpressionTextLiteral{Value: `3`}, - &tree.ExpressionBindParameter{Parameter: "$a"}, - &tree.ExpressionBindParameter{Parameter: "@b"}, - &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: &tree.ExpressionNumericLiteral{Value: 2}, - }, - &tree.ExpressionArithmetic{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: &tree.ExpressionNumericLiteral{Value: 2}, - }, - }, - &tree.ExpressionArithmetic{ - Left: &tree.ExpressionArithmetic{ - Wrapped: true, - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ArithmeticOperatorMultiply, - Right: &tree.ExpressionNumericLiteral{Value: 2}, - }, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionNumericLiteral{Value: 3}, - }, - &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ComparisonOperatorLessThanOrEqual, - Right: &tree.ExpressionNumericLiteral{Value: 2}, - }, - &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.LogicalOperatorAnd, - Right: &tree.ExpressionBindParameter{Parameter: "$c"}, - }, - &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{&tree.ExpressionBindParameter{Parameter: "$c"}}, - }, - &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{ - &tree.ExpressionFunction{ - Function: "upper", - Inputs: []tree.Expression{&tree.ExpressionBindParameter{Parameter: "$c"}}, - }, - }, - }, - }, - }, - }, - { - name: "extension_call", - // both `-2` and `- 2` will be parsed as ExpressionUnary - input: `$a, $b = erc20.transfer(2, '3', $a, @b, -2, 1 + - 2, (1 * 2) + 3, 1 <= 2, 1 and $c, abs($c), abs(upper($c)));`, - expect: &actparser.ExtensionCallStmt{ - Extension: "erc20", - Method: "transfer", - Receivers: []string{"$a", "$b"}, - Args: []tree.Expression{ - &tree.ExpressionNumericLiteral{Value: 2}, - &tree.ExpressionTextLiteral{Value: "3"}, - &tree.ExpressionBindParameter{Parameter: "$a"}, - &tree.ExpressionBindParameter{Parameter: "@b"}, - &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: &tree.ExpressionNumericLiteral{Value: 2}, - }, - &tree.ExpressionArithmetic{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: &tree.ExpressionNumericLiteral{Value: 2}, - }, - }, - &tree.ExpressionArithmetic{ - Left: &tree.ExpressionArithmetic{ - Wrapped: true, - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ArithmeticOperatorMultiply, - Right: &tree.ExpressionNumericLiteral{Value: 2}, - }, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionNumericLiteral{Value: 3}, - }, - &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.ComparisonOperatorLessThanOrEqual, - Right: &tree.ExpressionNumericLiteral{Value: 2}, - }, - &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionNumericLiteral{Value: 1}, - Operator: tree.LogicalOperatorAnd, - Right: &tree.ExpressionBindParameter{Parameter: "$c"}, - }, - &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{&tree.ExpressionBindParameter{Parameter: "$c"}}, - }, - &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{ - &tree.ExpressionFunction{ - Function: "upper", - Inputs: []tree.Expression{&tree.ExpressionBindParameter{Parameter: "$c"}}, - }, - }, - }, - }, - }, - }, - { - name: "action_call with sql keyword prefix", - input: `update_xx(1);`, - expect: &actparser.ActionCallStmt{ - Method: "update_xx", - Args: []tree.Expression{ - &tree.ExpressionNumericLiteral{Value: 1}, - }, - }, - }, - { - name: "dml select", - input: `SELECT * FROM users;`, - expect: &actparser.DMLStmt{ - Statement: `SELECT * FROM users;`, - }, - }, - { - name: "dml insert", - input: `insert into users (id, name) values (1, "test");`, - expect: &actparser.DMLStmt{ - Statement: `insert into users (id, name) values (1, "test");`, - }, - }, - { - name: "dml update", - input: `update users set name = "test" where id = 1;`, - expect: &actparser.DMLStmt{ - Statement: `update users set name = "test" where id = 1;`, - }, - }, - { - name: "dml delete", - input: `delete from users where id = 1;`, - expect: &actparser.DMLStmt{ - Statement: `delete from users where id = 1;`, - }, - }, - { - name: "dml with", - input: `with x as (select * from users) select * from x;`, - expect: &actparser.DMLStmt{ - Statement: `with x as (select * from users) select * from x;`, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - errLis := parseTypes.NewErrorListener() - gotAst, err := actparser.Parse(tt.input, errLis) - require.NoError(t, err, "ParseActionStmt(%v)", tt.input) - err = errLis.Err() - - if err != nil { - t.Errorf("ParseActionStmt() error = %v", err) - return - } - - if !deepCompare(gotAst[0], tt.expect) { - t.Errorf("ParseActionStmt() got = %v, want %v", gotAst[0], tt.expect) - } - }) - } -} - -func TestParseActionStmt_scalar_function(t *testing.T) { - tests := []struct { - name string - input string - wantErr bool - }{ - { - name: "scalar function notexist", - input: `a(notexist($a));`, - wantErr: true, - }, - } - - fns := []string{ - "format", "count", "lower", "upper", "abs", "error", "length", "sum", - } - - // existing scalar functions - for _, fn := range fns { - tests = append(tests, struct { - name string - input string - wantErr bool - }{ - name: "scalar function " + fn, - input: "a(" + fn + "($a));", - }) - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - errLis := parseTypes.NewErrorListener() - _, err := actparser.Parse(tt.input, errLis) - require.NoError(t, err, "ParseActionStmt(%v)", tt.input) - err = errLis.Err() - if tt.wantErr { - assert.Error(t, err, "ParseActionStmt(%v)", tt.input) - } else { - assert.NoError(t, err, "ParseActionStmt(%v)", tt.input) - } - }) - } -} - -// deepCompare deep compares the values of two nodes. -// It ignores the parseTypes.Node field. -func deepCompare(node1, node2 any) bool { - // we return true for the parseTypes.Node field, - // we also need to ignore the unexported "schema" fields - return cmp.Equal(node1, node2, cmp.Comparer(func(x, y parseTypes.Node) bool { - return true - })) -} diff --git a/parse/actions/parser/statement.go b/parse/actions/parser/statement.go deleted file mode 100644 index 4ef6038e5..000000000 --- a/parse/actions/parser/statement.go +++ /dev/null @@ -1,44 +0,0 @@ -package actparser - -import ( - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -type ActionStmt interface { - StmtType() string -} - -type ExtensionCallStmt struct { - parseTypes.Node - Extension string - Method string - Args []tree.Expression - Receivers []string -} - -type ActionCallStmt struct { - parseTypes.Node - Database string // for future use, e.g. call an action from another kuneiform - Method string - Args []tree.Expression - Receivers []string -} - -// DMLStmt is a DML statement, we leave the parsing to sqlparser -type DMLStmt struct { - parseTypes.Node - Statement string -} - -func (s *ExtensionCallStmt) StmtType() string { - return "extension_call" -} - -func (s *ActionCallStmt) StmtType() string { - return "action_call" -} - -func (s *DMLStmt) StmtType() string { - return "dml" -} diff --git a/parse/analyze.go b/parse/analyze.go new file mode 100644 index 000000000..5dfa60211 --- /dev/null +++ b/parse/analyze.go @@ -0,0 +1,2488 @@ +package parse + +import ( + "fmt" + + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/utils/order" +) + +/* + this file performs analysis of SQL and procedures. It performs several main types of validation: + 1. Type checking: it ensures that all all statements and expressions return correct types. + This is critical because plpgsql only throws type errors at runtime, which is really bad + for a smart contract language. + 2. Deterministic ordering: it ensures that all queries have deterministic ordering, even if + not specified by the query writer. It adds necessary ordering clauses to achieve this. + 3. Aggregate checks: it ensures that aggregate functions are used correctly, and that they + can not be used to create non-determinism, and also that they return errors that would otherwise + be thrown by Postgres at runtime. + 4. Mutative checks: it analyzes whether or not a procedure / sql statement is attempting to + modify state. It does not return an error if it does, but will return a boolean indicating + whether or not it is mutative. This can be used by callers to ensure that VIEW procedures + are not mutative, which would otherwise only be checked at runtime when executing them with + a read-only transaction. + 5. Contextual statement checks: Procedure statements that can only be used in certain contexts + (e.g. loop breaks and RETURN NEXT) are checked to ensure that they are only used in loops. + 6. PLPGSQL Variable Declarations: It analyzes what variables should be declared at the top + of a PLPGSQL statement, and what types they should be. + 7. Cartesian Join Checks: All joins must be joined using =, and one side of the join condition + must be a unique column with no other math applied to it. Primary keys are also counted as unique, + unless it is a compound primary key. + + DETERMINISTIC ORDERING RULES: + If a SELECT statement is a simple select (e.g. does not use compound operators): + + 1. All joined tables that are physical (and not subqueries or procedure calls) are ordered by their primary keys, + in the order they are joined. + + 2. If a SELECT has a DISTINCT clause, it will order by all columns being returned. The reason + for this can be seen here: https://stackoverflow.com/questions/3492093/does-postgresql-support-distinct-on-multiple-columns. + All previous rules do not apply. + + 3. If a SELECT has a GROUP BY clause, all columns specified in the GROUP BY clause will be ordered. + All previous rules do not apply. + + If a SELECT statement is a compound select (e.g. uses UNION, UNION ALL INTERSECT, EXCEPT): + + 1. All returned columns are ordered by their position in the SELECT statement. + + 2. If any compound SELECT statement has a GROUP BY, then it will return an error. + This is a remnant of SQLite's rudimentary indexing, but these queries are fairly uncommon, + and therefore not allowed for the time being + + + AGGREGATE FUNCTION RULES: + + 1. Aggregate functions can only be used in the SELECT clause, and not in the WHERE clause. + + 2. All columns referenced in HAVING or return columns must be in the GROUP BY clause, unless they are + in an aggregate function. + + 3. All columns used within aggregate functions cannot be specified in the GROUP BY clause. + + 4. If there is an aggregate in the return columns and no GROUP BY clause, then there can only + be one column in the return columns (the column with the aggregate function). +*/ + +// blockContext is the context for the current block. This is can be an action, procedure, +// or sql block. +type blockContext struct { + // schema is the current schema + schema *types.Schema + // variables holds information about all variable declarations in the block + // It holds both user variables like $arg1, $arg2, and contextual variables, + // like @caller and @txid. It will be populated while the analyzer is running, + // but is prepopulated with the procedure's arguments and contextual variables. + variables map[string]*types.DataType + // anonymousVariables holds information about all anonymous variable declarations in the block. + // Anonymous variables are objects with fields, such as the receiver of loops. + // The map maps the name to the fields to their data types. + // The map will be populated while the analyzer is running. + anonymousVariables map[string]map[string]*types.DataType + // errs is used for passing errors back to the caller. + errs *errorListener +} + +// variableExists checks if a variable exists in the current block. +// It will check both user variables and anonymous variables. +func (b *blockContext) variableExists(name string) bool { + _, ok := b.variables[name] + if ok { + return true + } + + _, ok = b.anonymousVariables[name] + return ok +} + +// sqlContext is the context of the current SQL statement +type sqlContext struct { + // joinedRelations tracks all relations joined on the current SQL statement. + joinedRelations []*Relation + // outerRelations are relations that are not joined on the scope, but are available. + // These are typically outer queries in a subquery. Calling these will be a correlated subquery. + outerRelations []*Relation + // joinedTables maps all used table names/aliases to their table definitions. + // The tables named here are also included in joinedRelations, but not + // all joinedRelations are in this map. This map ONLY includes actual SQL + // tables joined in this context, not joined subqueries or procedure calls. + // These are used for default ordering. + joinedTables map[string]*types.Table + // ctes are the common table expressions in the current scope. + ctes []*Relation + // outerScope is the scope of the outer query. + outerScope *sqlContext + // isAction is true if the visitor is analyzing SQL within an action. + isAction bool + // inConflict is true if we are in an ON CONFLICT clause + inConflict bool + // targetTable is the name (or alias) of the table being inserted, updated, or deleted to/from. + // It is not set if we are not in an insert, update, or delete statement. + targetTable string + // hasAnonymousTable is true if an unnamed table has been joined. If this is true, + // it can be the only table joined in a select statement. + hasAnonymousTable bool + // inSelect is true if we are in a select statement. + inSelect bool + + // temp are values that are temporary and not even saved within the same scope. + // they are used in highly specific contexts, and shouldn't be relied on unless + // specifically documented. All temp values are denoted with a _. + + // inAggregate is true if we are within an aggregate functions parameters. + // it should only be used in ExpressionColumn, and set in ExpressionFunctionCall. + _inAggregate bool + // containsAggregate is true if the current expression contains an aggregate function. + // it is set in ExpressionFunctionCall, and accessed/reset in SelectCore. + _containsAggregate bool + // columnInAggregate is the column found within an aggregate function, + // comprised of the relation and attribute. + // It is set in ExpressionColumn, and accessed/reset in + // SelectCore. It is nil if none are found. + _columnInAggregate *[2]string + // columnsOutsideAggregate are columns found outside of an aggregate function. + // It is set in ExpressionColumn, and accessed/reset in + // SelectCore + _columnsOutsideAggregate [][2]string + // inOrdering is true if we are in an ordering clause + _inOrdering bool + // result is the result of a query. It is only set when analyzing the ordering clause + _result []*Attribute +} + +func newSQLContext() sqlContext { + return sqlContext{ + joinedTables: make(map[string]*types.Table), + } +} + +// setTempValuesToZero resets all temp values to their zero values. +func (s *sqlContext) setTempValuesToZero() { + s._inAggregate = false + s._containsAggregate = false + s._columnInAggregate = nil + s._columnsOutsideAggregate = nil + s._inOrdering = false + s._result = nil +} + +// copy copies the sqlContext. +// it does not copy the outer scope. +func (c *sqlContext) copy() sqlContext { + joinedRelations := make([]*Relation, len(c.joinedRelations)) + for i, r := range c.joinedRelations { + joinedRelations[i] = r.Copy() + } + + outerRelations := make([]*Relation, len(c.outerRelations)) + for i, r := range c.outerRelations { + outerRelations[i] = r.Copy() + } + + // ctes don't need to be copied right now since they are not modified. + colsOutsideAgg := make([][2]string, len(c._columnsOutsideAggregate)) + copy(colsOutsideAgg, c._columnsOutsideAggregate) + + return sqlContext{ + joinedRelations: joinedRelations, + outerRelations: outerRelations, + ctes: c.ctes, + joinedTables: c.joinedTables, + } +} + +// joinRelation adds a relation to the context. +func (c *sqlContext) joinRelation(r *Relation) error { + // check if the relation is already joined + _, ok := c.getJoinedRelation(r.Name) + if ok { + return ErrTableAlreadyJoined + } + + c.joinedRelations = append(c.joinedRelations, r) + return nil +} + +// join joins a table. It will return an error if the table is already joined. +func (c *sqlContext) join(name string, t *types.Table) error { + _, ok := c.joinedTables[name] + if ok { + return ErrTableAlreadyJoined + } + + c.joinedTables[name] = t + return nil +} + +// getJoinedRelation returns the relation with the given name. +func (c *sqlContext) getJoinedRelation(name string) (*Relation, bool) { + for _, r := range c.joinedRelations { + if r.Name == name { + return r, true + } + } + + return nil, false +} + +// getOuterRelation returns the relation with the given name. +func (c *sqlContext) getOuterRelation(name string) (*Relation, bool) { + for _, r := range c.outerRelations { + if r.Name == name { + return r, true + } + } + + return nil, false +} + +// the following special table names track table names that mean something in the context of the SQL statement. +const ( + tableExcluded = "excluded" +) + +// findAttribute searches for a attribute in the specified relation. +// if the relation is empty, it will search all joined relations. +// It does NOT search the outer relations unless specifically specified; +// this matches Postgres' behavior. +// If the relation is empty and many columns are found, it will return an error. +// It returns both an error and an error message in case of an error. +// This is because it is meant to pass errors back to the error listener. +func (c *sqlContext) findAttribute(relation string, column string) (relName string, attr *Attribute, msg string, err error) { + if relation == "" { + foundAttrs := make([]*Attribute, 0) + + for _, r := range c.joinedRelations { + for _, a := range r.Attributes { + if a.Name == column { + relName = r.Name + foundAttrs = append(foundAttrs, a) + } + } + } + + switch len(foundAttrs) { + case 0: + return "", nil, column, ErrUnknownColumn + case 1: + return relName, foundAttrs[0], "", nil + default: + return "", nil, column, ErrAmbiguousColumn + } + } + + // if referencing excluded, we should instead look at the target table, + // since the excluded data will always match the failed insert. + if relation == tableExcluded { + // excluded can only be used in an ON CONFLICT clause + if !c.inConflict { + return "", nil, relation, fmt.Errorf("%w: excluded table can only be used in an ON CONFLICT clause", ErrInvalidExcludedTable) + } + relation = c.targetTable + } + + r, ok := c.getJoinedRelation(relation) + if !ok { + r, ok = c.getOuterRelation(relation) + if !ok { + return "", nil, relation, ErrUnknownTable + } + } + + for _, a := range r.Attributes { + if a.Name == column { + return r.Name, a, "", nil + } + } + + return "", nil, relation + "." + column, ErrUnknownColumn +} + +// scope moves the current scope to outer scope, +// and sets the current scope to a new scope. +func (c *sqlContext) scope() { + c2 := &sqlContext{ + joinedRelations: make([]*Relation, len(c.joinedRelations)), + outerRelations: make([]*Relation, len(c.outerRelations)), + joinedTables: make(map[string]*types.Table), + // we do not need to copy ctes since they are not ever modified. + targetTable: c.targetTable, + isAction: c.isAction, + inConflict: c.inConflict, + inSelect: c.inSelect, + hasAnonymousTable: c.hasAnonymousTable, + } + // copy all non-temp values + for i, r := range c.outerRelations { + c2.outerRelations[i] = r.Copy() + } + + for i, r := range c.joinedRelations { + c2.joinedRelations[i] = r.Copy() + } + + for k, t := range c.joinedTables { + c2.joinedTables[k] = t.Copy() + } + + // move joined relations to the outside + c.outerRelations = append(c.outerRelations, c.joinedRelations...) + + // zero everything else + c.joinedRelations = nil + c.joinedTables = make(map[string]*types.Table) + c.setTempValuesToZero() + + // we do NOT change the inAction, inConflict, or targetTable values, + // since these apply in all nested scopes. + + // we do not alter inSelect, but we do alter hasAnonymousTable. + c2.hasAnonymousTable = false + + c2.outerScope = c.outerScope + c.outerScope = c2 +} + +// popScope moves the current scope to the outer scope. +func (c *sqlContext) popScope() { + *c = *c.outerScope +} + +/* + this visitor breaks down nodes into 4 different types: + - Expressions: expressions simply return *Attribute. The name on all of these will be empty UNLESS it is a column reference. + - CommonTableExpressions: the only node that can directly add tables to outerRelations slice. + +*/ + +// sqlAnalyzer visits SQL nodes and analyzes them. +type sqlAnalyzer struct { + UnimplementedSqlVisitor + blockContext + sqlCtx sqlContext + sqlResult sqlAnalyzeResult +} + +// reset resets the sqlAnalyzer. +func (s *sqlAnalyzer) reset() { + // we don't need to touch the block context, since it does not change here. + s.sqlCtx = newSQLContext() + s.sqlResult = sqlAnalyzeResult{} +} + +type sqlAnalyzeResult struct { + Mutative bool +} + +// startSQLAnalyze initializes all fields of the sqlAnalyzer. +func (s *sqlAnalyzer) startSQLAnalyze() { + s.sqlCtx = sqlContext{ + joinedTables: make(map[string]*types.Table), + } +} + +// endSQLAnalyze is called at the end of the analysis. +func (s *sqlAnalyzer) endSQLAnalyze() *sqlAnalyzeResult { + res := s.sqlResult + s.sqlCtx = sqlContext{} + return &res +} + +var _ Visitor = (*sqlAnalyzer)(nil) + +// typeErr should be used when a type error is encountered. +// It returns an unknown attribute and adds an error to the error listener. +func (s *sqlAnalyzer) typeErr(node Node, t1, t2 *types.DataType) *types.DataType { + s.errs.AddErr(node, ErrType, fmt.Sprintf("%s != %s", t1.String(), t2.String())) + return cast(node, types.UnknownType) +} + +// expect is a helper function that expects a certain type, and adds an error if it is not found. +func (s *sqlAnalyzer) expect(node Node, t *types.DataType, expected *types.DataType) { + if !t.Equals(expected) { + s.errs.AddErr(node, ErrType, fmt.Sprintf("expected %s, received %s", expected.String(), t.String())) + } +} + +// expectedNumeric is a helper function that expects a numeric type, and adds an error if it is not found. +func (s *sqlAnalyzer) expectedNumeric(node Node, t *types.DataType) { + if !t.IsNumeric() { + s.errs.AddErr(node, ErrType, fmt.Sprintf("expected numeric type, received %s", t.String())) + } +} + +// expressionTypeErr should be used if we expect an expression to return a *types.DataType, +// but it returns something else. It will attempt to read the actual type and create an error +// message that is helpful for the end user. +func (s *sqlAnalyzer) expressionTypeErr(e Expression) *types.DataType { + // if expression is a receiver from a loop, it will be a map + _, ok := e.Accept(s).(map[string]*types.DataType) + if ok { + s.errs.AddErr(e, ErrType, "invalid usage of compound type, expected scalar value") + return cast(e, types.UnknownType) + } + + // if expression is a procedure call that returns a table, it will be a slice of attributes + _, ok = e.Accept(s).([]*Attribute) + if ok { + s.errs.AddErr(e, ErrType, "procedure returns table, not a scalar value") + return cast(e, types.UnknownType) + } + + // if it is a procedure call that returns many values, it will be a slice of data types + vals, ok := e.Accept(s).([]*types.DataType) + if ok { + s.errs.AddErr(e, ErrType, "expected procedure to return a single value, returns %d", len(vals)) + return cast(e, types.UnknownType) + + } + + s.errs.AddErr(e, ErrType, "could not infer expected type") + return cast(e, types.UnknownType) +} + +// cast will return the type case if one exists. If not, it will simply +// return the passed type. +func cast(castable any, fallback *types.DataType) *types.DataType { + if castable == nil { + return fallback + } + + c, ok := castable.(interface{ GetTypeCast() *types.DataType }) + if !ok { + return fallback + } + + if c.GetTypeCast() == nil { + return fallback + } + + return c.GetTypeCast() +} + +func (s *sqlAnalyzer) VisitExpressionLiteral(p0 *ExpressionLiteral) any { + return cast(p0, p0.Type) +} + +func (s *sqlAnalyzer) VisitExpressionFunctionCall(p0 *ExpressionFunctionCall) any { + // function call should either be against a known function, or a procedure. + fn, ok := Functions[p0.Name] + if !ok { + // if not found, it might be a schema procedure. + proc, found := s.schema.FindProcedure(p0.Name) + if !found { + s.errs.AddErr(p0, ErrUnknownFunctionOrProcedure, p0.Name) + return cast(p0, types.UnknownType) + } + + if !proc.IsView() { + s.sqlResult.Mutative = true + } + + // if it is a procedure, it cannot use distinct or * + if p0.Distinct { + s.errs.AddErr(p0, ErrFunctionSignature, "cannot use DISTINCT when calling procedure %s", p0.Name) + return cast(p0, types.UnknownType) + } + if p0.Star { + s.errs.AddErr(p0, ErrFunctionSignature, "cannot use * when calling procedure %s", p0.Name) + return cast(p0, types.UnknownType) + } + + // verify the inputs + if len(p0.Args) != len(proc.Parameters) { + s.errs.AddErr(p0, ErrFunctionSignature, "expected %d arguments, received %d", len(proc.Parameters), len(p0.Args)) + return cast(p0, types.UnknownType) + } + + for i, arg := range p0.Args { + dt, ok := arg.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(arg) + } + + if !dt.Equals(proc.Parameters[i].Type) { + return s.typeErr(arg, dt, proc.Parameters[i].Type) + } + } + + return s.returnProcedureReturnExpr(p0, p0.Name, proc.Returns) + } + + if s.sqlCtx._inOrdering && s.sqlCtx._inAggregate { + s.errs.AddErr(p0, ErrOrdering, "cannot use aggregate functions in ORDER BY clause") + return cast(p0, types.UnknownType) + } + + // the function is a built in function. If using DISTINCT, it needs to be an aggregate + // if using *, it needs to support it. + if p0.Distinct && !fn.IsAggregate { + s.errs.AddErr(p0, ErrFunctionSignature, "DISTINCT can only be used with aggregate functions") + return cast(p0, types.UnknownType) + } + + if fn.IsAggregate { + s.sqlCtx._inAggregate = true + s.sqlCtx._containsAggregate = true + defer func() { s.sqlCtx._inAggregate = false }() + } + + // if the function is called with *, we need to ensure it supports it. + // If not, then we validate all args and return the type. + var returnType *types.DataType + if p0.Star { + if fn.StarArgReturn == nil { + s.errs.AddErr(p0, ErrFunctionSignature, "function does not support *") + return cast(p0, types.UnknownType) + } + + // if calling with *, it must have no args + if len(p0.Args) != 0 { + s.errs.AddErr(p0, ErrFunctionSignature, "function does not accept arguments when using *") + return cast(p0, types.UnknownType) + } + + returnType = fn.StarArgReturn + } else { + argTyps := make([]*types.DataType, len(p0.Args)) + for i, arg := range p0.Args { + dt, ok := arg.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(arg) + } + + argTyps[i] = dt + } + + var err error + returnType, err = fn.ValidateArgs(argTyps) + if err != nil { + s.errs.AddErr(p0, ErrFunctionSignature, err.Error()) + return cast(p0, types.UnknownType) + } + } + + return cast(p0, returnType) +} + +func (s *sqlAnalyzer) VisitExpressionForeignCall(p0 *ExpressionForeignCall) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrFunctionSignature, "foreign calls are not supported in in-line action statements") + } + + // foreign call must be defined as a foreign procedure + proc, found := s.schema.FindForeignProcedure(p0.Name) + if !found { + s.errs.AddErr(p0, ErrUnknownFunctionOrProcedure, p0.Name) + return cast(p0, types.UnknownType) + } + + if len(p0.ContextualArgs) != 2 { + s.errs.AddErr(p0, ErrFunctionSignature, "expected 2 contextual arguments, received %d", len(p0.ContextualArgs)) + return cast(p0, types.UnknownType) + } + + // contextual args have to be strings + for _, ctxArgs := range p0.ContextualArgs { + dt, ok := ctxArgs.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(ctxArgs) + } + + s.expect(ctxArgs, dt, types.TextType) + } + + // verify the inputs + if len(p0.Args) != len(proc.Parameters) { + s.errs.AddErr(p0, ErrFunctionSignature, "expected %d arguments, received %d", len(proc.Parameters), len(p0.Args)) + return cast(p0, types.UnknownType) + } + + for i, arg := range p0.Args { + dt, ok := arg.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(arg) + } + + if !dt.Equals(proc.Parameters[i]) { + return s.typeErr(arg, dt, proc.Parameters[i]) + } + } + + return s.returnProcedureReturnExpr(p0, p0.Name, proc.Returns) +} + +// returnProcedureReturnExpr handles a procedure return used as an expression return. It mandates +// that the procedure returns a single value, or a table. +func (s *sqlAnalyzer) returnProcedureReturnExpr(p0 ExpressionCall, procedureName string, ret *types.ProcedureReturn) any { + // if an expression calls a function, it should return exactly one value or a table. + if ret == nil { + if p0.GetTypeCast() != nil { + s.errs.AddErr(p0, ErrType, "cannot typecast procedure %s because does not return a value", procedureName) + } + return types.NullType + } + + // if it returns a table, we need to return it as a set of attributes. + if ret.IsTable { + attrs := make([]*Attribute, len(ret.Fields)) + for i, f := range ret.Fields { + attrs[i] = &Attribute{ + Name: f.Name, + Type: f.Type, + } + } + + return attrs + } + + switch len(ret.Fields) { + case 0: + s.errs.AddErr(p0, ErrFunctionSignature, "procedure %s does not return a value", procedureName) + return cast(p0, types.UnknownType) + case 1: + return cast(p0, ret.Fields[0].Type) + default: + if p0.GetTypeCast() != nil { + s.errs.AddErr(p0, ErrType, "cannot type cast multiple return values") + } + + retVals := make([]*types.DataType, len(ret.Fields)) + for i, f := range ret.Fields { + retVals[i] = f.Type.Copy() + } + + return retVals + } +} + +func (s *sqlAnalyzer) VisitExpressionVariable(p0 *ExpressionVariable) any { + dt, ok := s.blockContext.variables[p0.String()] + if !ok { + // if not found, it could be an anonymous variable. + anonVar, ok := s.blockContext.anonymousVariables[p0.String()] + if ok { + // if it is anonymous, we cannot type cast, since it is a compound type. + if p0.GetTypeCast() != nil { + s.errs.AddErr(p0, ErrType, "cannot type cast compound variable") + } + + return anonVar + } + + // if not found, then var does not exist. + s.errs.AddErr(p0, ErrUndeclaredVariable, p0.String()) + return cast(p0, types.UnknownType) + } + + return cast(p0, dt) +} + +func (s *sqlAnalyzer) VisitExpressionArrayAccess(p0 *ExpressionArrayAccess) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "array access is not supported in in-line action statements") + } + + idxAttr, ok := p0.Index.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Index) + } + if !idxAttr.Equals(types.IntType) { + return s.typeErr(p0.Index, idxAttr, types.IntType) + } + + arrAttr, ok := p0.Array.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Array) + } + + if !arrAttr.IsArray { + s.errs.AddErr(p0.Array, ErrType, "expected array") + return cast(p0, types.UnknownType) + } + + return cast(p0, &types.DataType{ + Name: arrAttr.Name, + Metadata: arrAttr.Metadata, + // leave IsArray as false since we are accessing an element. + }) +} + +func (s *sqlAnalyzer) VisitExpressionMakeArray(p0 *ExpressionMakeArray) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "array instantiation is not supported in in-line action statements") + } + + if len(p0.Values) == 0 { + s.errs.AddErr(p0, ErrAssignment, "array instantiation must have at least one element") + return cast(p0, types.UnknownType) + } + + first, ok := p0.Values[0].Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Values[0]) + } + + for _, v := range p0.Values { + typ, ok := v.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(v) + } + + if !typ.Equals(first) { + return s.typeErr(v, typ, first) + } + } + + return cast(p0, &types.DataType{ + Name: first.Name, + Metadata: first.Metadata, + IsArray: true, + }) +} + +func (s *sqlAnalyzer) VisitExpressionFieldAccess(p0 *ExpressionFieldAccess) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "field access is not supported in in-line action statements") + } + + // field access needs to be accessing a compound type. + // currently, compound types can only be anonymous variables declared + // as loop receivers. + anonType, ok := p0.Record.Accept(s).(map[string]*types.DataType) + if !ok { + s.errs.AddErr(p0.Record, ErrType, "cannot access field on non-compound type") + return cast(p0, types.UnknownType) + } + + dt, ok := anonType[p0.Field] + if !ok { + s.errs.AddErr(p0, ErrType, fmt.Sprintf("unknown field %s", p0.Field)) + return cast(p0, types.UnknownType) + } + + return cast(p0, dt) +} + +func (s *sqlAnalyzer) VisitExpressionParenthesized(p0 *ExpressionParenthesized) any { + dt, ok := p0.Inner.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Inner) + } + + return cast(p0, dt) +} + +func (s *sqlAnalyzer) VisitExpressionComparison(p0 *ExpressionComparison) any { + left, ok := p0.Left.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Left) + } + + right, ok := p0.Right.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Right) + } + + if !left.Equals(right) { + return s.typeErr(p0.Right, right, left) + } + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionLogical(p0 *ExpressionLogical) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "logical expressions are not supported in in-line action statements") + } + + left, ok := p0.Left.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Left) + } + + right, ok := p0.Right.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Right) + } + + if !left.Equals(types.BoolType) { + return s.typeErr(p0.Left, left, types.BoolType) + } + + if !right.Equals(types.BoolType) { + return s.typeErr(p0.Right, right, types.BoolType) + } + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionArithmetic(p0 *ExpressionArithmetic) any { + left, ok := p0.Left.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Left) + } + + right, ok := p0.Right.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Right) + } + + if !left.Equals(right) { + return s.typeErr(p0.Right, right, left) + } + + // both must be numeric UNLESS it is a concat + if p0.Operator == ArithmeticOperatorConcat { + s.expect(p0.Left, left, types.TextType) + } else { + s.expectedNumeric(p0.Left, left) + } + + return cast(p0, left) +} + +func (s *sqlAnalyzer) VisitExpressionUnary(p0 *ExpressionUnary) any { + e, ok := p0.Expression.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Expression) + } + + switch p0.Operator { + default: + panic("unknown unary operator") + case UnaryOperatorPos: + s.expectedNumeric(p0.Expression, e) + case UnaryOperatorNeg: + s.expectedNumeric(p0.Expression, e) + + if e.Equals(types.Uint256Type) { + s.errs.AddErr(p0.Expression, ErrType, "cannot negate uint256") + return cast(p0, types.UnknownType) + } + case UnaryOperatorNot: + s.expect(p0.Expression, e, types.BoolType) + } + + return cast(p0, e) +} + +func (s *sqlAnalyzer) VisitExpressionColumn(p0 *ExpressionColumn) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "column references are not supported in in-line action statements") + } + + // there is a special case, where if we are within an ORDER BY clause, + // we can access columns in the result set. We should search that first + // before searching all joined tables, as result set columns with conflicting + // names are given precedence over joined tables. + if s.sqlCtx._inOrdering && p0.Table == "" { + attr := findAttribute(s.sqlCtx._result, p0.Column) + // short-circuit if we find the column, otherwise proceed to normal search + if attr != nil { + return cast(p0, attr.Type) + } + } + + // if we are in an upsert and the column references a column name in the target table + // AND the table is not specified, we need to throw an ambiguity error. For conflict tables, + // the user HAS to specify whether the upsert value is from the existing table or excluded table. + if s.sqlCtx.inConflict && p0.Table == "" { + mainTbl, ok := s.sqlCtx.joinedTables[s.sqlCtx.targetTable] + // if not ok, then we are in a subquery or something else, and we can ignore this check. + if ok { + if _, ok = mainTbl.FindColumn(p0.Column); ok { + s.errs.AddErr(p0, ErrAmbiguousConflictTable, `upsert value is ambigous. specify whether the column is from "%s" or "%s"`, s.sqlCtx.targetTable, tableExcluded) + return cast(p0, types.UnknownType) + + } + } + } + + // findColumn accounts for empty tables in search, so we do not have to + // worry about it being qualified or not. + relName, col, msg, err := s.sqlCtx.findAttribute(p0.Table, p0.Column) + if err != nil { + s.errs.AddErr(p0, err, msg) + return cast(p0, types.UnknownType) + } + + if s.sqlCtx._inAggregate { + if s.sqlCtx._columnInAggregate != nil { + s.errs.AddErr(p0, ErrAggregate, "cannot use multiple columns in aggregate function args") + return cast(p0, types.UnknownType) + } + + s.sqlCtx._columnInAggregate = &[2]string{relName, col.Name} + } else { + s.sqlCtx._columnsOutsideAggregate = append(s.sqlCtx._columnsOutsideAggregate, [2]string{relName, col.Name}) + } + + return cast(p0, col.Type) +} + +var supportedCollations = map[string]struct{}{ + "nocase": {}, +} + +func (s *sqlAnalyzer) VisitExpressionCollate(p0 *ExpressionCollate) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "collate is not supported in in-line action statements") + } + + e, ok := p0.Expression.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Expression) + } + + if !e.Equals(types.TextType) { + return s.typeErr(p0.Expression, e, types.TextType) + } + + _, ok = supportedCollations[p0.Collation] + if !ok { + s.errs.AddErr(p0, ErrCollation, `unsupported collation "%s"`, p0.Collation) + } + + return cast(p0, e) +} + +func (s *sqlAnalyzer) VisitExpressionStringComparison(p0 *ExpressionStringComparison) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "string comparison is not supported in in-line action statements") + } + + left, ok := p0.Left.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Left) + } + + right, ok := p0.Right.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Right) + } + + if !left.Equals(types.TextType) { + return s.typeErr(p0.Left, left, types.TextType) + } + + if !right.Equals(types.TextType) { + return s.typeErr(p0.Right, right, types.TextType) + } + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionIs(p0 *ExpressionIs) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "IS expression is not supported in in-line action statements") + } + + left, ok := p0.Left.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Left) + } + + right, ok := p0.Right.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Right) + } + + // right has to be null, unless distinct is true. If distinct is true, + // then left and right must be the same type + if p0.Distinct { + if !left.Equals(right) { + return s.typeErr(p0.Right, right, left) + } + } else { + if !right.Equals(types.NullType) { + return s.typeErr(p0.Right, right, types.NullType) + } + } + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionIn(p0 *ExpressionIn) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "IN expression is not supported in in-line action statements") + } + + exprType, ok := p0.Expression.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Expression) + } + + switch { + case len(p0.List) > 0: + for _, e := range p0.List { + dt, ok := e.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(e) + } + + if !dt.Equals(exprType) { + return s.typeErr(e, dt, exprType) + } + } + case p0.Subquery != nil: + rel, ok := p0.Subquery.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + if len(rel) != 1 { + s.errs.AddErr(p0.Subquery, ErrResultShape, "subquery expressions must return exactly 1 column, received %d", len(rel)) + return cast(p0, types.UnknownType) + } + + if !rel[0].Type.Equals(exprType) { + return s.typeErr(p0.Subquery, rel[0].Type, exprType) + } + default: + panic("list or subquery must be set for in expression") + } + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionBetween(p0 *ExpressionBetween) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "BETWEEN expression is not supported in in-line action statements") + } + + between, ok := p0.Expression.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Expression) + } + + lower, ok := p0.Lower.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Lower) + } + + upper, ok := p0.Upper.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Upper) + } + + if !between.Equals(lower) { + return s.typeErr(p0.Lower, lower, between) + } + + if !between.Equals(upper) { + return s.typeErr(p0.Upper, upper, between) + } + + s.expectedNumeric(p0.Expression, between) + + return cast(p0, types.BoolType) +} + +func (s *sqlAnalyzer) VisitExpressionSubquery(p0 *ExpressionSubquery) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "subquery is not supported in in-line action statements") + } + + // subquery should return a table + rel, ok := p0.Subquery.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + if len(rel) != 1 { + s.errs.AddErr(p0, ErrResultShape, "subquery expressions must return exactly 1 column, received %d", len(rel)) + return cast(p0, types.UnknownType) + } + + if p0.Exists { + if p0.GetTypeCast() != nil { + s.errs.AddErr(p0, ErrType, "cannot type cast subquery with EXISTS") + } + return types.BoolType + } + + return cast(p0, rel[0].Type) +} + +func (s *sqlAnalyzer) VisitExpressionCase(p0 *ExpressionCase) any { + if s.sqlCtx.isAction { + s.errs.AddErr(p0, ErrAssignment, "CASE expression is not supported in in-line action statements") + } + + // all whens in a case statement must be bool, unless there is an expression + // that occurs after CASE. In that case, whens all must match the case expression type. + expectedWhenType := types.BoolType + if p0.Case != nil { + caseType, ok := p0.Case.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Case) + } + + expectedWhenType = caseType + } + + // all thens and else must return the same type. + var returnType *types.DataType + for _, w := range p0.WhenThen { + when, ok := w[0].Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(w[0]) + } + + if !when.Equals(expectedWhenType) { + return s.typeErr(w[0], when, expectedWhenType) + } + + then, ok := w[1].Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(w[1]) + } + + // if return type is not set, set it to the first then + if returnType == nil { + returnType = then + } + // if the return type is of type null, we should keep trying + // to reset until we get a non-null type + if returnType.EqualsStrict(types.NullType) { + returnType = then + } + + if !then.Equals(returnType) { + return s.typeErr(w[1], then, returnType) + } + } + + if p0.Else != nil { + elseType, ok := p0.Else.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Else) + } + + if returnType != nil && !elseType.Equals(returnType) { + return s.typeErr(p0.Else, elseType, returnType) + } + } + + return cast(p0, returnType) +} + +// The below methods are responsible for manipulating the sql context and identifying +// the resulting relations. + +func (s *sqlAnalyzer) VisitCommonTableExpression(p0 *CommonTableExpression) any { + // check that the table does not already exist + _, ok := s.sqlCtx.getOuterRelation(p0.Name) + if ok { + s.errs.AddErr(p0, ErrTableAlreadyExists, p0.Name) + return nil + } + + _, ok = s.schema.FindTable(p0.Name) + if ok { + s.errs.AddErr(p0, ErrTableAlreadyExists, p0.Name) + return nil + } + + rel, ok := p0.Query.Accept(s).([]*Attribute) + if !ok { + // panic because it is an internal error. + // I guess we could just let it panic without ok, + // but this is more descriptive. + panic("expected query to return attributes") + } + + if len(p0.Columns) != len(rel) { + s.errs.AddErr(p0, ErrResultShape, "expected %d columns, received %d", len(p0.Columns), len(rel)) + return nil + } + + // rename the columns and add the relation to the outer scope + for i, col := range p0.Columns { + rel[i].Name = col + } + + s.sqlCtx.outerRelations = append(s.sqlCtx.outerRelations, &Relation{ + Name: p0.Name, + Attributes: rel, + }) + + return nil +} + +func (s *sqlAnalyzer) VisitSQLStatement(p0 *SQLStatement) any { + for _, cte := range p0.CTEs { + cte.Accept(s) + } + + rel, ok := p0.SQL.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + return rel +} + +func (s *sqlAnalyzer) VisitSelectStatement(p0 *SelectStatement) any { + // for each subquery, we need to create a new scope. + s.sqlCtx.inSelect = true + + // all select cores will need their own scope. They all also need to have the + // same shape as each other + s.sqlCtx.scope() + rel1, ok := p0.SelectCores[0].Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + // keep the rel1 scope as we may need to reference the joined + // tables later. + rel1Scope := s.sqlCtx.copy() + s.sqlCtx.popScope() + + isCompound := false + compoundHasGroupBy := false + // we visit the rest of the select cores to check the shape + for _, core := range p0.SelectCores[1:] { + isCompound = true + if core.GroupBy != nil { + compoundHasGroupBy = true + } + + s.sqlCtx.scope() + rel2, ok := core.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + s.sqlCtx.popScope() + + if !ShapesMatch(rel1, rel2) { + s.errs.AddErr(core, ErrResultShape, "expected shape to match previous select core") + return rel1 + } + } + + // If it is not a compound select, we should use the scope from the first select core, + // so that we can analyze joined tables in the order and limit clauses. It if is a compound + // select, then we should flatten all joined tables into a single anonymous table. This can + // then be referenced in order bys and limits. If there are column conflicts in the flattened column, + // we should return an error, since there will be no way for us to inform postgres of our default ordering. + if isCompound { + // if compound, flatten + flattened, conflictCol, err := Flatten(rel1Scope.joinedRelations...) + if err != nil { + s.errs.AddErr(p0, err, conflictCol) + return rel1 + } + + // we can simply assign this to the rel1Scope, since we we will not + // need it past this point. We can add it as an unnamed relation. + rel1Scope.joinedRelations = []*Relation{{Attributes: flattened}} + + // if a compound select, then we have the following default ordering rules: + // 1. All columns returned will be ordered in the order they are returned. + // 2. If the statement includes a group by in one of the select cores, then + // we throw an error. This is a relic of SQLite's rudimentary referencing, however + // since it is such an uncommon query anyways, we have decided to not support it + // until we have time for more testing. + if compoundHasGroupBy || p0.SelectCores[0].GroupBy != nil { + s.errs.AddErr(p0, ErrAggregate, "cannot use group by in compound select") + return rel1 + } + + // order all flattened returns + for _, attr := range flattened { + p0.Ordering = append(p0.Ordering, &OrderingTerm{ + Expression: &ExpressionColumn{ + // leave column blank, since we are referencing a column that no + // longer knows what table it is from due to the compound. + Column: attr.Name, + }, + }) + } + } else { + // if it is not a compound, then we apply the following default ordering rules (after the user defined): + // 1. Each primary key for each schema table joined is ordered in ascending order. + // The tables and columns for all joined tables will be sorted alphabetically. + // If table aliases are used, they will be used instead of the name. + // 2. If the select core contains DISTINCT, then the above does not apply, and + // we order by all columns returned, in the order they are returned. + // 3. If there is a group by clause, none of the above apply, and instead we order by + // all columns specified in the group by. + if p0.SelectCores[0].GroupBy != nil { + // reset and visit the group by to get the columns + var colsToOrder [][2]string + for _, g := range p0.SelectCores[0].GroupBy { + s.sqlCtx.setTempValuesToZero() + g.Accept(s) + + if len(s.sqlCtx._columnsOutsideAggregate) > 1 { + s.errs.AddErr(g, ErrAggregate, "cannot use multiple columns in group by") + return rel1 + } + + colsToOrder = append(colsToOrder, s.sqlCtx._columnsOutsideAggregate...) + } + + // order the columns + for _, col := range colsToOrder { + p0.Ordering = append(p0.Ordering, &OrderingTerm{ + Expression: &ExpressionColumn{ + Table: col[0], + Column: col[1], + }, + }) + } + } else if p0.SelectCores[0].Distinct { + // if distinct, order by all columns returned + for _, attr := range rel1 { + p0.Ordering = append(p0.Ordering, &OrderingTerm{ + Expression: &ExpressionColumn{ + Table: "", + Column: attr.Name, + }, + }) + } + } else { + // if not distinct, order by primary keys in all joined tables + for _, tbl := range order.OrderMap(rel1Scope.joinedTables) { + pks, err := tbl.Value.GetPrimaryKey() + if err != nil { + s.errs.AddErr(p0, err, "could not get primary key for table %s", tbl.Key) + } + + for _, pk := range pks { + p0.Ordering = append(p0.Ordering, &OrderingTerm{ + Expression: &ExpressionColumn{ + Table: tbl.Key, + Column: pk, + }, + }) + } + } + } + } + + oldScope := s.sqlCtx + s.sqlCtx = rel1Scope + defer func() { s.sqlCtx = oldScope }() + + // we need to inform the analyzer that we are in ordering + s.sqlCtx._inOrdering = true + s.sqlCtx._result = rel1 + + // analyze the ordering, limit, and offset + for _, o := range p0.Ordering { + o.Accept(s) + } + + // unset the ordering context + s.sqlCtx._inOrdering = false + s.sqlCtx._result = nil + + if p0.Limit != nil { + dt, ok := p0.Limit.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.Limit) + return rel1 + } + + s.expectedNumeric(p0.Limit, dt) + } + + if p0.Offset != nil { + dt, ok := p0.Offset.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.Offset) + return rel1 + } + + s.expectedNumeric(p0.Offset, dt) + + } + + return rel1 +} + +// There are some rules for select cores that are necessary for non-determinism: +// 1. If a SELECT is DISTINCT and contains a GROUP BY, we return an error since we cannot +// order it. +// 2. If a result column uses an aggregate function AND there is no GROUP BY, then all +// result columns must be aggregate functions if they reference a column in a table. +// 3. If there is a GROUP BY, then all result columns must be aggregate functions UNLESS +// the column is specified in the GROUP BY +func (s *sqlAnalyzer) VisitSelectCore(p0 *SelectCore) any { + // we first need to visit the from and join in order to join + // all tables to the context. + // we will visit columns last since it will determine our return type. + if p0.From != nil { + p0.From.Accept(s) + for _, j := range p0.Joins { + j.Accept(s) + } + } + + if p0.Where != nil { + s.sqlCtx.setTempValuesToZero() + whereType, ok := p0.Where.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Where) + } + + // if it contains an aggregate, throw an error + if s.sqlCtx._containsAggregate { + s.errs.AddErr(p0.Where, ErrAggregate, "cannot use aggregate function in WHERE") + return []*Attribute{} + } + + s.expect(p0.Where, whereType, types.BoolType) + } + + hasGroupBy := false + // colsInGroupBy tracks the table and column names that are in the group by. + colsInGroupBy := make(map[[2]string]struct{}) + for _, g := range p0.GroupBy { + hasGroupBy = true + + // we need to get all columns used in the group by. + // If more than one column is used per group by, or if an aggregate is + // used, we return an error. + s.sqlCtx.setTempValuesToZero() + + // group by return type is not important + g.Accept(s) + + if s.sqlCtx._containsAggregate { + s.errs.AddErr(g, ErrAggregate, "cannot use aggregate function in group by") + return []*Attribute{} + } + if len(s.sqlCtx._columnsOutsideAggregate) != 1 { + s.errs.AddErr(g, ErrAggregate, "group by must reference exactly one column") + return []*Attribute{} + } + + _, ok := colsInGroupBy[s.sqlCtx._columnsOutsideAggregate[0]] + if ok { + s.errs.AddErr(g, ErrAggregate, "cannot use column in group by more than once") + return []*Attribute{} + } + colsInGroupBy[s.sqlCtx._columnsOutsideAggregate[0]] = struct{}{} + + if p0.Having != nil { + s.sqlCtx.setTempValuesToZero() + havingType, ok := p0.Having.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Having) + } + + // columns in having must be in the group by if not in aggregate + for _, col := range s.sqlCtx._columnsOutsideAggregate { + if _, ok := colsInGroupBy[col]; !ok { + s.errs.AddErr(p0.Having, ErrAggregate, "column used in having must be in group by") + } + } + + if s.sqlCtx._columnInAggregate != nil { + if _, ok := colsInGroupBy[*s.sqlCtx._columnInAggregate]; !ok { + s.errs.AddErr(p0.Having, ErrAggregate, "cannot use column in aggregate if not in group by") + } + } + + s.expect(p0.Having, havingType, types.BoolType) + } + } + + if hasGroupBy && p0.Distinct { + s.errs.AddErr(p0, ErrAggregate, "cannot use DISTINCT with GROUP BY") + return []*Attribute{} + } + + var res []*Attribute + for _, c := range p0.Columns { + // for each result column, we need to check that: + // IF THERE IS A GROUP BY: + // 1. if it is an aggregate, then its column is not in the group by + // 2. for any column that occurs outside of an aggregate, it is also in the group by + // IF THERE IS NOT A GROUP BY: + // 3. if there is an aggregate, then it can be the only return column + + // reset to be sure + s.sqlCtx.setTempValuesToZero() + + attrs, ok := c.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + if !hasGroupBy && s.sqlCtx._containsAggregate { + if len(p0.Columns) != 1 { + s.errs.AddErr(c, ErrAggregate, "cannot return multiple values in SELECT that uses aggregate function and no group by") + } + } else if hasGroupBy { + // if column used in aggregate, ensure it is not in group by + if s.sqlCtx._columnInAggregate != nil { + if _, ok := colsInGroupBy[*s.sqlCtx._columnInAggregate]; ok { + s.errs.AddErr(c, ErrAggregate, "cannot use column in aggregate function and in group by") + } + } + + // ensure all columns used outside aggregate are in group by + for _, col := range s.sqlCtx._columnsOutsideAggregate { + if _, ok := colsInGroupBy[col]; !ok { + s.errs.AddErr(c, ErrAggregate, "column used outside aggregate must be included in group by") + } + } + } + + var amiguousCol string + var err error + res, amiguousCol, err = Coalesce(append(res, attrs...)...) + if err != nil { + s.errs.AddErr(c, err, amiguousCol) + return res + } + } + + return res +} + +func (s *sqlAnalyzer) VisitRelationTable(p0 *RelationTable) any { + if s.sqlCtx.hasAnonymousTable { + s.errs.AddErr(p0, ErrUnnamedJoin, "statement uses an unnamed subquery or procedure join. to join another table, alias the subquery or procedure") + return []*Attribute{} + } + + // table must either be a common table expression, or a table in the schema. + var rel *Relation + tbl, ok := s.schema.FindTable(p0.Table) + if !ok { + cte, ok := s.sqlCtx.getOuterRelation(p0.Table) + if !ok { + s.errs.AddErr(p0, ErrUnknownTable, p0.Table) + return []*Attribute{} + } + + rel = cte.Copy() + } else { + var err error + rel, err = tableToRelation(tbl) + if err != nil { + s.errs.AddErr(p0, err, "table: %s", p0.Table) + return []*Attribute{} + } + + // since we have joined a new table, we need to add it to the joined tables. + name := p0.Table + if p0.Alias != "" { + name = p0.Alias + } + + err = s.sqlCtx.join(name, tbl) + if err != nil { + s.errs.AddErr(p0, err, name) + return []*Attribute{} + } + } + + // if there is an alias, we rename the relation + if p0.Alias != "" { + rel.Name = p0.Alias + } + + err := s.sqlCtx.joinRelation(rel) + if err != nil { + s.errs.AddErr(p0, err, p0.Table) + return []*Attribute{} + } + + return nil +} + +func (s *sqlAnalyzer) VisitRelationSubquery(p0 *RelationSubquery) any { + if s.sqlCtx.hasAnonymousTable { + s.errs.AddErr(p0, ErrUnnamedJoin, "statement uses an unnamed subquery or procedure join. to join another table, alias the subquery or procedure") + return []*Attribute{} + } + + relation, ok := p0.Subquery.Accept(s).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + // alias is usually required for subquery joins + if p0.Alias == "" { + // if alias is not given, then this must be a select and there must be exactly one table joined + if !s.sqlCtx.inSelect { + s.errs.AddErr(p0, ErrUnnamedJoin, "joins against subqueries must be aliased") + return []*Attribute{} + } + + // must be no relations, since this needs to be the first and only relation + if len(s.sqlCtx.joinedRelations) != 0 { + s.errs.AddErr(p0, ErrUnnamedJoin, "joins against subqueries must be aliased") + return []*Attribute{} + } + + s.sqlCtx.hasAnonymousTable = true + } + + err := s.sqlCtx.joinRelation(&Relation{ + Name: p0.Alias, + Attributes: relation, + }) + if err != nil { + s.errs.AddErr(p0, err, p0.Alias) + return []*Attribute{} + } + + return nil +} + +func (s *sqlAnalyzer) VisitRelationFunctionCall(p0 *RelationFunctionCall) any { + if s.sqlCtx.hasAnonymousTable { + s.errs.AddErr(p0, ErrUnnamedJoin, "statement uses an unnamed subquery or procedure join. to join another table, alias the subquery or procedure") + return []*Attribute{} + } + + // the function call here must return []*Attribute + // this logic is handled in returnProcedureReturnExpr. + ret, ok := p0.FunctionCall.Accept(s).([]*Attribute) + if !ok { + s.errs.AddErr(p0, ErrType, "cannot join procedure that does not return type table") + } + + // alias is usually required for subquery joins + if p0.Alias == "" { + // if alias is not given, then this must be a select and there must be exactly one table joined + if !s.sqlCtx.inSelect { + s.errs.AddErr(p0, ErrUnnamedJoin, "joins against procedures must be aliased") + return []*Attribute{} + } + + // must be no relations, since this needs to be the first and only relation + if len(s.sqlCtx.joinedRelations) != 0 { + s.errs.AddErr(p0, ErrUnnamedJoin, "joins against procedures must be aliased") + return []*Attribute{} + } + + s.sqlCtx.hasAnonymousTable = true + } + + err := s.sqlCtx.joinRelation(&Relation{ + Name: p0.Alias, + Attributes: ret, + }) + if err != nil { + s.errs.AddErr(p0, err, p0.Alias) + return []*Attribute{} + } + + return nil +} + +func (s *sqlAnalyzer) VisitJoin(p0 *Join) any { + // call visit on the comparison to perform regular type checking + p0.Relation.Accept(s) + dt, ok := p0.On.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.On) + return nil + } + + s.expect(p0.On, dt, types.BoolType) + + return nil +} + +func (s *sqlAnalyzer) VisitUpdateStatement(p0 *UpdateStatement) any { + s.sqlResult.Mutative = true + + tbl, msg, err := s.setTargetTable(p0.Table, p0.Alias) + if err != nil { + s.errs.AddErr(p0, err, msg) + return []*Attribute{} + } + + if p0.From != nil { + // we visit from and joins first to fill out the context, since those tables can be + // referenced in the set expression. + p0.From.Accept(s) + for _, j := range p0.Joins { + j.Accept(s) + } + } + + for _, set := range p0.SetClause { + // this calls VisitUpdateSetClause, defined directly below. + attr := set.Accept(s).(*Attribute) + + // we will see if the table being updated has this column, and if it + // is of the correct type. + col, ok := tbl.FindColumn(attr.Name) + if !ok { + s.errs.AddErr(set, ErrUnknownColumn, attr.Name) + continue + } + + if !col.Type.Equals(attr.Type) { + s.typeErr(set, attr.Type, col.Type) + } + } + + if p0.Where != nil { + whereType, ok := p0.Where.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.Where) + return []*Attribute{} + + } + + s.expect(p0.Where, whereType, types.BoolType) + } + + return []*Attribute{} +} + +// UpdateSetClause will map the updated column to the type it is being +// set to. Since it does not have context as to the table being acted on, +// it is the responsibility of the caller to validate the types. It will simply +// return the column and the type it is being set to, as an attribute. +func (s *sqlAnalyzer) VisitUpdateSetClause(p0 *UpdateSetClause) any { + dt, ok := p0.Value.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Value) + } + + return &Attribute{ + Name: p0.Column, + Type: dt, + } +} + +// result columns return []*Attribute +func (s *sqlAnalyzer) VisitResultColumnExpression(p0 *ResultColumnExpression) any { + e, ok := p0.Expression.Accept(s).(*types.DataType) + if !ok { + return s.expressionTypeErr(p0.Expression) + } + + attr := &Attribute{ + Name: p0.Alias, + Type: e, + } + + // ResultColumnExpressions always need to have aliases, unless the expression + // is a column. + if attr.Name == "" { + col, ok := p0.Expression.(*ExpressionColumn) + // if returning a column and not aliased, we give it the column name. + // otherwise, we simply leave the name blank. It will not be referenceable + if ok { + attr.Name = col.Column + } + } + + return []*Attribute{attr} +} + +func (s *sqlAnalyzer) VisitResultColumnWildcard(p0 *ResultColumnWildcard) any { + // if the table is specified, we need to return all columns from that table. + if p0.Table != "" { + tbl, ok := s.sqlCtx.getJoinedRelation(p0.Table) + if !ok { + s.errs.AddErr(p0, ErrUnknownTable, p0.Table) + return []*Attribute{} + } + + return tbl.Attributes + } + + // if table is empty, we flatten all joined relations. + flattened, conflictCol, err := Flatten(s.sqlCtx.joinedRelations...) + if err != nil { + s.errs.AddErr(p0, err, conflictCol) + return []*Attribute{} + } + + return flattened +} + +func (s *sqlAnalyzer) VisitDeleteStatement(p0 *DeleteStatement) any { + s.sqlResult.Mutative = true + + _, msg, err := s.setTargetTable(p0.Table, p0.Alias) + if err != nil { + s.errs.AddErr(p0, err, msg) + return []*Attribute{} + + } + + if p0.From != nil { + p0.From.Accept(s) + for _, j := range p0.Joins { + j.Accept(s) + } + } + + if p0.Where != nil { + whereType, ok := p0.Where.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.Where) + return []*Attribute{} + } + + s.expect(p0.Where, whereType, types.BoolType) + } + + return []*Attribute{} + +} + +func (s *sqlAnalyzer) VisitInsertStatement(p0 *InsertStatement) any { + s.sqlResult.Mutative = true + + tbl, msg, err := s.setTargetTable(p0.Table, p0.Alias) + if err != nil { + s.errs.AddErr(p0, err, msg) + return []*Attribute{} + } + + // all columns specified need to exist within the table + // we will keep track of the types of columns in the order + // they are specified, to match against the values. If columns + // are not specified, we simply get call the table's columns. + var colTypes []*types.DataType + if len(p0.Columns) == 0 { + for _, col := range tbl.Columns { + colTypes = append(colTypes, col.Type) + } + } else { + for _, col := range p0.Columns { + c, ok := tbl.FindColumn(col) + if !ok { + s.errs.AddErr(p0, ErrUnknownColumn, col) + return []*Attribute{} + } + colTypes = append(colTypes, c.Type) + } + } + + for _, valList := range p0.Values { + if len(valList) != len(colTypes) { + s.errs.AddErr(p0, ErrResultShape, "expected %d values, received %d", len(colTypes), len(valList)) + return []*Attribute{} + } + + for i, val := range valList { + dt, ok := val.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(val) + return []*Attribute{} + } + + if !dt.Equals(colTypes[i]) { + s.typeErr(val, dt, colTypes[i]) + } + } + } + + if p0.Upsert != nil { + s.sqlCtx.inConflict = true + p0.Upsert.Accept(s) + s.sqlCtx.inConflict = false + } + + return []*Attribute{} + +} + +// setTargetTable joins a table from the schema to the sql context, for +// usage in an insert, delete, or update statement. +// It will return an error if the table is already joined, or if the table +// is not in the schema. Optionally, an alias can be passed, which will join +// the table with the alias name. If there is an error, it returns the error +// and a message. It should only be used in INSERT, DELETE, and UPDATE statements. +func (s *sqlAnalyzer) setTargetTable(table string, alias string) (*types.Table, string, error) { + tbl, ok := s.schema.FindTable(table) + if !ok { + return nil, table, ErrUnknownTable + } + + name := tbl.Name + if alias != "" { + name = alias + } + + err := s.sqlCtx.join(name, tbl) + if err != nil { + return nil, name, err + } + + rel, err := tableToRelation(tbl) + if err != nil { + return nil, name, err + } + + err = s.sqlCtx.joinRelation(rel) + if err != nil { + return nil, name, err + } + + s.sqlCtx.targetTable = name + + return tbl, "", nil +} + +func (s *sqlAnalyzer) VisitUpsertClause(p0 *UpsertClause) any { + // upsert clause can only be called in an insert. Inserts will + // always have exactly 1 table joined to the context. We will + // need to retrieve the one table, verify all conflict columns + // are valid columns, and validate that any DoUpdate clause + // references a real column and is assigning it to the correct type. + if len(s.sqlCtx.joinedRelations) != 1 { + // panicking because this is an internal bug in context scoping + panic("expected exactly 1 table to be joined in upsert clause") + } + + rel := s.sqlCtx.joinedRelations[0] + for _, col := range p0.ConflictColumns { + _, ok := rel.FindAttribute(col) + if !ok { + s.errs.AddErr(p0, ErrUnknownColumn, "conflict column %s", col) + return nil + } + } + + for _, set := range p0.DoUpdate { + attr := set.Accept(s).(*Attribute) + + foundAttr, ok := rel.FindAttribute(attr.Name) + if !ok { + s.errs.AddErr(p0, ErrUnknownColumn, "update column %s", attr.Name) + continue + } + + if !foundAttr.Type.Equals(attr.Type) { + s.typeErr(set, attr.Type, foundAttr.Type) + return nil + } + } + + if p0.ConflictWhere != nil { + dt, ok := p0.ConflictWhere.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.ConflictWhere) + return nil + } + + s.expect(p0.ConflictWhere, dt, types.BoolType) + } + + if p0.UpdateWhere != nil { + dt, ok := p0.UpdateWhere.Accept(s).(*types.DataType) + if !ok { + s.expressionTypeErr(p0.UpdateWhere) + return nil + } + + s.expect(p0.UpdateWhere, dt, types.BoolType) + } + + return nil +} + +func (s *sqlAnalyzer) VisitOrderingTerm(p0 *OrderingTerm) any { + // visit the expression. We do not have to worry about what + // it returns though + p0.Expression.Accept(s) + return nil +} + +// tableToRelation converts a table to a relation. +func tableToRelation(t *types.Table) (*Relation, error) { + attrs := make([]*Attribute, len(t.Columns)) + for i, col := range t.Columns { + attrs[i] = &Attribute{ + Name: col.Name, + Type: col.Type.Copy(), + } + } + + return &Relation{ + Name: t.Name, + Attributes: attrs, + }, nil +} + +// procedureContext holds context for the procedure analyzer. +type procedureContext struct { + // procedureDefinition is the definition for the procedure that we are + // currently analyzing. + procedureDefinition *types.Procedure + // activeLoopReceivers track the variable name for the current loop. + // The innermost nested loop will be at the 0-index. If we are + // not in a loop, the slice will be empty. + activeLoopReceivers []string +} + +func newProcedureContext(proc *types.Procedure) *procedureContext { + return &procedureContext{ + procedureDefinition: proc, + } +} + +// loopTargetTracker is used to track the target of a loop. +type loopTargetTracker struct { + // name is the variable name of the loop target. + name *ExpressionVariable + // dataType is the data type of the loop target. + // If the loop target is an anonymous variable, then it will be nil. + dataType *types.DataType +} + +// procedureAnalyzer analyzes the procedural language. Since the procedural +// language can execute sql statements, it uses the sqlAnalyzer. +type procedureAnalyzer struct { + sqlAnalyzer + procCtx *procedureContext + procResult struct { + // allLoopReceivers tracks all loop receivers that have occurred over the lifetime + // of the procedure. This is used to generate variables to hold the loop target + // in plpgsql. + allLoopReceivers []*loopTargetTracker + // anonymousReceivers track the data types of procedure return values + // that the user throws away. In the procedure call + // `$var1, _, $var2 := proc_that_returns_3_values()`, the underscore is + // the anonymous receiver. This slice tracks the types for each of the + // receivers as it encounters them, so that it can generate a throw-away + // variable in plpgsql + anonymousReceivers []*types.DataType + // allVariables is a map of all variables declared in the procedure. + // The key is the variable name, and the value is the data type. + // This does not include any variable declared by a FOR LOOP. + allVariables map[string]*types.DataType + } +} + +// markDeclared checks if the variable has been declared in the same procedure body, +// but in a different scope. PLPGSQL cannot handle redeclaration, so we need to check for this. +// It will throw the error in the method, and let the caller continue since this is not a critical +// parsing bug. It will mark the variable as declared if it has not been declared yet. +func (p *procedureAnalyzer) markDeclared(p0 Node, name string, typ *types.DataType) { + dt, ok := p.procResult.allVariables[name] + if !ok { + p.procResult.allVariables[name] = typ + return + } + + if !dt.Equals(typ) { + p.errs.AddErr(p0, ErrCrossScopeDeclaration, `variable %s is declared in a different scope in this procedure as a different type. + This is not supported.`, name) + } +} + +// startProcedureAnalyze starts the analysis of a procedure. +func (p *procedureAnalyzer) startSQLAnalyze() { + p.sqlAnalyzer.startSQLAnalyze() +} + +// endProcedureAnalyze ends the analysis of a procedure. +func (p *procedureAnalyzer) endSQLAnalyze(node Node) { + sqlRes := p.sqlAnalyzer.endSQLAnalyze() + if sqlRes.Mutative { + if p.procCtx.procedureDefinition.IsView() { + p.errs.AddErr(node, ErrViewMutatesState, "SQL statement mutates state in view procedure") + } + } +} + +var _ Visitor = (*procedureAnalyzer)(nil) + +func (p *procedureAnalyzer) VisitProcedureStmtDeclaration(p0 *ProcedureStmtDeclaration) any { + // we will check if the variable has already been declared, and if so, error. + + if p.variableExists(p0.Variable.String()) { + p.errs.AddErr(p0, ErrVariableAlreadyDeclared, p0.Variable.String()) + return nil + } + + // TODO: we need to figure out how to undeclare a variable if it is declared in a loop/if block + + p.variables[p0.Variable.String()] = p0.Type + p.markDeclared(p0.Variable, p0.Variable.String(), p0.Type) + + // now that it is declared, we can visit it + p0.Variable.Accept(p) + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtAssignment(p0 *ProcedureStmtAssign) any { + // visit the value first to get the data type + dt, ok := p0.Value.Accept(p).(*types.DataType) + if !ok { + p.expressionTypeErr(p0.Value) + return nil + } + + _, ok = p.variables[p0.Variable.String()] + if !ok { + // if it does not exist, we can declare it here. + p.variables[p0.Variable.String()] = dt + p.markDeclared(p0.Variable, p0.Variable.String(), dt) + return nil + } + + // the type can be inferred from the value. + // If the user explicitly declared a type, the inferred + // type should match + if p0.Type != nil { + if !p0.Type.Equals(dt) { + p.errs.AddErr(p0, ErrType, "declared type: %s, inferred type: %s", p0.Type.String(), dt.String()) + return nil + } + } + + // ensure the variable already exists, and we are assigning the correct type. + dt2, ok := p0.Variable.Accept(p).(*types.DataType) + if !ok { + p.expressionTypeErr(p0.Variable) + return nil + } + + if !dt2.Equals(dt) { + p.typeErr(p0, dt, dt2) + } + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtCall(p0 *ProcedureStmtCall) any { + // we track if sqlResult has already been set to alreadyMutative to avoid throwing + // an incorrect error below. + alreadyMutative := p.sqlResult.Mutative + + var callReturns []*types.DataType + // it might return a single value + returns1, ok := p0.Call.Accept(p).(*types.DataType) + if ok { + // if it returns null, then we do not need to assign it to a variable. + if !returns1.EqualsStrict(types.NullType) { + callReturns = append(callReturns, returns1) + } + } else { + // or it might return multiple values + returns2, ok := p0.Call.Accept(p).([]*types.DataType) + if !ok { + p.errs.AddErr(p0.Call, ErrType, "expected function/procedure to return one or more variables") + return nil + } + + callReturns = returns2 + } + + // if calling a non-view procedure, the above will set the sqlResult to be mutative + // if this procedure is a view, we should throw an error. + if !alreadyMutative && p.sqlResult.Mutative && p.procCtx.procedureDefinition.IsView() { + p.errs.AddErr(p0, ErrViewMutatesState, `view procedure calls non-view procedure "%s"`, p0.Call.FunctionName()) + } + + // we do not have to capture all return values, but we need to ensure + // we do not have more receivers than return values. + if len(p0.Receivers) != len(callReturns) { + p.errs.AddErr(p0, ErrResultShape, `function/procedure "%s" returns %d value(s), statement expects %d value(s)`, p0.Call.FunctionName(), len(callReturns), len(p0.Receivers)) + return nil + } + + for i, r := range p0.Receivers { + // if the receiver is nil, we will not assign it to a variable, as it is an + // anonymous receiver. + if r == nil { + p.procResult.anonymousReceivers = append(p.procResult.anonymousReceivers, callReturns[i]) + continue + } + + // ensure the receiver is not already an anonymous variable + if _, ok := p.anonymousVariables[r.String()]; ok { + p.errs.AddErr(r, ErrVariableAlreadyDeclared, r.String()) + continue + } + + // if the variable has been declared, the type must match. otherwise, declare it and infer the type. + declaredType, ok := p.variables[r.String()] + if ok { + if !declaredType.Equals(callReturns[i]) { + p.typeErr(r, callReturns[i], declaredType) + continue + } + } else { + p.variables[r.String()] = callReturns[i] + p.markDeclared(r, r.String(), callReturns[i]) + } + } + + return nil +} + +// VisitProcedureStmtForLoop visits a for loop statement. +// This function is a bit convoluted, but it handles a lot of logic. It checks that the loop +// target variable can actually be declared by plpgsql, and then has to allow it to be accessed +// in the current block context. Once we exit the for loop, it has to make it no longer accessible +// in the context, BUT needs to still keep track of it. It needs to keep track of its data type, +// and whether it is a compound type, so that plpgsql knows whether to declare it as a RECORD +// or as a scalar type. +func (p *procedureAnalyzer) VisitProcedureStmtForLoop(p0 *ProcedureStmtForLoop) any { + // check to make sure the receiver has not already been declared + if p.variableExists(p0.Receiver.String()) { + p.errs.AddErr(p0.Receiver, ErrVariableAlreadyDeclared, p0.Receiver.String()) + return nil + } + + tracker := &loopTargetTracker{ + name: p0.Receiver, + } + + // get the type from the loop term. + // can be a scalar if the term is a range or array, + // and an object if it is a sql statement. + res := p0.LoopTerm.Accept(p) + scalarVal, ok := res.(*types.DataType) + + // we do not mark declared here since these are loop receivers, + // and they get tracked in a separate slice than other variables. + if ok { + p.variables[p0.Receiver.String()] = scalarVal + tracker.dataType = scalarVal + } else { + compound, ok := res.(map[string]*types.DataType) + if !ok { + panic("expected loop term to return scalar or compound type") + } + p.anonymousVariables[p0.Receiver.String()] = compound + // we do not set the tracker type here, since it is an anonymous variable. + } + + // we now need to add the loop target. + // if it already has been used, we will error. + for _, t := range p.procResult.allLoopReceivers { + if t.name.String() == p0.Receiver.String() { + p.errs.AddErr(p0.Receiver, ErrVariableAlreadyDeclared, p0.Receiver.String()) + return nil + } + } + + p.procCtx.activeLoopReceivers = append([]string{tracker.name.String()}, p.procCtx.activeLoopReceivers...) + p.procResult.allLoopReceivers = append(p.procResult.allLoopReceivers, tracker) + + // we will now visit the statements in the loop. + for _, stmt := range p0.Body { + stmt.Accept(p) + } + + // pop the loop target + if len(p.procCtx.activeLoopReceivers) == 1 { + p.procCtx.activeLoopReceivers = nil + } else { + p.procCtx.activeLoopReceivers = p.procCtx.activeLoopReceivers[1:] + } + + if tracker.dataType != nil { + delete(p.anonymousVariables, p0.Receiver.String()) + } else { + delete(p.variables, p0.Receiver.String()) + } + + return nil +} + +func (p *procedureAnalyzer) VisitLoopTermRange(p0 *LoopTermRange) any { + // range loops are always integers + start, ok := p0.Start.Accept(p).(*types.DataType) + if !ok { + return p.expressionTypeErr(p0.Start) + } + + end, ok := p0.End.Accept(p).(*types.DataType) + if !ok { + return p.expressionTypeErr(p0.End) + } + + // the types have to be ints + + p.expect(p0.Start, start, types.IntType) + p.expect(p0.End, end, types.IntType) + + return types.IntType +} + +func (p *procedureAnalyzer) VisitLoopTermSQL(p0 *LoopTermSQL) any { + p.startSQLAnalyze() + rels, ok := p0.Statement.Accept(p).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + p.endSQLAnalyze(p0.Statement) + + // we need to convert the attributes into an object + obj := make(map[string]*types.DataType) + for _, rel := range rels { + obj[rel.Name] = rel.Type + } + + return obj +} + +func (p *procedureAnalyzer) VisitLoopTermVariable(p0 *LoopTermVariable) any { + // we need to ensure the variable exists + dt, ok := p0.Variable.Accept(p).(*types.DataType) + if !ok { + return p.expressionTypeErr(p0.Variable) + } + + return dt +} + +func (p *procedureAnalyzer) VisitProcedureStmtIf(p0 *ProcedureStmtIf) any { + for _, c := range p0.IfThens { + c.Accept(p) + } + + if p0.Else != nil { + for _, stmt := range p0.Else { + stmt.Accept(p) + } + } + + return nil +} + +func (p *procedureAnalyzer) VisitIfThen(p0 *IfThen) any { + dt, ok := p0.If.Accept(p).(*types.DataType) + if !ok { + p.expressionTypeErr(p0.If) + return nil + } + + p.expect(p0.If, dt, types.BoolType) + + for _, stmt := range p0.Then { + stmt.Accept(p) + } + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtSQL(p0 *ProcedureStmtSQL) any { + p.startSQLAnalyze() + defer p.endSQLAnalyze(p0.SQL) + + _, ok := p0.SQL.Accept(p).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtBreak(p0 *ProcedureStmtBreak) any { + if len(p.procCtx.activeLoopReceivers) == 0 { + p.errs.AddErr(p0, ErrBreak, "break statement outside of loop") + } + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtReturn(p0 *ProcedureStmtReturn) any { + if p.procCtx.procedureDefinition.Returns == nil { + p.errs.AddErr(p0, ErrFunctionSignature, "procedure does not return any values") + return nil + } + returns := p.procCtx.procedureDefinition.Returns + + if p0.SQL != nil { + if !returns.IsTable { + p.errs.AddErr(p0, ErrReturn, "procedure expects scalar returns, cannot return SQL statement") + return nil + } + + p.startSQLAnalyze() + defer p.endSQLAnalyze(p0.SQL) + + res, ok := p0.SQL.Accept(p).([]*Attribute) + if !ok { + panic("expected query to return attributes") + } + + if len(res) != len(returns.Fields) { + p.errs.AddErr(p0, ErrReturn, "expected %d return table columns, received %d", len(returns.Fields), len(res)) + return nil + } + + // we will compare the return types to the procedure definition + for i, r := range res { + retField := returns.Fields[i] + if !r.Type.Equals(retField.Type) { + p.errs.AddErr(p0, ErrReturn, "expected column type %s, received column type %s", retField.Type.String(), r.Type.String()) + } + + if r.Name != retField.Name { + p.errs.AddErr(p0, ErrReturn, "expected column name %s, received column name %s", retField.Name, r.Name) + } + } + + return nil + } + if returns.IsTable { + p.errs.AddErr(p0, ErrReturn, "procedure expects table returns, cannot return scalar values") + return nil + } + + if len(p0.Values) != len(returns.Fields) { + p.errs.AddErr(p0, ErrReturn, "expected %d return values, received %d", len(returns.Fields), len(p0.Values)) + return nil + } + + for i, v := range p0.Values { + dt, ok := v.Accept(p).(*types.DataType) + if !ok { + return p.expressionTypeErr(v) + } + + if !dt.Equals(returns.Fields[i].Type) { + p.typeErr(v, dt, returns.Fields[i].Type) + } + } + + return nil +} + +func (p *procedureAnalyzer) VisitProcedureStmtReturnNext(p0 *ProcedureStmtReturnNext) any { + if p.procCtx.procedureDefinition.Returns == nil { + p.errs.AddErr(p0, ErrFunctionSignature, "procedure does not return any values") + return nil + } + + if !p.procCtx.procedureDefinition.Returns.IsTable { + p.errs.AddErr(p0, ErrReturn, "procedure expects scalar returns, cannot return next") + return nil + } + + if len(p0.Values) != len(p.procCtx.procedureDefinition.Returns.Fields) { + p.errs.AddErr(p0, ErrReturn, "expected %d return values, received %d", len(p.procCtx.procedureDefinition.Returns.Fields), len(p0.Values)) + return nil + } + + for i, v := range p0.Values { + dt, ok := v.Accept(p).(*types.DataType) + if !ok { + return p.expressionTypeErr(v) + } + + if !dt.Equals(p.procCtx.procedureDefinition.Returns.Fields[i].Type) { + p.typeErr(v, dt, p.procCtx.procedureDefinition.Returns.Fields[i].Type) + } + } + + return nil +} diff --git a/parse/analyze_test.go b/parse/analyze_test.go new file mode 100644 index 000000000..acdf14906 --- /dev/null +++ b/parse/analyze_test.go @@ -0,0 +1,29 @@ +package parse + +import ( + "testing" + + "github.com/kwilteam/kwil-db/core/types" + "github.com/stretchr/testify/require" +) + +func Test_Scope(t *testing.T) { + tbl := &types.Table{} + s := sqlContext{ + joinedTables: map[string]*types.Table{ + "table1": tbl, + }, + } + + s.scope() + s.scope() + + require.EqualValues(t, s.joinedTables, map[string]*types.Table{}) + + s.popScope() + s.popScope() + + require.EqualValues(t, s.joinedTables, map[string]*types.Table{ + "table1": tbl, + }) +} diff --git a/parse/antlr.go b/parse/antlr.go new file mode 100644 index 000000000..3c8522f08 --- /dev/null +++ b/parse/antlr.go @@ -0,0 +1,1998 @@ +package parse + +import ( + "encoding/hex" + "fmt" + "math" + "math/big" + "strconv" + "strings" + + "github.com/antlr4-go/antlr/v4" + "github.com/holiman/uint256" + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/types/decimal" + "github.com/kwilteam/kwil-db/core/types/validation" + "github.com/kwilteam/kwil-db/parse/gen" +) + +// schemaVisitor is a visitor for converting Kuneiform's ANTLR +// generated parse tree into our native schema type. It will perform +// syntax validation on actions and procedures. +type schemaVisitor struct { + antlr.BaseParseTreeVisitor + // schema is the schema that was parsed. + // If no schema was parsed, it will be nil. + schema *types.Schema + // schemaInfo holds information on the position + // of certain blocks in the schema. + schemaInfo *SchemaInfo + // errs is used for passing errors back to the caller. + errs *errorListener + // stream is the input stream + stream *antlr.InputStream + // both procedures and actions are only needed if parsing + // an entire top-level schema, and will not be called if + // parsing only an action or procedure body, or SQL. + // procedures maps the asts of all parsed procedures + procedures map[string][]ProcedureStmt + // actions maps the asts of all parsed actions + actions map[string][]ActionStmt +} + +// newSchemaVisitor creates a new schema visitor. +func newSchemaVisitor(stream *antlr.InputStream, errLis *errorListener) *schemaVisitor { + return &schemaVisitor{ + schemaInfo: &SchemaInfo{ + Blocks: make(map[string]*Block), + }, + errs: errLis, + stream: stream, + } +} + +var _ gen.KuneiformParserVisitor = (*schemaVisitor)(nil) + +// VisitEntry visits the top-level entry in the schema. +// It can be a schema, action, procedure, or sql statement. +func (s *schemaVisitor) VisitEntry(ctx *gen.EntryContext) any { + switch { + case ctx.Schema() != nil: + return s.VisitSchema(ctx.Schema().(*gen.SchemaContext)) + case ctx.Sql() != nil: + return s.VisitSql(ctx.Sql().(*gen.SqlContext)) + case ctx.Action_block() != nil: + return s.VisitAction_block(ctx.Action_block().(*gen.Action_blockContext)) + case ctx.Procedure_block() != nil: + return s.VisitProcedure_block(ctx.Procedure_block().(*gen.Procedure_blockContext)) + default: + panic("unknown entry") + } +} + +// unknownExpression creates a new literal with an unknown type and null value. +// It should be used when we have to return early from a visitor method that +// returns an expression. +func unknownExpression(ctx antlr.ParserRuleContext) *ExpressionLiteral { + e := &ExpressionLiteral{ + Type: types.UnknownType, + Value: nil, + } + + e.Set(ctx) + + return e +} + +func (s *schemaVisitor) VisitString_literal(ctx *gen.String_literalContext) any { + str := ctx.STRING_() + n := &ExpressionLiteral{ + Type: types.TextType, + Value: strings.Trim(str.GetText(), "'"), + } + + n.Set(ctx) + + return n +} + +var ( + maxInt64 = big.NewInt(math.MaxInt64) + minInt64 = big.NewInt(math.MinInt64) +) + +func (s *schemaVisitor) VisitInteger_literal(ctx *gen.Integer_literalContext) any { + i := ctx.DIGITS_().GetText() + if ctx.MINUS() != nil { + i = "-" + i + } + + // integer literal can be either a uint256 or int64 + bigNum := new(big.Int) + _, ok := bigNum.SetString(i, 10) + if !ok { + s.errs.RuleErr(ctx, ErrSyntax, "invalid integer literal: %s", i) + return unknownExpression(ctx) + } + + if bigNum.Cmp(maxInt64) > 0 { + // it is a uint256 + u256, ok := uint256.FromBig(bigNum) + if !ok { + s.errs.RuleErr(ctx, ErrSyntax, "invalid integer literal: %s", i) + return unknownExpression(ctx) + } + + e := &ExpressionLiteral{ + Type: types.Uint256Type, + Value: u256, + } + e.Set(ctx) + return e + } + if bigNum.Cmp(minInt64) < 0 { + s.errs.RuleErr(ctx, ErrType, "integer literal out of range: %s", i) + return unknownExpression(ctx) + } + + e := &ExpressionLiteral{ + Type: types.IntType, + Value: bigNum.Int64(), + } + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitDecimal_literal(ctx *gen.Decimal_literalContext) any { + // our decimal library can parse the decimal, so we simply pass it there + txt := ctx.GetText() + + dec, err := decimal.NewFromString(txt) + if err != nil { + s.errs.RuleErr(ctx, err, "invalid decimal literal: %s", txt) + return unknownExpression(ctx) + } + + typ, err := types.NewDecimalType(dec.Precision(), dec.Scale()) + if err != nil { + s.errs.RuleErr(ctx, err, "invalid decimal literal: %s", txt) + return unknownExpression(ctx) + } + + e := &ExpressionLiteral{ + Type: typ, + Value: dec, + } + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitBoolean_literal(ctx *gen.Boolean_literalContext) any { + var b bool + switch { + case ctx.TRUE() != nil: + b = true + case ctx.FALSE() != nil: + b = false + default: + panic("unknown boolean literal") + } + + e := &ExpressionLiteral{ + Type: types.BoolType, + Value: b, + } + + e.Set(ctx) + + return e +} + +func (s *schemaVisitor) VisitNull_literal(ctx *gen.Null_literalContext) any { + e := &ExpressionLiteral{ + Type: types.NullType, + Value: nil, + } + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitBinary_literal(ctx *gen.Binary_literalContext) any { + b := ctx.GetText() + // trim off beginning 0x + if b[:2] != "0x" { + // this should get caught by the parser + s.errs.RuleErr(ctx, ErrSyntax, "invalid blob literal: %s", b) + } + + b = b[2:] + + decoded, err := hex.DecodeString(b) + if err != nil { + // this should get caught by the parser + s.errs.RuleErr(ctx, ErrSyntax, "invalid blob literal: %s", b) + } + + e := &ExpressionLiteral{ + Type: types.BlobType, + Value: decoded, + } + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitIdentifier_list(ctx *gen.Identifier_listContext) any { + var ident []string + for _, i := range ctx.AllIdentifier() { + ident = append(ident, i.Accept(s).(string)) + } + + return ident +} + +func (s *schemaVisitor) VisitIdentifier(ctx *gen.IdentifierContext) any { + return s.getIdent(ctx.IDENTIFIER()) +} + +func (s *schemaVisitor) VisitType(ctx *gen.TypeContext) any { + dt := &types.DataType{ + Name: s.getIdent(ctx.IDENTIFIER()), + } + + if ctx.LPAREN() != nil { + // there should be 2 digits + prec, err := strconv.ParseInt(ctx.DIGITS_(0).GetText(), 10, 64) + if err != nil { + s.errs.RuleErr(ctx, ErrSyntax, "invalid precision: %s", ctx.DIGITS_(0).GetText()) + return types.UnknownType + } + + scale, err := strconv.ParseInt(ctx.DIGITS_(1).GetText(), 10, 64) + if err != nil { + s.errs.RuleErr(ctx, ErrSyntax, "invalid scale: %s", ctx.DIGITS_(1).GetText()) + return types.UnknownType + } + + dt.Metadata = [2]uint16{uint16(prec), uint16(scale)} + } + + if ctx.LBRACKET() != nil { + dt.IsArray = true + } + + err := dt.Clean() + if err != nil { + s.errs.RuleErr(ctx, err, "invalid type: %s", dt.String()) + return types.UnknownType + } + + return dt +} + +func (s *schemaVisitor) VisitType_cast(ctx *gen.Type_castContext) any { + return s.Visit(ctx.Type_()).(*types.DataType) +} + +func (s *schemaVisitor) VisitVariable(ctx *gen.VariableContext) any { + var e *ExpressionVariable + var tok antlr.Token + switch { + case ctx.VARIABLE() != nil: + e = &ExpressionVariable{ + Name: strings.ToLower(strings.TrimLeft(ctx.GetText(), "$")), + Prefix: VariablePrefixDollar, + } + tok = ctx.VARIABLE().GetSymbol() + case ctx.CONTEXTUAL_VARIABLE() != nil: + e = &ExpressionVariable{ + Name: strings.ToLower(strings.TrimLeft(ctx.GetText(), "@")), + Prefix: VariablePrefixAt, + } + tok = ctx.CONTEXTUAL_VARIABLE().GetSymbol() + + _, ok := SessionVars[e.Name] + if !ok { + s.errs.RuleErr(ctx, ErrUnknownContextualVariable, e.Name) + } + + default: + panic("unknown variable") + } + + s.validateVariableIdentifier(tok, e.Name) + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitVariable_list(ctx *gen.Variable_listContext) any { + var vars []*ExpressionVariable + for _, v := range ctx.AllVariable() { + vars = append(vars, v.Accept(s).(*ExpressionVariable)) + } + + return vars +} + +func (s *schemaVisitor) VisitSchema(ctx *gen.SchemaContext) any { + s.schema = &types.Schema{ + Name: ctx.Database_declaration().Accept(s).(string), + Tables: arr[*types.Table](len(ctx.AllTable_declaration())), + Extensions: arr[*types.Extension](len(ctx.AllUse_declaration())), + Actions: arr[*types.Action](len(ctx.AllAction_declaration())), + Procedures: arr[*types.Procedure](len(ctx.AllProcedure_declaration())), + ForeignProcedures: arr[*types.ForeignProcedure](len(ctx.AllForeign_procedure_declaration())), + } + + for i, t := range ctx.AllTable_declaration() { + s.schema.Tables[i] = t.Accept(s).(*types.Table) + s.registerBlock(t, s.schema.Tables[i].Name) + } + + for i, e := range ctx.AllUse_declaration() { + s.schema.Extensions[i] = e.Accept(s).(*types.Extension) + s.registerBlock(e, s.schema.Extensions[i].Alias) + } + + for i, a := range ctx.AllAction_declaration() { + s.schema.Actions[i] = a.Accept(s).(*types.Action) + s.registerBlock(a, s.schema.Actions[i].Name) + } + + for i, p := range ctx.AllProcedure_declaration() { + s.schema.Procedures[i] = p.Accept(s).(*types.Procedure) + s.registerBlock(p, s.schema.Procedures[i].Name) + } + + for i, p := range ctx.AllForeign_procedure_declaration() { + s.schema.ForeignProcedures[i] = p.Accept(s).(*types.ForeignProcedure) + s.registerBlock(p, s.schema.ForeignProcedures[i].Name) + } + + return s.schema +} + +// registerBlock registers a top-level block (table, action, procedure, etc.), +// ensuring uniqueness +func (s *schemaVisitor) registerBlock(ctx antlr.ParserRuleContext, name string) { + lower := strings.ToLower(name) + if _, ok := s.schemaInfo.Blocks[lower]; ok { + s.errs.RuleErr(ctx, ErrDuplicateBlock, lower) + return + } + + node := &Position{} + node.Set(ctx) + s.schemaInfo.Blocks[lower] = &Block{ + Position: *node, + AbsStart: ctx.GetStart().GetStart(), + AbsEnd: ctx.GetStop().GetStop(), + } +} + +// arr will make an array of type A if the input is greater than 0 +func arr[A any](b int) []A { + if b > 0 { + return make([]A, b) + } + return nil +} + +func (s *schemaVisitor) VisitAnnotation(ctx *gen.AnnotationContext) any { + // we will parse but reconstruct annotations, so they can later be consumed by the gateway + str := strings.Builder{} + + str.WriteString(s.getIdent(ctx.CONTEXTUAL_VARIABLE())) + str.WriteString("(") + for i, l := range ctx.AllLiteral() { + if i > 0 { + str.WriteString(", ") + } + + str.WriteString(s.getIdent(ctx.IDENTIFIER(i))) + str.WriteString("=") + // we do not touch the literal, since case should be preserved + str.WriteString(l.GetText()) + } + str.WriteString(")") + + return str.String() +} + +func (s *schemaVisitor) VisitDatabase_declaration(ctx *gen.Database_declarationContext) any { + return s.getIdent(ctx.IDENTIFIER()) +} + +func (s *schemaVisitor) VisitUse_declaration(ctx *gen.Use_declarationContext) any { + // the first identifier is the extension name, the last is the alias, + // and all in between are keys in the initialization. + e := &types.Extension{ + Name: s.getIdent(ctx.IDENTIFIER(0)), + Initialization: arr[*types.ExtensionConfig](len(ctx.AllIDENTIFIER()) - 2), + Alias: s.getIdent(ctx.IDENTIFIER(len(ctx.AllIDENTIFIER()) - 1)), + } + + for i, id := range ctx.AllIDENTIFIER()[1 : len(ctx.AllIDENTIFIER())-1] { + val := ctx.Literal(i).Accept(s).(*ExpressionLiteral) + + e.Initialization[i] = &types.ExtensionConfig{ + Key: s.getIdent(id), + Value: val.String(), + } + } + + return e +} + +func (s *schemaVisitor) VisitTable_declaration(ctx *gen.Table_declarationContext) any { + t := &types.Table{ + Name: s.getIdent(ctx.IDENTIFIER()), + Columns: arr[*types.Column](len(ctx.AllColumn_def())), + Indexes: arr[*types.Index](len(ctx.AllIndex_def())), + ForeignKeys: arr[*types.ForeignKey](len(ctx.AllForeign_key_def())), + } + + for i, c := range ctx.AllColumn_def() { + t.Columns[i] = c.Accept(s).(*types.Column) + } + + for i, idx := range ctx.AllIndex_def() { + t.Indexes[i] = idx.Accept(s).(*types.Index) + } + + for i, fk := range ctx.AllForeign_key_def() { + t.ForeignKeys[i] = fk.Accept(s).(*types.ForeignKey) + } + + return t +} + +func (s *schemaVisitor) VisitColumn_def(ctx *gen.Column_defContext) any { + col := &types.Column{ + Name: s.getIdent(ctx.IDENTIFIER()), + Type: ctx.Type_().Accept(s).(*types.DataType), + Attributes: arr[*types.Attribute](len(ctx.AllConstraint())), + } + + for i, a := range ctx.AllConstraint() { + col.Attributes[i] = a.Accept(s).(*types.Attribute) + } + + return col +} + +func (s *schemaVisitor) VisitIndex_def(ctx *gen.Index_defContext) any { + name := ctx.HASH_IDENTIFIER().GetText() + name = strings.TrimLeft(name, "#") + idx := &types.Index{ + Name: strings.ToLower(name), + Columns: ctx.Identifier_list().Accept(s).([]string), + } + + s.validateVariableIdentifier(ctx.HASH_IDENTIFIER().GetSymbol(), idx.Name) + + switch { + case ctx.INDEX() != nil: + idx.Type = types.BTREE + case ctx.UNIQUE() != nil: + idx.Type = types.UNIQUE_BTREE + case ctx.PRIMARY() != nil: + idx.Type = types.PRIMARY + default: + panic("unknown index type") + } + + return idx +} + +func (s *schemaVisitor) VisitForeign_key_def(ctx *gen.Foreign_key_defContext) any { + fk := &types.ForeignKey{ + ChildKeys: ctx.GetChild_keys().Accept(s).([]string), + ParentKeys: ctx.GetParent_keys().Accept(s).([]string), + ParentTable: strings.ToLower(ctx.GetParent_table().GetText()), + Actions: arr[*types.ForeignKeyAction](len(ctx.AllForeign_key_action())), + } + + for i, a := range ctx.AllForeign_key_action() { + fk.Actions[i] = a.Accept(s).(*types.ForeignKeyAction) + } + + return fk +} + +func (s *schemaVisitor) VisitForeign_key_action(ctx *gen.Foreign_key_actionContext) any { + ac := &types.ForeignKeyAction{} + switch { + case ctx.UPDATE() != nil, ctx.LEGACY_ON_UPDATE() != nil: + ac.On = types.ON_UPDATE + case ctx.DELETE() != nil, ctx.LEGACY_ON_DELETE() != nil: + ac.On = types.ON_DELETE + default: + panic("unknown foreign key action") + } + + switch { + case ctx.ACTION() != nil, ctx.LEGACY_NO_ACTION() != nil: + ac.Do = types.DO_NO_ACTION + case ctx.NULL() != nil, ctx.LEGACY_SET_NULL() != nil: + ac.Do = types.DO_SET_NULL + case ctx.DEFAULT() != nil, ctx.LEGACY_SET_DEFAULT() != nil: + ac.Do = types.DO_SET_DEFAULT + // cascade and restrict do not have legacys + case ctx.CASCADE() != nil: + ac.Do = types.DO_CASCADE + case ctx.RESTRICT() != nil: + ac.Do = types.DO_RESTRICT + default: + panic("unknown foreign key action") + } + + return ac +} + +func (s *schemaVisitor) VisitType_list(ctx *gen.Type_listContext) any { + var ts []*types.DataType + for _, t := range ctx.AllType_() { + ts = append(ts, t.Accept(s).(*types.DataType)) + } + + return ts +} + +func (s *schemaVisitor) VisitNamed_type_list(ctx *gen.Named_type_listContext) any { + var ts []*types.NamedType + for i, t := range ctx.AllIDENTIFIER() { + ts = append(ts, &types.NamedType{ + Name: s.getIdent(t), + Type: ctx.Type_(i).Accept(s).(*types.DataType), + }) + } + + return ts +} + +func (s *schemaVisitor) VisitTyped_variable_list(ctx *gen.Typed_variable_listContext) any { + var vars []*types.ProcedureParameter + for i, v := range ctx.AllVariable() { + vars = append(vars, &types.ProcedureParameter{ + Name: v.Accept(s).(*ExpressionVariable).String(), + Type: ctx.Type_(i).Accept(s).(*types.DataType), + }) + } + + return vars +} + +func (s *schemaVisitor) VisitMin_constraint(ctx *gen.Min_constraintContext) any { + return &types.Attribute{ + Type: types.MIN, + Value: ctx.Literal().Accept(s).(*ExpressionLiteral).String(), + } +} + +func (s *schemaVisitor) VisitMax_constraint(ctx *gen.Max_constraintContext) any { + return &types.Attribute{ + Type: types.MAX, + Value: ctx.Literal().Accept(s).(*ExpressionLiteral).String(), + } +} + +func (s *schemaVisitor) VisitMin_len_constraint(ctx *gen.Min_len_constraintContext) any { + return &types.Attribute{ + Type: types.MIN_LENGTH, + Value: ctx.Literal().Accept(s).(*ExpressionLiteral).String(), + } +} + +func (s *schemaVisitor) VisitMax_len_constraint(ctx *gen.Max_len_constraintContext) any { + return &types.Attribute{ + Type: types.MAX_LENGTH, + Value: ctx.Literal().Accept(s).(*ExpressionLiteral).String(), + } +} + +func (s *schemaVisitor) VisitNot_null_constraint(ctx *gen.Not_null_constraintContext) any { + return &types.Attribute{ + Type: types.NOT_NULL, + } +} + +func (s *schemaVisitor) VisitPrimary_key_constraint(ctx *gen.Primary_key_constraintContext) any { + return &types.Attribute{ + Type: types.PRIMARY_KEY, + } +} + +func (s *schemaVisitor) VisitDefault_constraint(ctx *gen.Default_constraintContext) any { + return &types.Attribute{ + Type: types.DEFAULT, + Value: ctx.Literal().Accept(s).(*ExpressionLiteral).String(), + } +} + +func (s *schemaVisitor) VisitUnique_constraint(ctx *gen.Unique_constraintContext) any { + return &types.Attribute{ + Type: types.UNIQUE, + } +} + +func (s *schemaVisitor) VisitAccess_modifier(ctx *gen.Access_modifierContext) any { + // we will have to parse this at a later stage, since this is either public/private, + // or a types.Modifier + panic("VisitAccess_modifier should not be called") +} + +// getModifiersAndPublicity parses access modifiers and returns. it should be used when +// parsing procedures and actions +func getModifiersAndPublicity(ctxs []gen.IAccess_modifierContext) (public bool, mods []types.Modifier) { + for _, ctx := range ctxs { + switch { + case ctx.PUBLIC() != nil: + public = true + case ctx.PRIVATE() != nil: + public = false + case ctx.VIEW() != nil: + mods = append(mods, types.ModifierView) + case ctx.OWNER() != nil: + mods = append(mods, types.ModifierOwner) + default: + // should not happen, as this would suggest a bug in the parser + panic("unknown access modifier") + } + } + + return +} + +func (s *schemaVisitor) VisitAction_declaration(ctx *gen.Action_declarationContext) any { + act := &types.Action{ + Name: s.getIdent(ctx.IDENTIFIER()), + Annotations: arr[string](len(ctx.AllAnnotation())), + } + + for i, a := range ctx.AllAnnotation() { + act.Annotations[i] = a.Accept(s).(string) + } + + public, mods := getModifiersAndPublicity(ctx.AllAccess_modifier()) + act.Public = public + act.Modifiers = mods + + if ctx.Variable_list() != nil { + params := ctx.Variable_list().Accept(s).([]*ExpressionVariable) + paramStrs := make([]string, len(params)) + for i, p := range params { + paramStrs[i] = p.String() + } + act.Parameters = paramStrs + } + + act.Body = s.stream.GetText(ctx.Action_block().GetStart().GetStart(), ctx.Action_block().GetStop().GetStop()) + + ast := ctx.Action_block().Accept(s).([]ActionStmt) + s.actions[act.Name] = ast + + return act +} + +func (s *schemaVisitor) VisitProcedure_declaration(ctx *gen.Procedure_declarationContext) any { + proc := &types.Procedure{ + Name: s.getIdent(ctx.IDENTIFIER()), + Annotations: arr[string](len(ctx.AllAnnotation())), + } + + if ctx.Typed_variable_list() != nil { + proc.Parameters = ctx.Typed_variable_list().Accept(s).([]*types.ProcedureParameter) + } + + if ctx.Procedure_return() != nil { + proc.Returns = ctx.Procedure_return().Accept(s).(*types.ProcedureReturn) + } + + for i, a := range ctx.AllAnnotation() { + proc.Annotations[i] = a.Accept(s).(string) + } + + public, mods := getModifiersAndPublicity(ctx.AllAccess_modifier()) + proc.Public = public + proc.Modifiers = mods + ast := ctx.Procedure_block().Accept(s).([]ProcedureStmt) + s.procedures[proc.Name] = ast + + proc.Body = s.stream.GetText(ctx.Procedure_block().GetStart().GetStart(), ctx.Procedure_block().GetStop().GetStop()) + + return proc +} + +func (s *schemaVisitor) VisitForeign_procedure_declaration(ctx *gen.Foreign_procedure_declarationContext) any { + fp := &types.ForeignProcedure{ + Name: s.getIdent(ctx.IDENTIFIER()), + } + + if ctx.Procedure_return() != nil { + fp.Returns = ctx.Procedure_return().Accept(s).(*types.ProcedureReturn) + } + + // no default, since foreign procedures can take no inputs optionally + switch { + case ctx.GetUnnamed_params() != nil: + fp.Parameters = ctx.GetUnnamed_params().Accept(s).([]*types.DataType) + case ctx.GetNamed_params() != nil: + ps := ctx.GetNamed_params().Accept(s).([]*types.ProcedureParameter) + var dataTypes []*types.DataType + for _, p := range ps { + dataTypes = append(dataTypes, p.Type) + } + fp.Parameters = dataTypes + } + + return fp +} + +func (s *schemaVisitor) VisitProcedure_return(ctx *gen.Procedure_returnContext) any { + ret := &types.ProcedureReturn{} + + switch { + case ctx.GetReturn_columns() != nil: + ret.Fields = ctx.GetReturn_columns().Accept(s).([]*types.NamedType) + case ctx.GetUnnamed_return_types() != nil: + ret.Fields = make([]*types.NamedType, len(ctx.GetUnnamed_return_types().AllType_())) + for i, t := range ctx.GetUnnamed_return_types().AllType_() { + ret.Fields[i] = &types.NamedType{ + Name: "col" + fmt.Sprint(i), + Type: t.Accept(s).(*types.DataType), + } + } + default: + panic("unknown return type") + } + + if ctx.TABLE() != nil { + ret.IsTable = true + } + + return ret +} + +// VisitSQL visits a SQL statement. It is the top-level SQL visitor. +func (s *schemaVisitor) VisitSql(ctx *gen.SqlContext) any { + return ctx.Sql_statement().Accept(s) +} + +// VisitSql_statement visits a SQL statement. It is called by all nested +// sql statements (e.g. in procedures and actions) +func (s *schemaVisitor) VisitSql_statement(ctx *gen.Sql_statementContext) any { + stmt := &SQLStatement{ + CTEs: arr[*CommonTableExpression](len(ctx.AllCommon_table_expression())), + } + + for i, cte := range ctx.AllCommon_table_expression() { + stmt.CTEs[i] = cte.Accept(s).(*CommonTableExpression) + } + + switch { + case ctx.Select_statement() != nil: + stmt.SQL = ctx.Select_statement().Accept(s).(*SelectStatement) + case ctx.Update_statement() != nil: + stmt.SQL = ctx.Update_statement().Accept(s).(*UpdateStatement) + case ctx.Insert_statement() != nil: + stmt.SQL = ctx.Insert_statement().Accept(s).(*InsertStatement) + case ctx.Delete_statement() != nil: + stmt.SQL = ctx.Delete_statement().Accept(s).(*DeleteStatement) + default: + panic("unknown sql statement") + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitCommon_table_expression(ctx *gen.Common_table_expressionContext) any { + // first identifier is the table name, the rest are the columns + cte := &CommonTableExpression{ + Name: ctx.Identifier(0).Accept(s).(string), + Query: ctx.Select_statement().Accept(s).(*SelectStatement), + } + + for _, id := range ctx.AllIdentifier()[1:] { + cte.Columns = append(cte.Columns, id.Accept(s).(string)) + } + + cte.Set(ctx) + + return cte +} + +func (s *schemaVisitor) VisitSelect_statement(ctx *gen.Select_statementContext) any { + stmt := &SelectStatement{ + SelectCores: arr[*SelectCore](len(ctx.AllSelect_core())), + CompoundOperators: arr[CompoundOperator](len(ctx.AllCompound_operator())), + Ordering: arr[*OrderingTerm](len(ctx.AllOrdering_term())), + } + + for i, core := range ctx.AllSelect_core() { + stmt.SelectCores[i] = core.Accept(s).(*SelectCore) + } + + for i, op := range ctx.AllCompound_operator() { + stmt.CompoundOperators[i] = op.Accept(s).(CompoundOperator) + } + + for i, ord := range ctx.AllOrdering_term() { + stmt.Ordering[i] = ord.Accept(s).(*OrderingTerm) + } + + if ctx.GetLimit() != nil { + stmt.Limit = ctx.GetLimit().Accept(s).(*ExpressionLiteral) + } + if ctx.GetOffset() != nil { + stmt.Offset = ctx.GetOffset().Accept(s).(*ExpressionLiteral) + } + + stmt.Set(ctx) + + return stmt +} + +func (s *schemaVisitor) VisitCompound_operator(ctx *gen.Compound_operatorContext) any { + switch { + case ctx.UNION() != nil: + if ctx.ALL() != nil { + return CompoundOperatorUnionAll + } + return CompoundOperatorUnion + case ctx.INTERSECT() != nil: + return CompoundOperatorIntersect + case ctx.EXCEPT() != nil: + return CompoundOperatorExcept + default: + panic("unknown compound operator") + } +} + +func (s *schemaVisitor) VisitOrdering_term(ctx *gen.Ordering_termContext) any { + ord := &OrderingTerm{ + Expression: ctx.Sql_expr().Accept(s).(Expression), + Order: OrderTypeAsc, + Nulls: NullOrderLast, + } + + if ctx.DESC() != nil { + ord.Order = OrderTypeDesc + } + + if ctx.FIRST() != nil { + ord.Nulls = NullOrderFirst + } + + ord.Set(ctx) + + return ord +} + +func (s *schemaVisitor) VisitSelect_core(ctx *gen.Select_coreContext) any { + stmt := &SelectCore{ + Columns: arr[ResultColumn](len(ctx.AllResult_column())), + Joins: arr[*Join](len(ctx.AllJoin())), + } + + if ctx.DISTINCT() != nil { + stmt.Distinct = true + } + + for i, col := range ctx.AllResult_column() { + stmt.Columns[i] = col.Accept(s).(ResultColumn) + } + + if ctx.Relation() != nil { + stmt.From = ctx.Relation().Accept(s).(Table) + } + + for i, join := range ctx.AllJoin() { + stmt.Joins[i] = join.Accept(s).(*Join) + } + + if ctx.GetWhere() != nil { + stmt.Where = ctx.GetWhere().Accept(s).(Expression) + } + + if ctx.GetGroup_by() != nil { + stmt.GroupBy = ctx.GetGroup_by().Accept(s).([]Expression) + } + + if ctx.GetHaving() != nil { + stmt.Having = ctx.GetHaving().Accept(s).(Expression) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitTable_relation(ctx *gen.Table_relationContext) any { + t := &RelationTable{ + Table: strings.ToLower(ctx.GetTable_name().Accept(s).(string)), + } + + if ctx.GetAlias() != nil { + t.Alias = strings.ToLower(ctx.GetAlias().Accept(s).(string)) + } + + t.Set(ctx) + return t +} + +func (s *schemaVisitor) VisitSubquery_relation(ctx *gen.Subquery_relationContext) any { + t := &RelationSubquery{ + Subquery: ctx.Select_statement().Accept(s).(*SelectStatement), + } + + // alias is technially required here, but we allow it in the grammar + // to throw a better error message here. + if ctx.Identifier() != nil { + t.Alias = ctx.Identifier().Accept(s).(string) + } + + t.Set(ctx) + return t +} + +func (s *schemaVisitor) VisitFunction_relation(ctx *gen.Function_relationContext) any { + t := &RelationFunctionCall{ + FunctionCall: ctx.Sql_function_call().Accept(s).(ExpressionCall), + } + + // alias is technially required here, but we allow it in the grammar + // to throw a better error message here. + if ctx.Identifier() != nil { + t.Alias = ctx.Identifier().Accept(s).(string) + } + + t.Set(ctx) + return t +} + +func (s *schemaVisitor) VisitJoin(ctx *gen.JoinContext) any { + j := &Join{ + Relation: ctx.Relation().Accept(s).(Table), + On: ctx.Sql_expr().Accept(s).(Expression), + } + switch { + case ctx.LEFT() != nil: + j.Type = JoinTypeLeft + case ctx.RIGHT() != nil: + j.Type = JoinTypeRight + case ctx.FULL() != nil: + j.Type = JoinTypeFull + case ctx.INNER() != nil: + j.Type = JoinTypeInner + default: + panic("unknown join type") + } + + j.Set(ctx) + return j +} + +func (s *schemaVisitor) VisitExpression_result_column(ctx *gen.Expression_result_columnContext) any { + col := &ResultColumnExpression{ + Expression: ctx.Sql_expr().Accept(s).(Expression), + } + + if ctx.Identifier() != nil { + col.Alias = ctx.Identifier().Accept(s).(string) + } + + col.Set(ctx) + return col +} + +func (s *schemaVisitor) VisitWildcard_result_column(ctx *gen.Wildcard_result_columnContext) any { + col := &ResultColumnWildcard{} + + if ctx.Identifier() != nil { + col.Table = ctx.Identifier().Accept(s).(string) + } + + col.Set(ctx) + return col +} + +func (s *schemaVisitor) VisitUpdate_statement(ctx *gen.Update_statementContext) any { + up := &UpdateStatement{ + Table: ctx.GetTable_name().Accept(s).(string), + SetClause: arr[*UpdateSetClause](len(ctx.AllUpdate_set_clause())), + Joins: arr[*Join](len(ctx.AllJoin())), + } + + if ctx.GetAlias() != nil { + up.Alias = ctx.GetAlias().Accept(s).(string) + } + + for i, set := range ctx.AllUpdate_set_clause() { + up.SetClause[i] = set.Accept(s).(*UpdateSetClause) + } + + if ctx.Relation() != nil { + up.From = ctx.Relation().Accept(s).(Table) + } + + for i, join := range ctx.AllJoin() { + up.Joins[i] = join.Accept(s).(*Join) + } + + if ctx.GetWhere() != nil { + up.Where = ctx.GetWhere().Accept(s).(Expression) + } + + up.Set(ctx) + return up +} + +func (s *schemaVisitor) VisitUpdate_set_clause(ctx *gen.Update_set_clauseContext) any { + u := &UpdateSetClause{ + Column: ctx.GetColumn().Accept(s).(string), + Value: ctx.Sql_expr().Accept(s).(Expression), + } + + u.Set(ctx) + return u +} + +func (s *schemaVisitor) VisitInsert_statement(ctx *gen.Insert_statementContext) any { + ins := &InsertStatement{ + Table: ctx.GetTable_name().Accept(s).(string), + } + + for _, valList := range ctx.AllSql_expr_list() { + ins.Values = append(ins.Values, valList.Accept(s).([]Expression)) + } + + if ctx.GetAlias() != nil { + ins.Alias = ctx.GetAlias().Accept(s).(string) + } + + if ctx.Identifier_list() != nil { + ins.Columns = ctx.Identifier_list().Accept(s).([]string) + } + + if ctx.Upsert_clause() != nil { + ins.Upsert = ctx.Upsert_clause().Accept(s).(*UpsertClause) + } + + ins.Set(ctx) + return ins +} + +func (s *schemaVisitor) VisitUpsert_clause(ctx *gen.Upsert_clauseContext) any { + u := &UpsertClause{} + + if ctx.GetConflict_columns() != nil { + u.ConflictColumns = ctx.GetConflict_columns().Accept(s).([]string) + } + + if ctx.GetConflict_where() != nil { + u.ConflictWhere = ctx.GetConflict_where().Accept(s).(Expression) + } + + if ctx.UPDATE() != nil { + for _, set := range ctx.AllUpdate_set_clause() { + u.DoUpdate = append(u.DoUpdate, set.Accept(s).(*UpdateSetClause)) + } + } + + if ctx.GetUpdate_where() != nil { + u.UpdateWhere = ctx.GetUpdate_where().Accept(s).(Expression) + } + + u.Set(ctx) + return u +} + +func (s *schemaVisitor) VisitDelete_statement(ctx *gen.Delete_statementContext) any { + d := &DeleteStatement{ + Table: ctx.GetTable_name().Accept(s).(string), + } + + if ctx.GetAlias() != nil { + d.Alias = ctx.GetAlias().Accept(s).(string) + } + + if ctx.GetWhere() != nil { + d.Where = ctx.GetWhere().Accept(s).(Expression) + } + + d.Set(ctx) + return d +} + +func (s *schemaVisitor) VisitColumn_sql_expr(ctx *gen.Column_sql_exprContext) any { + e := &ExpressionColumn{ + Column: ctx.GetColumn().Accept(s).(string), + } + + if ctx.GetTable() != nil { + e.Table = ctx.GetTable().Accept(s).(string) + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitLogical_sql_expr(ctx *gen.Logical_sql_exprContext) any { + e := &ExpressionLogical{ + Left: ctx.Sql_expr(0).Accept(s).(Expression), + Right: ctx.Sql_expr(1).Accept(s).(Expression), + } + + switch { + case ctx.AND() != nil: + e.Operator = LogicalOperatorAnd + case ctx.OR() != nil: + e.Operator = LogicalOperatorOr + default: + panic("unknown logical operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitArray_access_sql_expr(ctx *gen.Array_access_sql_exprContext) any { + e := &ExpressionArrayAccess{ + Array: ctx.Sql_expr(0).Accept(s).(Expression), + Index: ctx.Sql_expr(1).Accept(s).(Expression), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitField_access_sql_expr(ctx *gen.Field_access_sql_exprContext) any { + e := &ExpressionFieldAccess{ + Record: ctx.Sql_expr().Accept(s).(Expression), + Field: ctx.Identifier().Accept(s).(string), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitComparison_sql_expr(ctx *gen.Comparison_sql_exprContext) any { + e := &ExpressionComparison{ + Left: ctx.Sql_expr(0).Accept(s).(Expression), + Right: ctx.Sql_expr(1).Accept(s).(Expression), + } + + switch { + case ctx.EQUALS() != nil || ctx.EQUATE() != nil: + e.Operator = ComparisonOperatorEqual + case ctx.NEQ() != nil: + e.Operator = ComparisonOperatorNotEqual + case ctx.LT() != nil: + e.Operator = ComparisonOperatorLessThan + case ctx.LTE() != nil: + e.Operator = ComparisonOperatorLessThanOrEqual + case ctx.GT() != nil: + e.Operator = ComparisonOperatorGreaterThan + case ctx.GTE() != nil: + e.Operator = ComparisonOperatorGreaterThanOrEqual + default: + panic("unknown comparison operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitLiteral_sql_expr(ctx *gen.Literal_sql_exprContext) any { + e := ctx.Literal().Accept(s).(*ExpressionLiteral) + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitBetween_sql_expr(ctx *gen.Between_sql_exprContext) any { + e := &ExpressionBetween{ + Expression: ctx.GetElement().Accept(s).(Expression), + Lower: ctx.GetLower().Accept(s).(Expression), + Upper: ctx.GetUpper().Accept(s).(Expression), + } + + if ctx.NOT() != nil { + e.Not = true + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitFunction_call_sql_expr(ctx *gen.Function_call_sql_exprContext) any { + call := ctx.Sql_function_call().Accept(s).(ExpressionCall) + + if ctx.Type_cast() != nil { + call.Cast(ctx.Type_cast().Accept(s).(*types.DataType)) + } + + call.Set(ctx) + + return call +} + +func (s *schemaVisitor) VisitParen_sql_expr(ctx *gen.Paren_sql_exprContext) any { + e := &ExpressionParenthesized{ + Inner: ctx.Sql_expr().Accept(s).(Expression), + } + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitCollate_sql_expr(ctx *gen.Collate_sql_exprContext) any { + e := &ExpressionCollate{ + Expression: ctx.Sql_expr().Accept(s).(Expression), + Collation: ctx.Identifier().Accept(s).(string), + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitVariable_sql_expr(ctx *gen.Variable_sql_exprContext) any { + e := ctx.Variable().Accept(s).(*ExpressionVariable) + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitIs_sql_expr(ctx *gen.Is_sql_exprContext) any { + e := &ExpressionIs{ + Left: ctx.GetLeft().Accept(s).(Expression), + } + + if ctx.NOT() != nil { + e.Not = true + } + + if ctx.DISTINCT() != nil { + e.Distinct = true + } + + switch { + case ctx.NULL() != nil: + e.Right = &ExpressionLiteral{ + Type: types.NullType, + } + e.Right.SetToken(ctx.NULL().GetSymbol()) + case ctx.TRUE() != nil: + e.Right = &ExpressionLiteral{ + Type: types.BoolType, + Value: true, + } + e.Right.SetToken(ctx.TRUE().GetSymbol()) + case ctx.FALSE() != nil: + e.Right = &ExpressionLiteral{ + Type: types.BoolType, + Value: false, + } + e.Right.SetToken(ctx.FALSE().GetSymbol()) + case ctx.GetRight() != nil: + e.Right = ctx.GetRight().Accept(s).(Expression) + default: + panic("unknown right side of IS") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitLike_sql_expr(ctx *gen.Like_sql_exprContext) any { + e := &ExpressionStringComparison{ + Left: ctx.GetLeft().Accept(s).(Expression), + Right: ctx.GetRight().Accept(s).(Expression), + Operator: StringComparisonOperatorLike, + } + + if ctx.NOT() != nil { + e.Operator = StringComparisonOperatorNotLike + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitArithmetic_sql_expr(ctx *gen.Arithmetic_sql_exprContext) any { + e := &ExpressionArithmetic{ + Left: ctx.GetLeft().Accept(s).(Expression), + Right: ctx.GetRight().Accept(s).(Expression), + } + + switch { + case ctx.PLUS() != nil: + e.Operator = ArithmeticOperatorAdd + case ctx.MINUS() != nil: + e.Operator = ArithmeticOperatorSubtract + case ctx.STAR() != nil: + e.Operator = ArithmeticOperatorMultiply + case ctx.DIV() != nil: + e.Operator = ArithmeticOperatorDivide + case ctx.MOD() != nil: + e.Operator = ArithmeticOperatorModulo + case ctx.CONCAT() != nil: + e.Operator = ArithmeticOperatorConcat + default: + panic("unknown arithmetic operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitUnary_sql_expr(ctx *gen.Unary_sql_exprContext) any { + e := &ExpressionUnary{ + Expression: ctx.Sql_expr().Accept(s).(Expression), + } + + // this is the only known unary right now + switch { + case ctx.NOT() != nil: + e.Operator = UnaryOperatorNot + case ctx.MINUS() != nil: + e.Operator = UnaryOperatorNeg + case ctx.PLUS() != nil: + e.Operator = UnaryOperatorPos + default: + panic("unknown unary operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitSubquery_sql_expr(ctx *gen.Subquery_sql_exprContext) any { + e := &ExpressionSubquery{ + Subquery: ctx.Select_statement().Accept(s).(*SelectStatement), + } + + if ctx.NOT() != nil { + e.Not = true + } + + if ctx.EXISTS() != nil { + e.Exists = true + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitCase_expr(ctx *gen.Case_exprContext) any { + e := &ExpressionCase{} + if ctx.GetCase_clause() != nil { + e.Case = ctx.GetCase_clause().Accept(s).(Expression) + } + + for i := range ctx.AllWhen_then_clause() { + wt := ctx.AllWhen_then_clause()[i].Accept(s).([2]Expression) + + e.WhenThen = append(e.WhenThen, wt) + } + + if ctx.GetElse_clause() != nil { + e.Else = ctx.GetElse_clause().Accept(s).(Expression) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitWhen_then_clause(ctx *gen.When_then_clauseContext) any { + when := ctx.Sql_expr(0).Accept(s).(Expression) + then := ctx.Sql_expr(1).Accept(s).(Expression) + return [2]Expression{when, then} +} + +func (s *schemaVisitor) VisitIn_sql_expr(ctx *gen.In_sql_exprContext) any { + e := &ExpressionIn{ + Expression: ctx.Sql_expr().Accept(s).(Expression), + } + + if ctx.NOT() != nil { + e.Not = true + } + + if ctx.Sql_expr_list() != nil { + e.List = ctx.Sql_expr_list().Accept(s).([]Expression) + } else { + e.Subquery = ctx.Select_statement().Accept(s).(*SelectStatement) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitSql_expr_list(ctx *gen.Sql_expr_listContext) any { + + var e []Expression + for _, e2 := range ctx.AllSql_expr() { + e = append(e, e2.Accept(s).(Expression)) + } + + return e +} + +func (s *schemaVisitor) VisitNormal_call_sql(ctx *gen.Normal_call_sqlContext) any { + call := &ExpressionFunctionCall{ + Name: ctx.Identifier().Accept(s).(string), + } + + // function calls can have either of these types for args, + // or none at all. + switch { + case ctx.Sql_expr_list() != nil: + call.Args = ctx.Sql_expr_list().Accept(s).([]Expression) + if ctx.DISTINCT() != nil { + call.Distinct = true + } + case ctx.STAR() != nil: + call.Star = true + } + + call.Set(ctx) + return call +} + +func (s *schemaVisitor) VisitForeign_call_sql(ctx *gen.Foreign_call_sqlContext) any { + e := &ExpressionForeignCall{ + Name: ctx.Identifier().Accept(s).(string), + } + + if ctx.Sql_expr_list() != nil { + e.Args = ctx.Sql_expr_list().Accept(s).([]Expression) + } + + dbid := ctx.GetDbid().Accept(s).(Expression) + proc := ctx.GetProcedure().Accept(s).(Expression) + e.ContextualArgs = append(e.ContextualArgs, dbid, proc) + + e.Set(ctx) + + return e +} + +func (s *schemaVisitor) VisitAction_block(ctx *gen.Action_blockContext) any { + var stmts []ActionStmt + + for _, stmt := range ctx.AllAction_statement() { + stmts = append(stmts, stmt.Accept(s).(ActionStmt)) + } + + return stmts +} + +func (s *schemaVisitor) VisitSql_action(ctx *gen.Sql_actionContext) any { + stmt := &ActionStmtSQL{ + SQL: ctx.Sql_statement().Accept(s).(*SQLStatement), + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitLocal_action(ctx *gen.Local_actionContext) any { + stmt := &ActionStmtActionCall{ + Action: s.getIdent(ctx.IDENTIFIER()), + } + + if ctx.Procedure_expr_list() != nil { + stmt.Args = ctx.Procedure_expr_list().Accept(s).([]Expression) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitExtension_action(ctx *gen.Extension_actionContext) any { + stmt := &ActionStmtExtensionCall{ + Extension: s.getIdent(ctx.IDENTIFIER(0)), + Method: s.getIdent(ctx.IDENTIFIER(1)), + } + + if ctx.Procedure_expr_list() != nil { + stmt.Args = ctx.Procedure_expr_list().Accept(s).([]Expression) + } + + if ctx.Variable_list() != nil { + varList := ctx.Variable_list().Accept(s).([]*ExpressionVariable) + for _, v := range varList { + stmt.Receivers = append(stmt.Receivers, v.String()) + } + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitProcedure_block(ctx *gen.Procedure_blockContext) any { + var stmts []ProcedureStmt + + for _, stmt := range ctx.AllProc_statement() { + stmts = append(stmts, stmt.Accept(s).(ProcedureStmt)) + } + + return stmts +} + +func (s *schemaVisitor) VisitField_access_procedure_expr(ctx *gen.Field_access_procedure_exprContext) any { + e := &ExpressionFieldAccess{ + Record: ctx.Procedure_expr().Accept(s).(Expression), + Field: s.getIdent(ctx.IDENTIFIER()), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + + return e +} + +func (s *schemaVisitor) VisitLiteral_procedure_expr(ctx *gen.Literal_procedure_exprContext) any { + e := ctx.Literal().Accept(s).(*ExpressionLiteral) + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitParen_procedure_expr(ctx *gen.Paren_procedure_exprContext) any { + e := &ExpressionParenthesized{ + Inner: ctx.Procedure_expr().Accept(s).(Expression), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitVariable_procedure_expr(ctx *gen.Variable_procedure_exprContext) any { + e := ctx.Variable().Accept(s).(*ExpressionVariable) + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitProcedure_expr_arithmetic(ctx *gen.Procedure_expr_arithmeticContext) any { + e := &ExpressionArithmetic{ + Left: ctx.Procedure_expr(0).Accept(s).(Expression), + Right: ctx.Procedure_expr(1).Accept(s).(Expression), + } + + switch { + case ctx.PLUS() != nil: + e.Operator = ArithmeticOperatorAdd + case ctx.MINUS() != nil: + e.Operator = ArithmeticOperatorSubtract + case ctx.STAR() != nil: + e.Operator = ArithmeticOperatorMultiply + case ctx.DIV() != nil: + e.Operator = ArithmeticOperatorDivide + case ctx.MOD() != nil: + e.Operator = ArithmeticOperatorModulo + case ctx.CONCAT() != nil: + e.Operator = ArithmeticOperatorConcat + default: + panic("unknown arithmetic operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitComparison_procedure_expr(ctx *gen.Comparison_procedure_exprContext) any { + e := &ExpressionComparison{ + Left: ctx.Procedure_expr(0).Accept(s).(Expression), + Right: ctx.Procedure_expr(1).Accept(s).(Expression), + } + + switch { + case ctx.EQUALS() != nil || ctx.EQUATE() != nil: + e.Operator = ComparisonOperatorEqual + case ctx.NEQ() != nil: + e.Operator = ComparisonOperatorNotEqual + case ctx.LT() != nil: + e.Operator = ComparisonOperatorLessThan + case ctx.LTE() != nil: + e.Operator = ComparisonOperatorLessThanOrEqual + case ctx.GT() != nil: + e.Operator = ComparisonOperatorGreaterThan + case ctx.GTE() != nil: + e.Operator = ComparisonOperatorGreaterThanOrEqual + default: + panic("unknown comparison operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitFunction_call_procedure_expr(ctx *gen.Function_call_procedure_exprContext) any { + call := ctx.Procedure_function_call().Accept(s).(ExpressionCall) + + if ctx.Type_cast() != nil { + call.Cast(ctx.Type_cast().Accept(s).(*types.DataType)) + } + + call.Set(ctx) + + return call +} + +func (s *schemaVisitor) VisitArray_access_procedure_expr(ctx *gen.Array_access_procedure_exprContext) any { + e := &ExpressionArrayAccess{ + Array: ctx.Procedure_expr(0).Accept(s).(Expression), + Index: ctx.Procedure_expr(1).Accept(s).(Expression), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitUnary_procedure_expr(ctx *gen.Unary_procedure_exprContext) any { + e := &ExpressionUnary{ + Expression: ctx.Procedure_expr().Accept(s).(Expression), + } + + // this is the only known unary right now + switch { + case ctx.EXCL() != nil: + e.Operator = UnaryOperatorNot + case ctx.MINUS() != nil: + e.Operator = UnaryOperatorNeg + case ctx.PLUS() != nil: + e.Operator = UnaryOperatorPos + default: + panic("unknown unary operator") + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitMake_array_procedure_expr(ctx *gen.Make_array_procedure_exprContext) any { + e := &ExpressionMakeArray{ + // golang interface assertions do not work for slices, so we simply + // cast the result to []Expression. This comes from VisitProcedure_expr_list, + // directly below. + Values: ctx.Procedure_expr_list().Accept(s).([]Expression), + } + + if ctx.Type_cast() != nil { + e.TypeCast = ctx.Type_cast().Accept(s).(*types.DataType) + } + + e.Set(ctx) + return e +} + +func (s *schemaVisitor) VisitProcedure_expr_list(ctx *gen.Procedure_expr_listContext) any { + // we do not return a type ExpressionList here, since ExpressionList is SQL specific, + // and not supported in procedures. Instead, we return a slice of Expression. + var exprs []Expression + + for _, e := range ctx.AllProcedure_expr() { + exprs = append(exprs, e.Accept(s).(Expression)) + } + + return exprs +} + +func (s *schemaVisitor) VisitStmt_variable_declaration(ctx *gen.Stmt_variable_declarationContext) any { + stmt := &ProcedureStmtDeclaration{ + Variable: varFromTerminalNode(ctx.VARIABLE()), + } + + if ctx.Type_() != nil { + stmt.Type = ctx.Type_().Accept(s).(*types.DataType) + } + + stmt.Set(ctx) + return stmt +} + +// varFromTerminalNode returns a variable from an antlr terminal node. +// If the string is not a valid variable, it panics. +// This is only meant to be used when creating expressions +// directly from the AST. It will lowercase the string to +// ensure case-insensitivity. +func varFromTerminalNode(node antlr.TerminalNode) *ExpressionVariable { + s := node.GetText() + e := varFromString(s) + e.SetToken(node.GetSymbol()) + + return e +} + +// varFromString returns a variable from a string. +func varFromString(s string) *ExpressionVariable { + e := &ExpressionVariable{} + if len(s) < 2 { + panic("invalid variable: " + s) + } + + switch { + case s[0] == '$': + e.Prefix = VariablePrefixDollar + case s[0] == '@': + e.Prefix = VariablePrefixAt + default: + panic("invalid variable: " + s) + } + + e.Name = strings.ToLower(s[1:]) + + return e +} + +func (s *schemaVisitor) VisitStmt_procedure_call(ctx *gen.Stmt_procedure_callContext) any { + stmt := &ProcedureStmtCall{ + Call: ctx.Procedure_function_call().Accept(s).(ExpressionCall), + } + + for _, v := range ctx.AllVariable_or_underscore() { + // check for nil since nil pointer will fail *string type assertion + if v.Accept(s) == nil { + stmt.Receivers = append(stmt.Receivers, nil) + continue + } + + stmt.Receivers = append(stmt.Receivers, varFromString(*v.Accept(s).(*string))) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitVariable_or_underscore(ctx *gen.Variable_or_underscoreContext) any { + if ctx.UNDERSCORE() != nil { + return nil + } + + str := s.getIdent(ctx.VARIABLE()) + return &str +} + +func (s *schemaVisitor) VisitStmt_variable_assignment(ctx *gen.Stmt_variable_assignmentContext) any { + stmt := &ProcedureStmtAssign{ + Variable: varFromTerminalNode(ctx.VARIABLE()), + Value: ctx.Procedure_expr().Accept(s).(Expression), + } + + if ctx.Type_() != nil { + stmt.Type = ctx.Type_().Accept(s).(*types.DataType) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitStmt_for_loop(ctx *gen.Stmt_for_loopContext) any { + stmt := &ProcedureStmtForLoop{ + Receiver: varFromTerminalNode(ctx.VARIABLE()), + Body: arr[ProcedureStmt](len(ctx.AllProc_statement())), + } + + switch { + case ctx.Range_() != nil: + stmt.LoopTerm = ctx.Range_().Accept(s).(*LoopTermRange) + case ctx.GetTarget_variable() != nil: + v := ctx.GetTarget_variable().Accept(s).(*ExpressionVariable) + stmt.LoopTerm = &LoopTermVariable{ + Variable: v, + } + + if v.GetTypeCast() != nil { + s.errs.RuleErr(ctx.GetTarget_variable(), ErrSyntax, "cannot typecast loop variable") + } + + stmt.LoopTerm.Set(ctx.GetTarget_variable()) + case ctx.Sql_statement() != nil: + sqlStmt := ctx.Sql_statement().Accept(s).(*SQLStatement) + stmt.LoopTerm = &LoopTermSQL{ + Statement: sqlStmt, + } + stmt.LoopTerm.Set(ctx.Sql_statement()) + default: + panic("unknown loop term") + } + + for i, st := range ctx.AllProc_statement() { + stmt.Body[i] = st.Accept(s).(ProcedureStmt) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitStmt_if(ctx *gen.Stmt_ifContext) any { + stmt := &ProcedureStmtIf{ + IfThens: arr[*IfThen](len(ctx.AllIf_then_block())), + Else: arr[ProcedureStmt](len(ctx.AllProc_statement())), + } + + for i, th := range ctx.AllIf_then_block() { + stmt.IfThens[i] = th.Accept(s).(*IfThen) + } + + for i, st := range ctx.AllProc_statement() { + stmt.Else[i] = st.Accept(s).(ProcedureStmt) + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitIf_then_block(ctx *gen.If_then_blockContext) any { + ifthen := &IfThen{ + If: ctx.Procedure_expr().Accept(s).(Expression), + Then: arr[ProcedureStmt](len(ctx.AllProc_statement())), + } + + for i, st := range ctx.AllProc_statement() { + ifthen.Then[i] = st.Accept(s).(ProcedureStmt) + } + + ifthen.Set(ctx) + + return ifthen +} + +func (s *schemaVisitor) VisitStmt_sql(ctx *gen.Stmt_sqlContext) any { + stmt := &ProcedureStmtSQL{ + SQL: ctx.Sql_statement().Accept(s).(*SQLStatement), + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitStmt_break(ctx *gen.Stmt_breakContext) any { + stmt := &ProcedureStmtBreak{} + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitStmt_return(ctx *gen.Stmt_returnContext) any { + stmt := &ProcedureStmtReturn{} + + switch { + case ctx.Sql_statement() != nil: + stmt.SQL = ctx.Sql_statement().Accept(s).(*SQLStatement) + case ctx.Procedure_expr_list() != nil: + // loop through and add since these are Expressions, not Expressions + exprs := ctx.Procedure_expr_list().Accept(s).([]Expression) + stmt.Values = append(stmt.Values, exprs...) + default: + panic("unknown return type") + } + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitStmt_return_next(ctx *gen.Stmt_return_nextContext) any { + stmt := &ProcedureStmtReturnNext{} + + vals := ctx.Procedure_expr_list().Accept(s).([]Expression) + stmt.Values = append(stmt.Values, vals...) + + stmt.Set(ctx) + return stmt +} + +func (s *schemaVisitor) VisitNormal_call_procedure(ctx *gen.Normal_call_procedureContext) any { + call := &ExpressionFunctionCall{ + Name: s.getIdent(ctx.IDENTIFIER()), + } + + // distinct and * cannot be used in procedure function calls + if ctx.Procedure_expr_list() != nil { + call.Args = ctx.Procedure_expr_list().Accept(s).([]Expression) + } + + call.Set(ctx) + return call +} + +func (s *schemaVisitor) VisitForeign_call_procedure(ctx *gen.Foreign_call_procedureContext) any { + e := &ExpressionForeignCall{ + Name: s.getIdent(ctx.IDENTIFIER()), + } + + if ctx.Procedure_expr_list() != nil { + e.Args = ctx.Procedure_expr_list().Accept(s).([]Expression) + } + + dbid := ctx.GetDbid().Accept(s).(Expression) + proc := ctx.GetProcedure().Accept(s).(Expression) + e.ContextualArgs = append(e.ContextualArgs, dbid, proc) + + e.Set(ctx) + + return e +} + +func (s *schemaVisitor) VisitRange(ctx *gen.RangeContext) any { + r := &LoopTermRange{ + Start: ctx.Procedure_expr(0).Accept(s).(Expression), + End: ctx.Procedure_expr(1).Accept(s).(Expression), + } + + r.Set(ctx) + return r +} + +func (s *schemaVisitor) Visit(tree antlr.ParseTree) interface { +} { + return tree.Accept(s) +} + +// getIdent returns the text of an identifier. +// It checks that the identifier is not too long. +// It also converts the identifier to lowercase. +func (s *schemaVisitor) getIdent(i antlr.TerminalNode) string { + ident := i.GetText() + s.validateVariableIdentifier(i.GetSymbol(), ident) + return strings.ToLower(ident) +} + +// validateVariableIdentifier validates that a variable's identifier is not too long. +// It doesn't check if it is a keyword, since variables have $ prefixes. +func (s *schemaVisitor) validateVariableIdentifier(i antlr.Token, str string) { + if len(str) > validation.MAX_IDENT_NAME_LENGTH { + s.errs.TokenErr(i, ErrIdentifier, "maximum identifier length is %d", maxIdentifierLength) + } +} + +// pg max is 63, but Kwil sometimes adds extra characters +var maxIdentifierLength = 32 diff --git a/parse/ast.go b/parse/ast.go new file mode 100644 index 000000000..636e60b70 --- /dev/null +++ b/parse/ast.go @@ -0,0 +1,1139 @@ +package parse + +import ( + "encoding/hex" + "fmt" + "strings" + + "github.com/antlr4-go/antlr/v4" + "github.com/holiman/uint256" + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/types/decimal" +) + +// this file contains the ASTs for SQL, procedures, and actions. + +// Node is a node in the AST. +type Node interface { + Accept(Visitor) any + GetPosition() *Position + Set(r antlr.ParserRuleContext) + SetToken(t antlr.Token) +} + +type Typecastable struct { + TypeCast *types.DataType +} + +func (t *Typecastable) Cast(t2 *types.DataType) { + t.TypeCast = t2 +} + +func (t *Typecastable) GetTypeCast() *types.DataType { + return t.TypeCast +} + +// Expression is an interface for all expressions. +type Expression interface { + Node +} + +// ExpressionLiteral is a literal expression. +type ExpressionLiteral struct { + Position + Typecastable + Type *types.DataType + // Value is the value of the literal. + // It must be of type string, int64, bool, *uint256.Int, *decimal.Decimal, + // or nil + Value any +} + +func (e *ExpressionLiteral) Accept(v Visitor) any { + return v.VisitExpressionLiteral(e) +} + +// String returns the string representation of the literal. +func (e *ExpressionLiteral) String() string { + s, err := literalToString(e.Value) + if err != nil { + panic(err.Error() + ": " + fmt.Sprintf("%T", e.Value)) + } + return s +} + +// literalToString formats a literal value to be used in a SQL / DDL statement. +func literalToString(value any) (string, error) { + str := strings.Builder{} + switch v := value.(type) { + case string: // for text type + str.WriteString("'" + v + "'") + case int64, int, int32: // for int type + str.WriteString(fmt.Sprint(v)) + case types.UUID: + str.WriteString(v.String()) + case *uint256.Int: + str.WriteString(v.String()) + case *decimal.Decimal: + str.WriteString(v.String()) + case bool: // for bool type + if v { + str.WriteString("true") + } + str.WriteString("false") + case []byte: + str.WriteString("0x" + hex.EncodeToString(v)) + case nil: + // do nothing + default: + return "", fmt.Errorf("unsupported literal type: %T", v) + } + + return str.String(), nil +} + +type ExpressionCall interface { + Expression + Cast(*types.DataType) + GetTypeCast() *types.DataType + FunctionName() string +} + +// ExpressionFunctionCall is a function call expression. +type ExpressionFunctionCall struct { + Position + Typecastable + // Name is the name of the function. + Name string + // Args are the arguments to the function call. + // They are passed using () + Args []Expression + // Distinct is true if the function call is a DISTINCT function call. + Distinct bool + // Star is true if the function call is a * function call. + // If it is set, then Args must be empty. + Star bool +} + +var _ ExpressionCall = (*ExpressionFunctionCall)(nil) + +func (e *ExpressionFunctionCall) Accept(v Visitor) any { + return v.VisitExpressionFunctionCall(e) +} + +func (e *ExpressionFunctionCall) FunctionName() string { + return e.Name +} + +// ExpressionForeignCall is a call to an external procedure. +type ExpressionForeignCall struct { + Position + Typecastable + // Name is the name of the function. + Name string + // ContextualArgs are arguments that are contextual to the function call. + // They are passed using [] + ContextualArgs []Expression + // Args are the arguments to the function call. + // They are passed using () + Args []Expression +} + +func (e *ExpressionForeignCall) Accept(v Visitor) any { + return v.VisitExpressionForeignCall(e) +} + +func (e *ExpressionForeignCall) FunctionName() string { + return e.Name +} + +var _ ExpressionCall = (*ExpressionForeignCall)(nil) + +// ExpressionVariable is a variable. +// This can either be $ or @ variables. +type ExpressionVariable struct { + Position + Typecastable + // Name is the naem of the variable, + // without the $ or @. + Name string + // Prefix is the $ or @ prefix. + Prefix VariablePrefix +} + +func (e *ExpressionVariable) Accept(v Visitor) any { + return v.VisitExpressionVariable(e) +} + +// String returns the string representation, as it was passed +// in Kuneiform. +func (e *ExpressionVariable) String() string { + return string(e.Prefix) + e.Name +} + +type VariablePrefix string + +const ( + VariablePrefixDollar VariablePrefix = "$" + VariablePrefixAt VariablePrefix = "@" +) + +// ExpressionArrayAccess accesses an array value. +type ExpressionArrayAccess struct { + Position + Typecastable + // Array is the array that is being accessed. + Array Expression + // Index is the index that is being accessed. + Index Expression +} + +func (e *ExpressionArrayAccess) Accept(v Visitor) any { + return v.VisitExpressionArrayAccess(e) +} + +// ExpressionMakeArray makes a new array. +type ExpressionMakeArray struct { + Position + Typecastable + Values []Expression +} + +func (e *ExpressionMakeArray) Accept(v Visitor) any { + return v.VisitExpressionMakeArray(e) +} + +// ExpressionFieldAccess accesses a field in a record. +type ExpressionFieldAccess struct { + Position + Typecastable + // Record is the record that is being accessed. + Record Expression + // Field is the field that is being accessed. + Field string +} + +func (e *ExpressionFieldAccess) Accept(v Visitor) any { + return v.VisitExpressionFieldAccess(e) +} + +// ExpressionParenthesized is a parenthesized expression. +type ExpressionParenthesized struct { + Position + Typecastable + // Inner is the inner expression. + Inner Expression +} + +func (e *ExpressionParenthesized) Accept(v Visitor) any { + return v.VisitExpressionParenthesized(e) +} + +// ExpressionComparison is a comparison expression. +type ExpressionComparison struct { + Position + // Left is the left side of the comparison. + Left Expression + // Right is the right side of the comparison. + Right Expression + // Operator is the operator of the comparison. + Operator ComparisonOperator +} + +func (e *ExpressionComparison) Accept(v Visitor) any { + return v.VisitExpressionComparison(e) +} + +type ComparisonOperator string + +const ( + ComparisonOperatorEqual ComparisonOperator = "=" + ComparisonOperatorNotEqual ComparisonOperator = "!=" + ComparisonOperatorGreaterThan ComparisonOperator = ">" + ComparisonOperatorLessThan ComparisonOperator = "<" + ComparisonOperatorGreaterThanOrEqual ComparisonOperator = ">=" + ComparisonOperatorLessThanOrEqual ComparisonOperator = "<=" +) + +// ExpressionLogical is a logical expression. +type ExpressionLogical struct { + Position + // Left is the left side of the logical expression. + Left Expression + // Right is the right side of the logical expression. + Right Expression + // Operator is the operator of the logical expression. + Operator LogicalOperator +} + +func (e *ExpressionLogical) Accept(v Visitor) any { + return v.VisitExpressionLogical(e) +} + +type LogicalOperator string + +const ( + LogicalOperatorAnd LogicalOperator = "and" + LogicalOperatorOr LogicalOperator = "or" +) + +// ExpressionArithmetic is an arithmetic expression. +type ExpressionArithmetic struct { + Position + // Left is the left side of the arithmetic expression. + Left Expression + // Right is the right side of the arithmetic expression. + Right Expression + // Operator is the operator of the arithmetic expression. + Operator ArithmeticOperator +} + +func (e *ExpressionArithmetic) Accept(v Visitor) any { + return v.VisitExpressionArithmetic(e) +} + +type ArithmeticOperator string + +const ( + ArithmeticOperatorAdd ArithmeticOperator = "+" + ArithmeticOperatorSubtract ArithmeticOperator = "-" + ArithmeticOperatorMultiply ArithmeticOperator = "*" + ArithmeticOperatorDivide ArithmeticOperator = "/" + ArithmeticOperatorModulo ArithmeticOperator = "%" + ArithmeticOperatorConcat ArithmeticOperator = "||" +) + +type ExpressionUnary struct { + Position + // Expression is the expression that is being operated on. + Expression Expression + // Operator is the operator of the unary expression. + Operator UnaryOperator +} + +func (e *ExpressionUnary) Accept(v Visitor) any { + return v.VisitExpressionUnary(e) +} + +type UnaryOperator string + +const ( + // Not can be either NOT or ! + UnaryOperatorNot UnaryOperator = "not" + UnaryOperatorNeg UnaryOperator = "-" + UnaryOperatorPos UnaryOperator = "+" +) + +// ExpressionColumn is a column in a table. +type ExpressionColumn struct { + Position + Typecastable + // Table is the table that the column is in. + Table string // can be empty + // Column is the name of the column. + Column string +} + +func (e *ExpressionColumn) Accept(v Visitor) any { + return v.VisitExpressionColumn(e) +} + +// ExpressionCollate is an expression with a collation. +type ExpressionCollate struct { + Position + // Expression is the expression that is being collated. + Expression Expression + // Collation is the collation that is being used. + Collation string +} + +func (e *ExpressionCollate) Accept(v Visitor) any { + return v.VisitExpressionCollate(e) +} + +// ExpressionStringComparison is a string comparison expression. +type ExpressionStringComparison struct { + Position + // Left is the left side of the comparison. + Left Expression + // Right is the right side of the comparison. + Right Expression + // Operator is the operator of the comparison. + Operator StringComparisonOperator +} + +func (e *ExpressionStringComparison) Accept(v Visitor) any { + return v.VisitExpressionStringComparison(e) +} + +type StringComparisonOperator string + +const ( + StringComparisonOperatorLike StringComparisonOperator = "LIKE" + StringComparisonOperatorNotLike StringComparisonOperator = "NOT LIKE" +) + +// ExpressionIs is an IS expression. +type ExpressionIs struct { + Position + // Left is the left side of the IS expression. + Left Expression + // Right is the right side of the IS expression. + Right Expression + // Not is true if the IS expression is a NOT IS expression. + Not bool + // Distinct is true if the IS expression is a DISTINCT IS expression. + Distinct bool +} + +func (e *ExpressionIs) Accept(v Visitor) any { + return v.VisitExpressionIs(e) +} + +// ExpressionBetween is a BETWEEN expression. +type ExpressionBetween struct { + Position + // Expression is the expression that is being compared. + Expression Expression + // Lower is the left side of the BETWEEN expression. + Lower Expression + // Upper is the right side of the BETWEEN expression. + Upper Expression + // Not is true if the BETWEEN expression is a NOT BETWEEN expression. + Not bool +} + +func (e *ExpressionBetween) Accept(v Visitor) any { + return v.VisitExpressionBetween(e) +} + +type ExpressionIn struct { + Position + // Expression is the expression that is being compared. + Expression Expression + // List is the list of expressions that the expression is being compared to. + // Either List or Subquery is set, but not both. + List []Expression + // Subquery is the subquery that the expression is being compared to. + // Either List or Subquery is set, but not both. + Subquery *SelectStatement + // Not is true if the IN expression is a NOT IN expression. + Not bool +} + +func (e *ExpressionIn) Accept(v Visitor) any { + return v.VisitExpressionIn(e) +} + +// ExpressionSubquery is a subquery expression. +type ExpressionSubquery struct { + Position + Typecastable + Not bool + Exists bool + Subquery *SelectStatement +} + +func (e *ExpressionSubquery) Accept(v Visitor) any { + return v.VisitExpressionSubquery(e) +} + +// ExpressionCase is a CASE expression. +type ExpressionCase struct { + Position + Case Expression + WhenThen [][2]Expression + Else Expression +} + +func (e *ExpressionCase) Accept(v Visitor) any { + return v.VisitExpressionCase(e) +} + +// CommonTableExpression is a common table expression. +type CommonTableExpression struct { + Position + // Name is the name of the CTE. + Name string + // Columns are the columns of the CTE. + Columns []string + // Query is the query of the CTE. + Query *SelectStatement +} + +func (c *CommonTableExpression) Accept(v Visitor) any { + return v.VisitCommonTableExpression(c) +} + +// SQLStatement is a SQL statement. +type SQLStatement struct { + Position + CTEs []*CommonTableExpression + // SQL can be an insert, update, delete, or select statement. + SQL SQLCore +} + +func (s *SQLStatement) Accept(v Visitor) any { + return v.VisitSQLStatement(s) +} + +// SQLCore is a top-level statement. +// It can be INSERT, UPDATE, DELETE, SELECT. +type SQLCore interface { + Node + StmtType() SQLStatementType +} + +type SQLStatementType string + +const ( + SQLStatementTypeInsert SQLStatementType = "insert" + SQLStatementTypeUpdate SQLStatementType = "update" + SQLStatementTypeDelete SQLStatementType = "delete" + SQLStatementTypeSelect SQLStatementType = "select" +) + +// SelectStatement is a SELECT statement. +type SelectStatement struct { + Position + SelectCores []*SelectCore + CompoundOperators []CompoundOperator + Ordering []*OrderingTerm + Limit Expression + Offset Expression +} + +func (s *SelectStatement) Accept(v Visitor) any { + return v.VisitSelectStatement(s) +} + +func (SelectStatement) StmtType() SQLStatementType { + return SQLStatementTypeSelect +} + +type CompoundOperator string + +const ( + CompoundOperatorUnion CompoundOperator = "UNION" + CompoundOperatorUnionAll CompoundOperator = "UNION ALL" + CompoundOperatorIntersect CompoundOperator = "INTERSECT" + CompoundOperatorExcept CompoundOperator = "EXCEPT" +) + +// OrderingTerm is a term in an order by clause +type OrderingTerm struct { + Position + Expression Expression + Order OrderType + Nulls NullOrder +} + +func (o *OrderingTerm) Accept(v Visitor) any { + return v.VisitOrderingTerm(o) +} + +type OrderType string + +const ( + OrderTypeAsc OrderType = "ASC" + OrderTypeDesc OrderType = "DESC" +) + +type NullOrder string + +const ( + NullOrderFirst NullOrder = "FIRST" + NullOrderLast NullOrder = "LAST" +) + +type SelectCore struct { + Position + // Distinct is true if the SELECT statement is a DISTINCT SELECT statement. + Distinct bool + Columns []ResultColumn + From Table // can be nil + Joins []*Join // can be nil + Where Expression // can be nil + GroupBy []Expression // can be nil + Having Expression // can be nil +} + +func (s *SelectCore) Accept(v Visitor) any { + return v.VisitSelectCore(s) +} + +type ResultColumn interface { + Node + ResultColumnType() ResultColumnType +} + +type ResultColumnType string + +const ( + ResultColumnTypeExpression ResultColumnType = "expression" + ResultColumnTypeWildcard ResultColumnType = "wildcare" +) + +type ResultColumnExpression struct { + Position + + Expression Expression + Alias string // can be empty +} + +func (r *ResultColumnExpression) Accept(v Visitor) any { + return v.VisitResultColumnExpression(r) +} + +func (r *ResultColumnExpression) ResultColumnType() ResultColumnType { + return ResultColumnTypeExpression +} + +type ResultColumnWildcard struct { + Position + Table string // can be empty +} + +func (r *ResultColumnWildcard) Accept(v Visitor) any { + return v.VisitResultColumnWildcard(r) +} + +func (r *ResultColumnWildcard) ResultColumnType() ResultColumnType { + return ResultColumnTypeWildcard +} + +type Table interface { + Node + table() +} + +type RelationTable struct { + Position + Table string + Alias string // can be empty +} + +func (r *RelationTable) Accept(v Visitor) any { + return v.VisitRelationTable(r) +} + +func (RelationTable) table() {} + +type RelationSubquery struct { + Position + Subquery *SelectStatement + // Alias cannot be empty, as our syntax + // forces it for subqueries. + Alias string +} + +func (r *RelationSubquery) Accept(v Visitor) any { + return v.VisitRelationSubquery(r) +} + +func (RelationSubquery) table() {} + +type RelationFunctionCall struct { + Position + FunctionCall ExpressionCall + // The alias cannot be empty, as our syntax forces + // it for function calls + Alias string +} + +func (r *RelationFunctionCall) Accept(v Visitor) any { + return v.VisitRelationFunctionCall(r) +} + +func (RelationFunctionCall) table() {} + +// Join is a join in a SELECT statement. +type Join struct { + Position + Type JoinType + Relation Table + On Expression +} + +func (j *Join) Accept(v Visitor) any { + return v.VisitJoin(j) +} + +type JoinType string + +const ( + JoinTypeInner JoinType = "INNER" + JoinTypeLeft JoinType = "LEFT" + JoinTypeRight JoinType = "RIGHT" + JoinTypeFull JoinType = "FULL" +) + +type UpdateStatement struct { + Position + Table string + Alias string // can be empty + SetClause []*UpdateSetClause + From Table // can be nil + Joins []*Join // can be nil + Where Expression // can be nil +} + +func (u *UpdateStatement) Accept(v Visitor) any { + return v.VisitUpdateStatement(u) +} + +func (u *UpdateStatement) StmtType() SQLStatementType { + return SQLStatementTypeUpdate +} + +type UpdateSetClause struct { + Position + Column string + Value Expression +} + +func (u *UpdateSetClause) Accept(v Visitor) any { + return v.VisitUpdateSetClause(u) +} + +type DeleteStatement struct { + Position + + Table string + Alias string // can be empty + From Table // can be nil + Joins []*Join // can be nil + Where Expression // can be nil +} + +func (d *DeleteStatement) StmtType() SQLStatementType { + return SQLStatementTypeDelete +} + +func (d *DeleteStatement) Accept(v Visitor) any { + return v.VisitDeleteStatement(d) +} + +type InsertStatement struct { + Position + Table string + Alias string // can be empty + Columns []string // can be empty + Values [][]Expression + Upsert *UpsertClause // can be nil +} + +func (i *InsertStatement) Accept(v Visitor) any { + return v.VisitInsertStatement(i) +} + +func (i *InsertStatement) StmtType() SQLStatementType { + return SQLStatementTypeInsert +} + +type UpsertClause struct { + Position + ConflictColumns []string // can be empty + ConflictWhere Expression // can be nil + DoUpdate []*UpdateSetClause // if nil, then do nothing + UpdateWhere Expression // can be nil +} + +func (u *UpsertClause) Accept(v Visitor) any { + return v.VisitUpsertClause(u) +} + +// action ast: + +type ActionStmt interface { + Node + ActionStmt() ActionStatementTypes +} + +type ActionStatementTypes string + +const ( + ActionStatementTypeExtensionCall ActionStatementTypes = "extension_call" + ActionStatementTypeActionCall ActionStatementTypes = "action_call" + ActionStatementTypeSQL ActionStatementTypes = "sql" +) + +type ActionStmtSQL struct { + Position + SQL *SQLStatement +} + +func (a *ActionStmtSQL) Accept(v Visitor) any { + return v.VisitActionStmtSQL(a) +} + +func (a *ActionStmtSQL) ActionStmt() ActionStatementTypes { + return ActionStatementTypeSQL +} + +type ActionStmtExtensionCall struct { + Position + Receivers []string + Extension string + Method string + Args []Expression +} + +func (a *ActionStmtExtensionCall) Accept(v Visitor) any { + return v.VisitActionStmtExtensionCall(a) +} + +func (a *ActionStmtExtensionCall) ActionStmt() ActionStatementTypes { + return ActionStatementTypeExtensionCall +} + +type ActionStmtActionCall struct { + Position + Action string + Args []Expression +} + +func (a *ActionStmtActionCall) Accept(v Visitor) any { + return v.VisitActionStmtActionCall(a) +} + +func (a *ActionStmtActionCall) ActionStmt() ActionStatementTypes { + return ActionStatementTypeActionCall +} + +// procedure ast: + +// ProcedureStmt is a statement in a procedure. +// it is the top-level interface for all procedure statements. +type ProcedureStmt interface { + Node + procedureStmt() +} + +type baseProcedureStmt struct { + Position +} + +func (baseProcedureStmt) procedureStmt() {} + +// ProcedureStmtDeclaration is a variable declaration in a procedure. +type ProcedureStmtDeclaration struct { + baseProcedureStmt + // Variable is the variable that is being declared. + Variable *ExpressionVariable + Type *types.DataType +} + +func (p *ProcedureStmtDeclaration) Accept(v Visitor) any { + return v.VisitProcedureStmtDeclaration(p) +} + +// ProcedureStmtAssign is a variable assignment in a procedure. +// It should only be called on variables that have already been declared. +type ProcedureStmtAssign struct { + baseProcedureStmt + // Variable is the variable that is being assigned. + Variable *ExpressionVariable + // Type is the type of the variable. + // It can be nil if the variable is not being assigned, + // or if the type should be inferred. + Type *types.DataType + // Value is the value that is being assigned. + Value Expression +} + +func (p *ProcedureStmtAssign) Accept(v Visitor) any { + return v.VisitProcedureStmtAssignment(p) +} + +// ProcedureStmtCall is a call to another procedure or built-in function. +type ProcedureStmtCall struct { + baseProcedureStmt + // Receivers are the variables being assigned. If nil, then the + // receiver can be ignored. + Receivers []*ExpressionVariable + Call ExpressionCall +} + +func (p *ProcedureStmtCall) Accept(v Visitor) any { + return v.VisitProcedureStmtCall(p) +} + +type ProcedureStmtForLoop struct { + baseProcedureStmt + // Receiver is the variable that is assigned on each iteration. + Receiver *ExpressionVariable + // LoopTerm is what the loop is looping through. + LoopTerm LoopTerm + // Body is the body of the loop. + Body []ProcedureStmt +} + +func (p *ProcedureStmtForLoop) Accept(v Visitor) any { + return v.VisitProcedureStmtForLoop(p) +} + +// LoopTerm what the loop is looping through. +type LoopTerm interface { + Node + loopTerm() +} + +type baseLoopTerm struct { + Position +} + +func (baseLoopTerm) loopTerm() {} + +type LoopTermRange struct { + baseLoopTerm + // Start is the start of the range. + Start Expression + // End is the end of the range. + End Expression +} + +func (e *LoopTermRange) Accept(v Visitor) interface{} { + return v.VisitLoopTermRange(e) +} + +type LoopTermSQL struct { + baseLoopTerm + // Statement is the Statement statement to execute. + Statement *SQLStatement +} + +func (e *LoopTermSQL) Accept(v Visitor) interface{} { + return v.VisitLoopTermSQL(e) +} + +type LoopTermVariable struct { + baseLoopTerm + // Variable is the variable to loop through. + // It must be an array. + Variable *ExpressionVariable +} + +func (e *LoopTermVariable) Accept(v Visitor) interface{} { + return v.VisitLoopTermVariable(e) +} + +type ProcedureStmtIf struct { + baseProcedureStmt + // IfThens are the if statements. + // They are evaluated in order, as + // IF ... THEN ... ELSEIF ... THEN ... + IfThens []*IfThen + // Else is the else statement. + // It is evaluated if no other if statement + // is true. + Else []ProcedureStmt +} + +func (p *ProcedureStmtIf) Accept(v Visitor) any { + return v.VisitProcedureStmtIf(p) +} + +type IfThen struct { + Position + If Expression + Then []ProcedureStmt +} + +func (i *IfThen) Accept(v Visitor) any { + return v.VisitIfThen(i) +} + +type ProcedureStmtSQL struct { + baseProcedureStmt + SQL *SQLStatement +} + +func (p *ProcedureStmtSQL) Accept(v Visitor) any { + return v.VisitProcedureStmtSQL(p) +} + +type ProcedureStmtBreak struct { + baseProcedureStmt +} + +func (p *ProcedureStmtBreak) Accept(v Visitor) any { + return v.VisitProcedureStmtBreak(p) +} + +type ProcedureStmtReturn struct { + baseProcedureStmt + // Values are the values to return. + // Either values is set or SQL is set, but not both. + Values []Expression + // SQL is the SQL statement to return. + // Either values is set or SQL is set, but not both. + SQL *SQLStatement +} + +func (p *ProcedureStmtReturn) Accept(v Visitor) any { + return v.VisitProcedureStmtReturn(p) +} + +type ProcedureStmtReturnNext struct { + baseProcedureStmt + // Values are the values to return. + Values []Expression +} + +func (p *ProcedureStmtReturnNext) Accept(v Visitor) any { + return v.VisitProcedureStmtReturnNext(p) +} + +/* + There are three types of visitors, all which compose on each other: + - Visitor: top-level visitor capable of visiting actions, procedures, and SQL. + - ProcedureVisitor: a visitor capable of only visiting procedures and SQL. It must include + SQL because procedures themselves rely on SQL/ + - SQLVisitor: a visitor capable of only visiting SQL. +*/ + +// Visitor is an interface for visiting nodes in the parse tree. +type Visitor interface { + ProcedureVisitor + VisitActionStmtSQL(*ActionStmtSQL) any + VisitActionStmtExtensionCall(*ActionStmtExtensionCall) any + VisitActionStmtActionCall(*ActionStmtActionCall) any +} + +// ProcedureVisitor includes visit methods only needed to analyze procedures. +// It does not need visit methods for structs that are for the schema or actions +type ProcedureVisitor interface { + SQLVisitor + VisitProcedureStmtDeclaration(*ProcedureStmtDeclaration) any + VisitProcedureStmtAssignment(*ProcedureStmtAssign) any + VisitProcedureStmtCall(*ProcedureStmtCall) any + VisitProcedureStmtForLoop(*ProcedureStmtForLoop) any + VisitLoopTermRange(*LoopTermRange) any + VisitLoopTermSQL(*LoopTermSQL) any + VisitLoopTermVariable(*LoopTermVariable) any + VisitProcedureStmtIf(*ProcedureStmtIf) any + VisitIfThen(*IfThen) any + VisitProcedureStmtSQL(*ProcedureStmtSQL) any + VisitProcedureStmtBreak(*ProcedureStmtBreak) any + VisitProcedureStmtReturn(*ProcedureStmtReturn) any + VisitProcedureStmtReturnNext(*ProcedureStmtReturnNext) any +} + +// SQLVisitor is a visitor that only has methods for SQL nodes. +type SQLVisitor interface { + VisitExpressionLiteral(*ExpressionLiteral) any + VisitExpressionFunctionCall(*ExpressionFunctionCall) any + VisitExpressionForeignCall(*ExpressionForeignCall) any + VisitExpressionVariable(*ExpressionVariable) any + VisitExpressionArrayAccess(*ExpressionArrayAccess) any + VisitExpressionMakeArray(*ExpressionMakeArray) any + VisitExpressionFieldAccess(*ExpressionFieldAccess) any + VisitExpressionParenthesized(*ExpressionParenthesized) any + VisitExpressionComparison(*ExpressionComparison) any + VisitExpressionLogical(*ExpressionLogical) any + VisitExpressionArithmetic(*ExpressionArithmetic) any + VisitExpressionUnary(*ExpressionUnary) any + VisitExpressionColumn(*ExpressionColumn) any + VisitExpressionCollate(*ExpressionCollate) any + VisitExpressionStringComparison(*ExpressionStringComparison) any + VisitExpressionIs(*ExpressionIs) any + VisitExpressionIn(*ExpressionIn) any + VisitExpressionBetween(*ExpressionBetween) any + VisitExpressionSubquery(*ExpressionSubquery) any + VisitExpressionCase(*ExpressionCase) any + VisitCommonTableExpression(*CommonTableExpression) any + VisitSQLStatement(*SQLStatement) any + VisitSelectStatement(*SelectStatement) any + VisitSelectCore(*SelectCore) any + VisitResultColumnExpression(*ResultColumnExpression) any + VisitResultColumnWildcard(*ResultColumnWildcard) any + VisitRelationTable(*RelationTable) any + VisitRelationSubquery(*RelationSubquery) any + VisitRelationFunctionCall(*RelationFunctionCall) any + VisitJoin(*Join) any + VisitUpdateStatement(*UpdateStatement) any + VisitUpdateSetClause(*UpdateSetClause) any + VisitDeleteStatement(*DeleteStatement) any + VisitInsertStatement(*InsertStatement) any + VisitUpsertClause(*UpsertClause) any + VisitOrderingTerm(*OrderingTerm) any +} + +// UnimplementedSqlVisitor is meant to be used when an implementing visitor only intends +// to implement the SQLVisitor interface. It will implement the full visitor interface, +// but will panic if any of the methods are called. It does not implement the SQLVisitor +// interface, so it alone cannot be used as a visitor. +type UnimplementedSqlVisitor struct { + UnimplementedProcedureVisitor +} + +func (s *UnimplementedSqlVisitor) VisitActionStmtSQL(p0 *ActionStmtSQL) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedSqlVisitor) VisitActionStmtExtensionCall(p0 *ActionStmtExtensionCall) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedSqlVisitor) VisitActionStmtActionCall(p0 *ActionStmtActionCall) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +// UnimplementedProcedureVisitor is meant to be used when an implementing visitor only intends +// to implement the ProcedureVisitor interface. It will implement the full visitor interface, +// but will panic if any of the methods are called. It does not implement the SQLVisitor or +// ProcedureVisitor interfaces, so it alone cannot be used as a visitor. +type UnimplementedProcedureVisitor struct{} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtDeclaration(p0 *ProcedureStmtDeclaration) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtAssignment(p0 *ProcedureStmtAssign) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtCall(p0 *ProcedureStmtCall) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtForLoop(p0 *ProcedureStmtForLoop) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitLoopTermRange(p0 *LoopTermRange) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitLoopTermSQL(p0 *LoopTermSQL) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitLoopTermVariable(p0 *LoopTermVariable) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtIf(p0 *ProcedureStmtIf) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitIfThen(p0 *IfThen) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtSQL(p0 *ProcedureStmtSQL) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtBreak(p0 *ProcedureStmtBreak) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtReturn(p0 *ProcedureStmtReturn) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} + +func (s *UnimplementedProcedureVisitor) VisitProcedureStmtReturnNext(p0 *ProcedureStmtReturnNext) any { + panic(fmt.Sprintf("api misuse: cannot visit %T in constrained visitor", s)) +} diff --git a/parse/contextual.go b/parse/contextual.go new file mode 100644 index 000000000..68cc859d9 --- /dev/null +++ b/parse/contextual.go @@ -0,0 +1,31 @@ +package parse + +import ( + "github.com/kwilteam/kwil-db/core/types" +) + +var ( + // caller is the session variable for the caller. + CallerVar = "caller" + // txid is the session variable for the transaction id. + TxidVar = "txid" + // signer is the session variable for the signer. + SignerVar = "signer" + // SessionVars are the session variables that are available in the engine. + // It maps the variable name to its type. + SessionVars = map[string]*types.DataType{ + CallerVar: types.TextType, + TxidVar: types.TextType, + SignerVar: types.BlobType, + } +) + +// makeSessionVars creates a new map of session variables. +// It includes the @ symbol in the keys. +func makeSessionVars() map[string]*types.DataType { + newMap := make(map[string]*types.DataType) + for k, v := range SessionVars { + newMap["@"+k] = v.Copy() + } + return newMap +} diff --git a/parse/errors.go b/parse/errors.go new file mode 100644 index 000000000..9c5ababa8 --- /dev/null +++ b/parse/errors.go @@ -0,0 +1,254 @@ +package parse + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + + "github.com/antlr4-go/antlr/v4" +) + +// ParseErrors is a collection of parse errors. +type ParseErrors []*ParseError + +var _ interface{ Unwrap() []error } = (*ParseErrors)(nil) + +// Unwrap allows errors.Is and error.As to identify wrapped errors. +func (p ParseErrors) Unwrap() []error { + errs := make([]error, len(p)) + for i := range p { + errs[i] = p[i] + } + return errs +} + +// Err returns all the errors as a single error. +func (p ParseErrors) Err() error { + if len(p) == 0 { + return nil + } + return &p +} + +// The zero value of a ParseErrors instance intentionally does not implement the +// error interface. The Err method will return nil if the length is zero. +var _ error = (*ParseErrors)(nil) + +// Error implements the error interface. +func (p *ParseErrors) Error() string { + errs := *p + switch len(errs) { + case 0: // use Err and this won't happen + return "" + case 1: + return errs[0].Error() + default: + var str strings.Builder + str.WriteString("detected multiple parse errors:") + for i, err := range errs { + str.WriteString(fmt.Sprintf("\n%d: %s", i, err.Error())) + } + return str.String() + } +} + +// Add adds errors to the collection. +func (p *ParseErrors) Add(errs ...*ParseError) { + *p = append(*p, errs...) +} + +// ParseError is an error that occurred during parsing. +type ParseError struct { + ParserName string `json:"parser_name,omitempty"` + Err error `json:"error"` + Message string `json:"message,omitempty"` + Position *Position `json:"position,omitempty"` +} + +// MarshalJSON marshals the error to JSON. +func (p *ParseError) MarshalJSON() ([]byte, error) { + type Alias struct { + ParserName string `json:"parser_name,omitempty"` + Message string `json:"message,omitempty"` + Position *Position `json:"position,omitempty"` + } + + a := &Alias{ + ParserName: p.ParserName, + Message: p.Message, + Position: p.Position, + } + + return json.Marshal(struct { + Error *error `json:"error,omitempty"` + *Alias + }{ + Error: &p.Err, + Alias: a, + }) +} + +// Unwrap() allows errors.Is and errors.As to find wrapped errors. +func (p ParseError) Unwrap() error { + return p.Err +} + +// Error satisfies the standard library error interface. +func (p *ParseError) Error() string { + // Add 1 to the column numbers to make them 1-indexed, since antlr-go is 0-indexed + // for columns. + return fmt.Sprintf("(%s) %s: %s\nstart %d:%d end %d:%d", p.ParserName, p.Err.Error(), p.Message, + p.Position.StartLine, p.Position.StartCol+1, + p.Position.EndLine, p.Position.EndCol+1) +} + +// ParseErrs is a collection of parse errors. +type ParseErrs interface { + Err() error + Errors() []*ParseError + Add(...*ParseError) + MarshalJSON() ([]byte, error) +} + +// errorListener listens to errors emitted by Antlr, and also collects +// errors from Kwil's native validation logic. +type errorListener struct { + errs []*ParseError + name string +} + +var _ antlr.ErrorListener = (*errorListener)(nil) +var _ ParseErrs = (*errorListener)(nil) + +// newErrorListener creates a new error listener with the given options. +func newErrorListener(name string) *errorListener { + return &errorListener{ + errs: make([]*ParseError, 0), + name: name, + } +} + +// Err returns the error if there are any, otherwise it returns nil. +func (e *errorListener) Err() error { + if len(e.errs) == 0 { + return nil + } + pe := ParseErrors(e.errs) + return &pe +} + +// Add adds errors to the collection. +func (e *errorListener) Add(errs ...*ParseError) { + e.errs = append(e.errs, errs...) +} + +// Errors returns the errors that have been collected. +func (e *errorListener) Errors() []*ParseError { + return e.errs +} + +// MarshalJSON marshals the errors to JSON. +func (e *errorListener) MarshalJSON() ([]byte, error) { + return json.Marshal(e.errs) +} + +// AddErr adds an error to the error listener. +func (e *errorListener) AddErr(node Node, err error, msg string, v ...any) { + // TODO: we should change the ParseError struct. It should use the passed error as the "Type", + // and replace the Err field with message. + e.errs = append(e.errs, &ParseError{ + ParserName: e.name, + Err: err, + Message: fmt.Sprintf(msg, v...), + Position: node.GetPosition(), + }) +} + +// TokenErr adds an error that comes from an Antlr token. +func (e *errorListener) TokenErr(t antlr.Token, err error, msg string, v ...any) { + e.errs = append(e.errs, &ParseError{ + ParserName: e.name, + Err: err, + Message: fmt.Sprintf(msg, v...), + Position: unaryNode(t.GetLine(), t.GetColumn()), + }) +} + +// RuleErr adds an error that comes from a Antlr parser rule. +func (e *errorListener) RuleErr(ctx antlr.ParserRuleContext, err error, msg string, v ...any) { + node := &Position{} + node.Set(ctx) + e.errs = append(e.errs, &ParseError{ + ParserName: e.name, + Err: err, + Message: fmt.Sprintf(msg, v...), + Position: node, + }) +} + +// SyntaxError implements the Antlr error listener interface. +func (e *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, + msg string, ex antlr.RecognitionException) { + e.errs = append(e.errs, &ParseError{ + ParserName: e.name, + Err: ErrSyntax, + Message: msg, + Position: unaryNode(line, column), + }) +} + +// We do not need to do anything in the below methods because they are simply Antlr's way of reporting. +// We may want to add warnings in the future, but for now, we will ignore them. +// https://stackoverflow.com/questions/71056312/antlr-how-to-avoid-reportattemptingfullcontext-and-reportambiguity + +// ReportAmbiguity implements the Antlr error listener interface. +func (e *errorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, + exact bool, ambigAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { +} + +// ReportAttemptingFullContext implements the Antlr error listener interface. +func (e *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, + stopIndex int, conflictingAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { +} + +// ReportContextSensitivity implements the Antlr error listener interface. +func (e *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, + prediction int, configs *antlr.ATNConfigSet) { +} + +var ( + ErrSyntax = errors.New("syntax error") + ErrDuplicateBlock = errors.New("duplicate block name") + ErrUndeclaredVariable = errors.New("undeclared variable") + ErrVariableAlreadyDeclared = errors.New("variable already declared") + ErrType = errors.New("type error") + ErrAssignment = errors.New("assignment error") + ErrUnknownTable = errors.New("unknown table reference") + ErrTableDefinition = errors.New("table definition error") + ErrUnknownColumn = errors.New("unknown column reference") + ErrAmbiguousColumn = errors.New("ambiguous column reference") + ErrDuplicateResultColumnName = errors.New("duplicate result column name") + ErrUnknownFunctionOrProcedure = errors.New("unknown function or procedure") + // ErrFunctionSignature is returned when a function/procedure is called with the wrong number of arguments, + // or returns an unexpected number of values / table. + ErrFunctionSignature = errors.New("function/procedure signature error") + ErrTableAlreadyExists = errors.New("table already exists") + // ErrResultShape is used if the result of a query is not in a shape we expect. + ErrResultShape = errors.New("result shape error") + ErrUnnamedResultColumn = errors.New("unnamed result column") + ErrTableAlreadyJoined = errors.New("table already joined") + ErrUnnamedJoin = errors.New("unnamed join") + ErrBreak = errors.New("break error") + ErrReturn = errors.New("return type error") + ErrAggregate = errors.New("aggregate error") + ErrUnknownContextualVariable = errors.New("unknown contextual variable") + ErrIdentifier = errors.New("identifier error") + ErrActionNotFound = errors.New("action not found") + ErrViewMutatesState = errors.New("view mutates state") + ErrOrdering = errors.New("ordering error") + ErrCrossScopeDeclaration = errors.New("cross-scope declaration") + ErrInvalidExcludedTable = errors.New("invalid excluded table usage") + ErrAmbiguousConflictTable = errors.New("ambiguous conflict table") + ErrCollation = errors.New("collation error") +) diff --git a/parse/metadata/functions.go b/parse/functions.go similarity index 55% rename from parse/metadata/functions.go rename to parse/functions.go index b5b47bcfc..fe14247f6 100644 --- a/parse/metadata/functions.go +++ b/parse/functions.go @@ -1,12 +1,10 @@ -package metadata +package parse import ( - "errors" "fmt" "strings" "github.com/kwilteam/kwil-db/core/types" - parseTypes "github.com/kwilteam/kwil-db/parse/types" ) var ( @@ -17,14 +15,21 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.IntType) { + if !args[0].EqualsStrict(types.IntType) { return nil, wrapErrArgumentType(types.IntType, args[0]) } return types.IntType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("abs(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("abs") + } + if distinct { + return "", errDistinct("abs") + } + + return fmt.Sprintf("abs(%s)", inputs[0]), nil }, }, "error": { @@ -33,14 +38,21 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.TextType) { + if !args[0].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[0]) } return types.NullType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("error(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("error") + } + if distinct { + return "", errDistinct("error") + } + + return fmt.Sprintf("error(%s)", inputs[0]), nil }, }, "length": { @@ -49,14 +61,21 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.TextType) { + if !args[0].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[0]) } return types.IntType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("length(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", fmt.Errorf("cannot use * with length") + } + if distinct { + return "", fmt.Errorf("cannot use distinct with length") + } + + return fmt.Sprintf("length(%s)", inputs[0]), nil }, }, "lower": { @@ -65,14 +84,21 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.TextType) { + if !args[0].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[0]) } return types.TextType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("lower(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("lower") + } + if distinct { + return "", errDistinct("lower") + } + + return fmt.Sprintf("lower(%s)", inputs[0]), nil }, }, "upper": { @@ -81,14 +107,21 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.TextType) { + if !args[0].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[0]) } return types.TextType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("upper(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("upper") + } + if distinct { + return "", errDistinct("upper") + } + + return fmt.Sprintf("upper(%s)", inputs[0]), nil }, }, "format": { @@ -97,14 +130,21 @@ var ( return nil, fmt.Errorf("invalid number of arguments: expected at least 1, got %d", len(args)) } - if !args[0].Equals(types.TextType) { + if !args[0].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[0]) } return types.TextType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("format(%s)", strings.Join(inputs, ", ")) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("format") + } + if distinct { + return "", errDistinct("format") + } + + return fmt.Sprintf("format(%s)", strings.Join(inputs, ", ")), nil }, }, "uuid_generate_v5": { @@ -114,18 +154,25 @@ var ( return nil, wrapErrArgumentNumber(2, len(args)) } - if !args[0].Equals(types.UUIDType) { + if !args[0].EqualsStrict(types.UUIDType) { return nil, wrapErrArgumentType(types.UUIDType, args[0]) } - if !args[1].Equals(types.TextType) { + if !args[1].EqualsStrict(types.TextType) { return nil, wrapErrArgumentType(types.TextType, args[1]) } return types.UUIDType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("uuid_generate_v5(%s)", strings.Join(inputs, ", ")) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("uuid_generate_v5") + } + if distinct { + return "", errDistinct("uuid_generate_v5") + } + + return fmt.Sprintf("uuid_generate_v5(%s)", strings.Join(inputs, ", ")), nil }, }, // array functions @@ -136,21 +183,28 @@ var ( } if !args[0].IsArray { - return nil, fmt.Errorf("%w: expected first argument to be an array, got %s", parseTypes.ErrParamType, args[0].String()) + return nil, fmt.Errorf("%w: expected first argument to be an array, got %s", ErrType, args[0].String()) } if args[1].IsArray { - return nil, fmt.Errorf("%w: expected second argument to be a scalar, got %s", parseTypes.ErrParamType, args[1].String()) + return nil, fmt.Errorf("%w: expected second argument to be a scalar, got %s", ErrType, args[1].String()) } if !strings.EqualFold(args[0].Name, args[1].Name) { - return nil, fmt.Errorf("%w: append type must be equal to scalar array type: array type: %s append type: %s", parseTypes.ErrArrayType, args[0].Name, args[1].Name) + return nil, fmt.Errorf("%w: append type must be equal to scalar array type: array type: %s append type: %s", ErrType, args[0].Name, args[1].Name) } return args[0], nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("array_append(%s)", strings.Join(inputs, ", ")) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("array_append") + } + if distinct { + return "", errDistinct("array_append") + } + + return fmt.Sprintf("array_append(%s)", strings.Join(inputs, ", ")), nil }, }, "array_prepend": { @@ -160,21 +214,28 @@ var ( } if args[0].IsArray { - return nil, fmt.Errorf("%w: expected first argument to be a scalar, got %s", parseTypes.ErrParamType, args[0].String()) + return nil, fmt.Errorf("%w: expected first argument to be a scalar, got %s", ErrType, args[0].String()) } if !args[1].IsArray { - return nil, fmt.Errorf("%w: expected second argument to be an array, got %s", parseTypes.ErrParamType, args[1].String()) + return nil, fmt.Errorf("%w: expected second argument to be an array, got %s", ErrType, args[1].String()) } if !strings.EqualFold(args[0].Name, args[1].Name) { - return nil, fmt.Errorf("%w: prepend type must be equal to scalar array type: array type: %s prepend type: %s", parseTypes.ErrArrayType, args[1].Name, args[0].Name) + return nil, fmt.Errorf("%w: prepend type must be equal to scalar array type: array type: %s prepend type: %s", ErrType, args[1].Name, args[0].Name) } return args[1], nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("array_prepend(%s)", strings.Join(inputs, ", ")) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("array_prepend") + } + if distinct { + return "", errDistinct("array_prepend") + } + + return fmt.Sprintf("array_prepend(%s)", strings.Join(inputs, ", ")), nil }, }, "array_cat": { @@ -184,21 +245,28 @@ var ( } if !args[0].IsArray { - return nil, fmt.Errorf("%w: expected first argument to be an array, got %s", parseTypes.ErrParamType, args[0].String()) + return nil, fmt.Errorf("%w: expected first argument to be an array, got %s", ErrType, args[0].String()) } if !args[1].IsArray { - return nil, fmt.Errorf("%w: expected second argument to be an array, got %s", parseTypes.ErrParamType, args[1].String()) + return nil, fmt.Errorf("%w: expected second argument to be an array, got %s", ErrType, args[1].String()) } if !strings.EqualFold(args[0].Name, args[1].Name) { - return nil, fmt.Errorf("%w: expected both arrays to be of the same scalar type, got %s and %s", parseTypes.ErrArrayType, args[0].Name, args[1].Name) + return nil, fmt.Errorf("%w: expected both arrays to be of the same scalar type, got %s and %s", ErrType, args[0].Name, args[1].Name) } return args[0], nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("array_cat(%s)", strings.Join(inputs, ", ")) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("array_cat") + } + if distinct { + return "", errDistinct("array_cat") + } + + return fmt.Sprintf("array_cat(%s)", strings.Join(inputs, ", ")), nil }, }, "array_length": { @@ -213,8 +281,15 @@ var ( return types.IntType, nil }, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("array_length(%s, 1)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("array_length") + } + if distinct { + return "", errDistinct("array_length") + } + + return fmt.Sprintf("array_length(%s, 1)", inputs[0]), nil }, }, // Aggregate functions @@ -227,13 +302,17 @@ var ( return types.IntType, nil }, IsAggregate: true, - PGFormat: func(inputs []string) string { - if len(inputs) == 0 { - return "count(*)" + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "count(*)", nil + } + if distinct { + return fmt.Sprintf("count(DISTINCT %s)", inputs[0]), nil } - return fmt.Sprintf("count(%s)", inputs[0]) + return fmt.Sprintf("count(%s)", inputs[0]), nil }, + StarArgReturn: types.IntType, }, "sum": { ValidateArgs: func(args []*types.DataType) (*types.DataType, error) { @@ -241,44 +320,61 @@ var ( return nil, wrapErrArgumentNumber(1, len(args)) } - if !args[0].Equals(types.IntType) { + if !args[0].EqualsStrict(types.IntType) { return nil, wrapErrArgumentType(types.IntType, args[0]) } return types.IntType, nil }, IsAggregate: true, - PGFormat: func(inputs []string) string { - return fmt.Sprintf("sum(%s)", inputs[0]) + PGFormat: func(inputs []string, distinct bool, star bool) (string, error) { + if star { + return "", errStar("sum") + } + if distinct { + return "sum(DISTINCT %s)", nil + } + + return fmt.Sprintf("sum(%s)", inputs[0]), nil }, + StarArgReturn: types.IntType, }, } ) +func errDistinct(funcName string) error { + return fmt.Errorf(`%w: cannot use DISTINCT with function "%s"`, ErrFunctionSignature, funcName) +} + +func errStar(funcName string) error { + return fmt.Errorf(`%w: cannot use * with function "%s"`, ErrFunctionSignature, funcName) +} + // FunctionDefinition defines a function that can be used in the database. type FunctionDefinition struct { // ValidateArgs is a function that checks the arguments passed to the function. // It can check the argument type and amount of arguments. // It returns the expected return type based on the arguments. ValidateArgs func(args []*types.DataType) (*types.DataType, error) + // StarArgReturn is the type the function returns if * is passed as the sole + // argument. If it is nil, the function does not support *. + StarArgReturn *types.DataType // IsAggregate is true if the function is an aggregate function. IsAggregate bool // PGFormat is a function that formats the inputs to the function in Postgres format. // For example, the function `sum` would format the inputs as `sum($1)`. // It will be given the same amount of inputs as ValidateArgs() was given. // ValidateArgs will always be called first. - PGFormat func(inputs []string) string + PGFormat FormatFunc } -var ( - // ErrInvalidArgumentNumber is returned when the number of arguments passed to a function is invalid. - ErrInvalidArgumentNumber = errors.New("invalid number of arguments") -) +// FormatFunc is a function that formats a string of inputs for a SQL function. +type FormatFunc func(inputs []string, distinct bool, star bool) (string, error) func wrapErrArgumentNumber(expected, got int) error { - return fmt.Errorf("%w: expected %d, got %d", parseTypes.ErrArgCount, expected, got) + return fmt.Errorf("%w: expected %d, got %d", ErrFunctionSignature, expected, got) } func wrapErrArgumentType(expected, got *types.DataType) error { - return fmt.Errorf("%w: expected %s, got %s", parseTypes.ErrParamType, expected.String(), got.String()) + return fmt.Errorf("%w: expected %s, got %s", ErrType, expected.String(), got.String()) } diff --git a/parse/gen/kuneiform_lexer.go b/parse/gen/kuneiform_lexer.go new file mode 100644 index 000000000..9f9d5605a --- /dev/null +++ b/parse/gen/kuneiform_lexer.go @@ -0,0 +1,727 @@ +// Code generated from KuneiformLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. + +package gen + +import ( + "fmt" + "github.com/antlr4-go/antlr/v4" + "sync" + "unicode" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = sync.Once{} +var _ = unicode.IsLetter + +type KuneiformLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +var KuneiformLexerLexerStaticData struct { + once sync.Once + serializedATN []int32 + ChannelNames []string + ModeNames []string + LiteralNames []string + SymbolicNames []string + RuleNames []string + PredictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func kuneiformlexerLexerInit() { + staticData := &KuneiformLexerLexerStaticData + staticData.ChannelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + } + staticData.ModeNames = []string{ + "DEFAULT_MODE", + } + staticData.LiteralNames = []string{ + "", "'{'", "'}'", "'['", "']'", "':'", "';'", "'('", "')'", "','", "'@'", + "'!'", "'.'", "'||'", "'*'", "'='", "'=='", "'#'", "'$'", "'%'", "'+'", + "'-'", "'/'", "", "'<'", "'<='", "'>'", "'>='", "'::'", "'_'", "':='", + "'..'", "'\"'", "'database'", "'use'", "'table'", "'action'", "'procedure'", + "'public'", "'private'", "'view'", "'owner'", "'min'", "'max'", "'minlen'", + "'maxlen'", "'unique'", "'foreign'", "'primary'", "'key'", "'on'", "'do'", + "'cascade'", "'restrict'", "'set'", "'default'", "'null'", "'delete'", + "'update'", "'references'", "'ref'", "'not'", "'index'", "'and'", "'or'", + "'like'", "'in'", "'between'", "'is'", "'exists'", "'all'", "'any'", + "'join'", "'left'", "'right'", "'inner'", "'as'", "'asc'", "'desc'", + "'limit'", "'offset'", "'order'", "'by'", "'group'", "'having'", "'returns'", + "'no'", "'notnull'", "'with'", "'case'", "'when'", "'then'", "'end'", + "'distinct'", "'from'", "'where'", "'collate'", "'select'", "'insert'", + "'values'", "'full'", "'union'", "'intersect'", "'except'", "'nulls'", + "'first'", "'last'", "'returning'", "'into'", "'conflict'", "'nothing'", + "'for'", "'if'", "'elseif'", "'else'", "'break'", "'return'", "'next'", + "", "'true'", "'false'", "", "", "", "", "'on_update'", "'on_delete'", + "'set_default'", "'set_null'", "'no_action'", + } + staticData.SymbolicNames = []string{ + "", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", + "RPAREN", "COMMA", "AT", "EXCL", "PERIOD", "CONCAT", "STAR", "EQUALS", + "EQUATE", "HASH", "DOLLAR", "MOD", "PLUS", "MINUS", "DIV", "NEQ", "LT", + "LTE", "GT", "GTE", "TYPE_CAST", "UNDERSCORE", "ASSIGN", "RANGE", "DOUBLE_QUOTE", + "DATABASE", "USE", "TABLE", "ACTION", "PROCEDURE", "PUBLIC", "PRIVATE", + "VIEW", "OWNER", "MIN", "MAX", "MINLEN", "MAXLEN", "UNIQUE", "FOREIGN", + "PRIMARY", "KEY", "ON", "DO", "CASCADE", "RESTRICT", "SET", "DEFAULT", + "NULL", "DELETE", "UPDATE", "REFERENCES", "REF", "NOT", "INDEX", "AND", + "OR", "LIKE", "IN", "BETWEEN", "IS", "EXISTS", "ALL", "ANY", "JOIN", + "LEFT", "RIGHT", "INNER", "AS", "ASC", "DESC", "LIMIT", "OFFSET", "ORDER", + "BY", "GROUP", "HAVING", "RETURNS", "NO", "NOTNULL", "WITH", "CASE", + "WHEN", "THEN", "END", "DISTINCT", "FROM", "WHERE", "COLLATE", "SELECT", + "INSERT", "VALUES", "FULL", "UNION", "INTERSECT", "EXCEPT", "NULLS", + "FIRST", "LAST", "RETURNING", "INTO", "CONFLICT", "NOTHING", "FOR", + "IF", "ELSEIF", "ELSE", "BREAK", "RETURN", "NEXT", "STRING_", "TRUE", + "FALSE", "DIGITS_", "BINARY_", "LEGACY_PRIMARY_KEY", "LEGACY_FOREIGN_KEY", + "LEGACY_ON_UPDATE", "LEGACY_ON_DELETE", "LEGACY_SET_DEFAULT", "LEGACY_SET_NULL", + "LEGACY_NO_ACTION", "IDENTIFIER", "VARIABLE", "CONTEXTUAL_VARIABLE", + "HASH_IDENTIFIER", "WS", "BLOCK_COMMENT", "LINE_COMMENT", + } + staticData.RuleNames = []string{ + "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", + "RPAREN", "COMMA", "AT", "EXCL", "PERIOD", "CONCAT", "STAR", "EQUALS", + "EQUATE", "HASH", "DOLLAR", "MOD", "PLUS", "MINUS", "DIV", "NEQ", "LT", + "LTE", "GT", "GTE", "TYPE_CAST", "UNDERSCORE", "ASSIGN", "RANGE", "DOUBLE_QUOTE", + "DATABASE", "USE", "TABLE", "ACTION", "PROCEDURE", "PUBLIC", "PRIVATE", + "VIEW", "OWNER", "MIN", "MAX", "MINLEN", "MAXLEN", "UNIQUE", "FOREIGN", + "PRIMARY", "KEY", "ON", "DO", "CASCADE", "RESTRICT", "SET", "DEFAULT", + "NULL", "DELETE", "UPDATE", "REFERENCES", "REF", "NOT", "INDEX", "AND", + "OR", "LIKE", "IN", "BETWEEN", "IS", "EXISTS", "ALL", "ANY", "JOIN", + "LEFT", "RIGHT", "INNER", "AS", "ASC", "DESC", "LIMIT", "OFFSET", "ORDER", + "BY", "GROUP", "HAVING", "RETURNS", "NO", "NOTNULL", "WITH", "CASE", + "WHEN", "THEN", "END", "DISTINCT", "FROM", "WHERE", "COLLATE", "SELECT", + "INSERT", "VALUES", "FULL", "UNION", "INTERSECT", "EXCEPT", "NULLS", + "FIRST", "LAST", "RETURNING", "INTO", "CONFLICT", "NOTHING", "FOR", + "IF", "ELSEIF", "ELSE", "BREAK", "RETURN", "NEXT", "STRING_", "TRUE", + "FALSE", "DIGITS_", "BINARY_", "LEGACY_PRIMARY_KEY", "LEGACY_FOREIGN_KEY", + "LEGACY_ON_UPDATE", "LEGACY_ON_DELETE", "LEGACY_SET_DEFAULT", "LEGACY_SET_NULL", + "LEGACY_NO_ACTION", "IDENTIFIER", "VARIABLE", "CONTEXTUAL_VARIABLE", + "HASH_IDENTIFIER", "WS", "BLOCK_COMMENT", "LINE_COMMENT", + } + staticData.PredictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 0, 136, 1015, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, + 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, + 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, + 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, + 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, + 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, + 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, + 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, + 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, + 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, + 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, + 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, + 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, + 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, + 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, + 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, + 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, + 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, + 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, + 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, + 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, + 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, + 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, + 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, + 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, + 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, + 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, + 7, 135, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, + 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, + 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, + 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, + 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 3, 22, 324, 8, 22, 1, + 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, + 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, + 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, + 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, + 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, + 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, + 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, + 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, + 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, + 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, + 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, + 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, + 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, + 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, + 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, + 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, + 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, + 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, + 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, + 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 64, + 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, + 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, + 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, + 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, + 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, + 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, + 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, + 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, + 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, + 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, + 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, + 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, + 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, + 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, + 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, + 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, + 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, + 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, + 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, + 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, + 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, + 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, + 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, + 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, + 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, + 107, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, + 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, + 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, + 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, + 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, + 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, + 116, 1, 117, 1, 117, 1, 117, 1, 117, 5, 117, 859, 8, 117, 10, 117, 12, + 117, 862, 9, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, + 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 4, 120, 878, 8, + 120, 11, 120, 12, 120, 879, 1, 121, 1, 121, 1, 121, 1, 121, 4, 121, 886, + 8, 121, 11, 121, 12, 121, 887, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, + 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 3, 122, + 903, 8, 122, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, + 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 3, 123, 918, 8, 123, 1, 124, + 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, + 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, + 1, 125, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, + 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, + 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, + 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 129, 1, 129, 5, 129, 973, 8, + 129, 10, 129, 12, 129, 976, 9, 129, 1, 130, 1, 130, 1, 130, 1, 131, 1, + 131, 1, 131, 1, 132, 1, 132, 1, 132, 1, 133, 1, 133, 1, 133, 1, 133, 1, + 134, 1, 134, 1, 134, 1, 134, 5, 134, 995, 8, 134, 10, 134, 12, 134, 998, + 9, 134, 1, 134, 1, 134, 1, 134, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, + 1, 135, 5, 135, 1009, 8, 135, 10, 135, 12, 135, 1012, 9, 135, 1, 135, 1, + 135, 1, 996, 0, 136, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, + 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, + 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, + 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, + 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, + 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, + 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, + 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, + 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 76, 153, + 77, 155, 78, 157, 79, 159, 80, 161, 81, 163, 82, 165, 83, 167, 84, 169, + 85, 171, 86, 173, 87, 175, 88, 177, 89, 179, 90, 181, 91, 183, 92, 185, + 93, 187, 94, 189, 95, 191, 96, 193, 97, 195, 98, 197, 99, 199, 100, 201, + 101, 203, 102, 205, 103, 207, 104, 209, 105, 211, 106, 213, 107, 215, 108, + 217, 109, 219, 110, 221, 111, 223, 112, 225, 113, 227, 114, 229, 115, 231, + 116, 233, 117, 235, 118, 237, 119, 239, 120, 241, 121, 243, 122, 245, 123, + 247, 124, 249, 125, 251, 126, 253, 127, 255, 128, 257, 129, 259, 130, 261, + 131, 263, 132, 265, 133, 267, 134, 269, 135, 271, 136, 1, 0, 32, 2, 0, + 68, 68, 100, 100, 2, 0, 65, 65, 97, 97, 2, 0, 84, 84, 116, 116, 2, 0, 66, + 66, 98, 98, 2, 0, 83, 83, 115, 115, 2, 0, 69, 69, 101, 101, 2, 0, 85, 85, + 117, 117, 2, 0, 76, 76, 108, 108, 2, 0, 67, 67, 99, 99, 2, 0, 73, 73, 105, + 105, 2, 0, 79, 79, 111, 111, 2, 0, 78, 78, 110, 110, 2, 0, 80, 80, 112, + 112, 2, 0, 82, 82, 114, 114, 2, 0, 86, 86, 118, 118, 2, 0, 87, 87, 119, + 119, 2, 0, 77, 77, 109, 109, 2, 0, 88, 88, 120, 120, 2, 0, 81, 81, 113, + 113, 2, 0, 70, 70, 102, 102, 2, 0, 71, 71, 103, 103, 2, 0, 89, 89, 121, + 121, 2, 0, 75, 75, 107, 107, 2, 0, 74, 74, 106, 106, 2, 0, 72, 72, 104, + 104, 2, 0, 39, 39, 92, 92, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, + 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 3, 0, 9, + 11, 13, 13, 32, 32, 2, 0, 10, 10, 13, 13, 1024, 0, 1, 1, 0, 0, 0, 0, 3, + 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, + 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, + 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, + 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, + 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, + 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, + 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, + 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, + 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, + 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, + 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, + 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, + 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, + 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, + 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, + 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, + 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, + 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, + 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, + 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 0, 153, 1, + 0, 0, 0, 0, 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, + 161, 1, 0, 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, + 0, 0, 0, 169, 1, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 173, 1, 0, 0, 0, 0, 175, + 1, 0, 0, 0, 0, 177, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, + 0, 183, 1, 0, 0, 0, 0, 185, 1, 0, 0, 0, 0, 187, 1, 0, 0, 0, 0, 189, 1, + 0, 0, 0, 0, 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 0, 195, 1, 0, 0, 0, 0, + 197, 1, 0, 0, 0, 0, 199, 1, 0, 0, 0, 0, 201, 1, 0, 0, 0, 0, 203, 1, 0, + 0, 0, 0, 205, 1, 0, 0, 0, 0, 207, 1, 0, 0, 0, 0, 209, 1, 0, 0, 0, 0, 211, + 1, 0, 0, 0, 0, 213, 1, 0, 0, 0, 0, 215, 1, 0, 0, 0, 0, 217, 1, 0, 0, 0, + 0, 219, 1, 0, 0, 0, 0, 221, 1, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 225, 1, + 0, 0, 0, 0, 227, 1, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, + 233, 1, 0, 0, 0, 0, 235, 1, 0, 0, 0, 0, 237, 1, 0, 0, 0, 0, 239, 1, 0, + 0, 0, 0, 241, 1, 0, 0, 0, 0, 243, 1, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 247, + 1, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 251, 1, 0, 0, 0, 0, 253, 1, 0, 0, 0, + 0, 255, 1, 0, 0, 0, 0, 257, 1, 0, 0, 0, 0, 259, 1, 0, 0, 0, 0, 261, 1, + 0, 0, 0, 0, 263, 1, 0, 0, 0, 0, 265, 1, 0, 0, 0, 0, 267, 1, 0, 0, 0, 0, + 269, 1, 0, 0, 0, 0, 271, 1, 0, 0, 0, 1, 273, 1, 0, 0, 0, 3, 275, 1, 0, + 0, 0, 5, 277, 1, 0, 0, 0, 7, 279, 1, 0, 0, 0, 9, 281, 1, 0, 0, 0, 11, 283, + 1, 0, 0, 0, 13, 285, 1, 0, 0, 0, 15, 287, 1, 0, 0, 0, 17, 289, 1, 0, 0, + 0, 19, 291, 1, 0, 0, 0, 21, 293, 1, 0, 0, 0, 23, 295, 1, 0, 0, 0, 25, 297, + 1, 0, 0, 0, 27, 300, 1, 0, 0, 0, 29, 302, 1, 0, 0, 0, 31, 304, 1, 0, 0, + 0, 33, 307, 1, 0, 0, 0, 35, 309, 1, 0, 0, 0, 37, 311, 1, 0, 0, 0, 39, 313, + 1, 0, 0, 0, 41, 315, 1, 0, 0, 0, 43, 317, 1, 0, 0, 0, 45, 323, 1, 0, 0, + 0, 47, 325, 1, 0, 0, 0, 49, 327, 1, 0, 0, 0, 51, 330, 1, 0, 0, 0, 53, 332, + 1, 0, 0, 0, 55, 335, 1, 0, 0, 0, 57, 338, 1, 0, 0, 0, 59, 340, 1, 0, 0, + 0, 61, 343, 1, 0, 0, 0, 63, 346, 1, 0, 0, 0, 65, 348, 1, 0, 0, 0, 67, 357, + 1, 0, 0, 0, 69, 361, 1, 0, 0, 0, 71, 367, 1, 0, 0, 0, 73, 374, 1, 0, 0, + 0, 75, 384, 1, 0, 0, 0, 77, 391, 1, 0, 0, 0, 79, 399, 1, 0, 0, 0, 81, 404, + 1, 0, 0, 0, 83, 410, 1, 0, 0, 0, 85, 414, 1, 0, 0, 0, 87, 418, 1, 0, 0, + 0, 89, 425, 1, 0, 0, 0, 91, 432, 1, 0, 0, 0, 93, 439, 1, 0, 0, 0, 95, 447, + 1, 0, 0, 0, 97, 455, 1, 0, 0, 0, 99, 459, 1, 0, 0, 0, 101, 462, 1, 0, 0, + 0, 103, 465, 1, 0, 0, 0, 105, 473, 1, 0, 0, 0, 107, 482, 1, 0, 0, 0, 109, + 486, 1, 0, 0, 0, 111, 494, 1, 0, 0, 0, 113, 499, 1, 0, 0, 0, 115, 506, + 1, 0, 0, 0, 117, 513, 1, 0, 0, 0, 119, 524, 1, 0, 0, 0, 121, 528, 1, 0, + 0, 0, 123, 532, 1, 0, 0, 0, 125, 538, 1, 0, 0, 0, 127, 542, 1, 0, 0, 0, + 129, 545, 1, 0, 0, 0, 131, 550, 1, 0, 0, 0, 133, 553, 1, 0, 0, 0, 135, + 561, 1, 0, 0, 0, 137, 564, 1, 0, 0, 0, 139, 571, 1, 0, 0, 0, 141, 575, + 1, 0, 0, 0, 143, 579, 1, 0, 0, 0, 145, 584, 1, 0, 0, 0, 147, 589, 1, 0, + 0, 0, 149, 595, 1, 0, 0, 0, 151, 601, 1, 0, 0, 0, 153, 604, 1, 0, 0, 0, + 155, 608, 1, 0, 0, 0, 157, 613, 1, 0, 0, 0, 159, 619, 1, 0, 0, 0, 161, + 626, 1, 0, 0, 0, 163, 632, 1, 0, 0, 0, 165, 635, 1, 0, 0, 0, 167, 641, + 1, 0, 0, 0, 169, 648, 1, 0, 0, 0, 171, 656, 1, 0, 0, 0, 173, 659, 1, 0, + 0, 0, 175, 667, 1, 0, 0, 0, 177, 672, 1, 0, 0, 0, 179, 677, 1, 0, 0, 0, + 181, 682, 1, 0, 0, 0, 183, 687, 1, 0, 0, 0, 185, 691, 1, 0, 0, 0, 187, + 700, 1, 0, 0, 0, 189, 705, 1, 0, 0, 0, 191, 711, 1, 0, 0, 0, 193, 719, + 1, 0, 0, 0, 195, 726, 1, 0, 0, 0, 197, 733, 1, 0, 0, 0, 199, 740, 1, 0, + 0, 0, 201, 745, 1, 0, 0, 0, 203, 751, 1, 0, 0, 0, 205, 761, 1, 0, 0, 0, + 207, 768, 1, 0, 0, 0, 209, 774, 1, 0, 0, 0, 211, 780, 1, 0, 0, 0, 213, + 785, 1, 0, 0, 0, 215, 795, 1, 0, 0, 0, 217, 800, 1, 0, 0, 0, 219, 809, + 1, 0, 0, 0, 221, 817, 1, 0, 0, 0, 223, 821, 1, 0, 0, 0, 225, 824, 1, 0, + 0, 0, 227, 831, 1, 0, 0, 0, 229, 836, 1, 0, 0, 0, 231, 842, 1, 0, 0, 0, + 233, 849, 1, 0, 0, 0, 235, 854, 1, 0, 0, 0, 237, 865, 1, 0, 0, 0, 239, + 870, 1, 0, 0, 0, 241, 877, 1, 0, 0, 0, 243, 881, 1, 0, 0, 0, 245, 902, + 1, 0, 0, 0, 247, 917, 1, 0, 0, 0, 249, 919, 1, 0, 0, 0, 251, 929, 1, 0, + 0, 0, 253, 939, 1, 0, 0, 0, 255, 951, 1, 0, 0, 0, 257, 960, 1, 0, 0, 0, + 259, 970, 1, 0, 0, 0, 261, 977, 1, 0, 0, 0, 263, 980, 1, 0, 0, 0, 265, + 983, 1, 0, 0, 0, 267, 986, 1, 0, 0, 0, 269, 990, 1, 0, 0, 0, 271, 1004, + 1, 0, 0, 0, 273, 274, 5, 123, 0, 0, 274, 2, 1, 0, 0, 0, 275, 276, 5, 125, + 0, 0, 276, 4, 1, 0, 0, 0, 277, 278, 5, 91, 0, 0, 278, 6, 1, 0, 0, 0, 279, + 280, 5, 93, 0, 0, 280, 8, 1, 0, 0, 0, 281, 282, 5, 58, 0, 0, 282, 10, 1, + 0, 0, 0, 283, 284, 5, 59, 0, 0, 284, 12, 1, 0, 0, 0, 285, 286, 5, 40, 0, + 0, 286, 14, 1, 0, 0, 0, 287, 288, 5, 41, 0, 0, 288, 16, 1, 0, 0, 0, 289, + 290, 5, 44, 0, 0, 290, 18, 1, 0, 0, 0, 291, 292, 5, 64, 0, 0, 292, 20, + 1, 0, 0, 0, 293, 294, 5, 33, 0, 0, 294, 22, 1, 0, 0, 0, 295, 296, 5, 46, + 0, 0, 296, 24, 1, 0, 0, 0, 297, 298, 5, 124, 0, 0, 298, 299, 5, 124, 0, + 0, 299, 26, 1, 0, 0, 0, 300, 301, 5, 42, 0, 0, 301, 28, 1, 0, 0, 0, 302, + 303, 5, 61, 0, 0, 303, 30, 1, 0, 0, 0, 304, 305, 5, 61, 0, 0, 305, 306, + 5, 61, 0, 0, 306, 32, 1, 0, 0, 0, 307, 308, 5, 35, 0, 0, 308, 34, 1, 0, + 0, 0, 309, 310, 5, 36, 0, 0, 310, 36, 1, 0, 0, 0, 311, 312, 5, 37, 0, 0, + 312, 38, 1, 0, 0, 0, 313, 314, 5, 43, 0, 0, 314, 40, 1, 0, 0, 0, 315, 316, + 5, 45, 0, 0, 316, 42, 1, 0, 0, 0, 317, 318, 5, 47, 0, 0, 318, 44, 1, 0, + 0, 0, 319, 320, 5, 33, 0, 0, 320, 324, 5, 61, 0, 0, 321, 322, 5, 60, 0, + 0, 322, 324, 5, 62, 0, 0, 323, 319, 1, 0, 0, 0, 323, 321, 1, 0, 0, 0, 324, + 46, 1, 0, 0, 0, 325, 326, 5, 60, 0, 0, 326, 48, 1, 0, 0, 0, 327, 328, 5, + 60, 0, 0, 328, 329, 5, 61, 0, 0, 329, 50, 1, 0, 0, 0, 330, 331, 5, 62, + 0, 0, 331, 52, 1, 0, 0, 0, 332, 333, 5, 62, 0, 0, 333, 334, 5, 61, 0, 0, + 334, 54, 1, 0, 0, 0, 335, 336, 5, 58, 0, 0, 336, 337, 5, 58, 0, 0, 337, + 56, 1, 0, 0, 0, 338, 339, 5, 95, 0, 0, 339, 58, 1, 0, 0, 0, 340, 341, 5, + 58, 0, 0, 341, 342, 5, 61, 0, 0, 342, 60, 1, 0, 0, 0, 343, 344, 5, 46, + 0, 0, 344, 345, 5, 46, 0, 0, 345, 62, 1, 0, 0, 0, 346, 347, 5, 34, 0, 0, + 347, 64, 1, 0, 0, 0, 348, 349, 7, 0, 0, 0, 349, 350, 7, 1, 0, 0, 350, 351, + 7, 2, 0, 0, 351, 352, 7, 1, 0, 0, 352, 353, 7, 3, 0, 0, 353, 354, 7, 1, + 0, 0, 354, 355, 7, 4, 0, 0, 355, 356, 7, 5, 0, 0, 356, 66, 1, 0, 0, 0, + 357, 358, 7, 6, 0, 0, 358, 359, 7, 4, 0, 0, 359, 360, 7, 5, 0, 0, 360, + 68, 1, 0, 0, 0, 361, 362, 7, 2, 0, 0, 362, 363, 7, 1, 0, 0, 363, 364, 7, + 3, 0, 0, 364, 365, 7, 7, 0, 0, 365, 366, 7, 5, 0, 0, 366, 70, 1, 0, 0, + 0, 367, 368, 7, 1, 0, 0, 368, 369, 7, 8, 0, 0, 369, 370, 7, 2, 0, 0, 370, + 371, 7, 9, 0, 0, 371, 372, 7, 10, 0, 0, 372, 373, 7, 11, 0, 0, 373, 72, + 1, 0, 0, 0, 374, 375, 7, 12, 0, 0, 375, 376, 7, 13, 0, 0, 376, 377, 7, + 10, 0, 0, 377, 378, 7, 8, 0, 0, 378, 379, 7, 5, 0, 0, 379, 380, 7, 0, 0, + 0, 380, 381, 7, 6, 0, 0, 381, 382, 7, 13, 0, 0, 382, 383, 7, 5, 0, 0, 383, + 74, 1, 0, 0, 0, 384, 385, 7, 12, 0, 0, 385, 386, 7, 6, 0, 0, 386, 387, + 7, 3, 0, 0, 387, 388, 7, 7, 0, 0, 388, 389, 7, 9, 0, 0, 389, 390, 7, 8, + 0, 0, 390, 76, 1, 0, 0, 0, 391, 392, 7, 12, 0, 0, 392, 393, 7, 13, 0, 0, + 393, 394, 7, 9, 0, 0, 394, 395, 7, 14, 0, 0, 395, 396, 7, 1, 0, 0, 396, + 397, 7, 2, 0, 0, 397, 398, 7, 5, 0, 0, 398, 78, 1, 0, 0, 0, 399, 400, 7, + 14, 0, 0, 400, 401, 7, 9, 0, 0, 401, 402, 7, 5, 0, 0, 402, 403, 7, 15, + 0, 0, 403, 80, 1, 0, 0, 0, 404, 405, 7, 10, 0, 0, 405, 406, 7, 15, 0, 0, + 406, 407, 7, 11, 0, 0, 407, 408, 7, 5, 0, 0, 408, 409, 7, 13, 0, 0, 409, + 82, 1, 0, 0, 0, 410, 411, 7, 16, 0, 0, 411, 412, 7, 9, 0, 0, 412, 413, + 7, 11, 0, 0, 413, 84, 1, 0, 0, 0, 414, 415, 7, 16, 0, 0, 415, 416, 7, 1, + 0, 0, 416, 417, 7, 17, 0, 0, 417, 86, 1, 0, 0, 0, 418, 419, 7, 16, 0, 0, + 419, 420, 7, 9, 0, 0, 420, 421, 7, 11, 0, 0, 421, 422, 7, 7, 0, 0, 422, + 423, 7, 5, 0, 0, 423, 424, 7, 11, 0, 0, 424, 88, 1, 0, 0, 0, 425, 426, + 7, 16, 0, 0, 426, 427, 7, 1, 0, 0, 427, 428, 7, 17, 0, 0, 428, 429, 7, + 7, 0, 0, 429, 430, 7, 5, 0, 0, 430, 431, 7, 11, 0, 0, 431, 90, 1, 0, 0, + 0, 432, 433, 7, 6, 0, 0, 433, 434, 7, 11, 0, 0, 434, 435, 7, 9, 0, 0, 435, + 436, 7, 18, 0, 0, 436, 437, 7, 6, 0, 0, 437, 438, 7, 5, 0, 0, 438, 92, + 1, 0, 0, 0, 439, 440, 7, 19, 0, 0, 440, 441, 7, 10, 0, 0, 441, 442, 7, + 13, 0, 0, 442, 443, 7, 5, 0, 0, 443, 444, 7, 9, 0, 0, 444, 445, 7, 20, + 0, 0, 445, 446, 7, 11, 0, 0, 446, 94, 1, 0, 0, 0, 447, 448, 7, 12, 0, 0, + 448, 449, 7, 13, 0, 0, 449, 450, 7, 9, 0, 0, 450, 451, 7, 16, 0, 0, 451, + 452, 7, 1, 0, 0, 452, 453, 7, 13, 0, 0, 453, 454, 7, 21, 0, 0, 454, 96, + 1, 0, 0, 0, 455, 456, 7, 22, 0, 0, 456, 457, 7, 5, 0, 0, 457, 458, 7, 21, + 0, 0, 458, 98, 1, 0, 0, 0, 459, 460, 7, 10, 0, 0, 460, 461, 7, 11, 0, 0, + 461, 100, 1, 0, 0, 0, 462, 463, 7, 0, 0, 0, 463, 464, 7, 10, 0, 0, 464, + 102, 1, 0, 0, 0, 465, 466, 7, 8, 0, 0, 466, 467, 7, 1, 0, 0, 467, 468, + 7, 4, 0, 0, 468, 469, 7, 8, 0, 0, 469, 470, 7, 1, 0, 0, 470, 471, 7, 0, + 0, 0, 471, 472, 7, 5, 0, 0, 472, 104, 1, 0, 0, 0, 473, 474, 7, 13, 0, 0, + 474, 475, 7, 5, 0, 0, 475, 476, 7, 4, 0, 0, 476, 477, 7, 2, 0, 0, 477, + 478, 7, 13, 0, 0, 478, 479, 7, 9, 0, 0, 479, 480, 7, 8, 0, 0, 480, 481, + 7, 2, 0, 0, 481, 106, 1, 0, 0, 0, 482, 483, 7, 4, 0, 0, 483, 484, 7, 5, + 0, 0, 484, 485, 7, 2, 0, 0, 485, 108, 1, 0, 0, 0, 486, 487, 7, 0, 0, 0, + 487, 488, 7, 5, 0, 0, 488, 489, 7, 19, 0, 0, 489, 490, 7, 1, 0, 0, 490, + 491, 7, 6, 0, 0, 491, 492, 7, 7, 0, 0, 492, 493, 7, 2, 0, 0, 493, 110, + 1, 0, 0, 0, 494, 495, 7, 11, 0, 0, 495, 496, 7, 6, 0, 0, 496, 497, 7, 7, + 0, 0, 497, 498, 7, 7, 0, 0, 498, 112, 1, 0, 0, 0, 499, 500, 7, 0, 0, 0, + 500, 501, 7, 5, 0, 0, 501, 502, 7, 7, 0, 0, 502, 503, 7, 5, 0, 0, 503, + 504, 7, 2, 0, 0, 504, 505, 7, 5, 0, 0, 505, 114, 1, 0, 0, 0, 506, 507, + 7, 6, 0, 0, 507, 508, 7, 12, 0, 0, 508, 509, 7, 0, 0, 0, 509, 510, 7, 1, + 0, 0, 510, 511, 7, 2, 0, 0, 511, 512, 7, 5, 0, 0, 512, 116, 1, 0, 0, 0, + 513, 514, 7, 13, 0, 0, 514, 515, 7, 5, 0, 0, 515, 516, 7, 19, 0, 0, 516, + 517, 7, 5, 0, 0, 517, 518, 7, 13, 0, 0, 518, 519, 7, 5, 0, 0, 519, 520, + 7, 11, 0, 0, 520, 521, 7, 8, 0, 0, 521, 522, 7, 5, 0, 0, 522, 523, 7, 4, + 0, 0, 523, 118, 1, 0, 0, 0, 524, 525, 7, 13, 0, 0, 525, 526, 7, 5, 0, 0, + 526, 527, 7, 19, 0, 0, 527, 120, 1, 0, 0, 0, 528, 529, 7, 11, 0, 0, 529, + 530, 7, 10, 0, 0, 530, 531, 7, 2, 0, 0, 531, 122, 1, 0, 0, 0, 532, 533, + 7, 9, 0, 0, 533, 534, 7, 11, 0, 0, 534, 535, 7, 0, 0, 0, 535, 536, 7, 5, + 0, 0, 536, 537, 7, 17, 0, 0, 537, 124, 1, 0, 0, 0, 538, 539, 7, 1, 0, 0, + 539, 540, 7, 11, 0, 0, 540, 541, 7, 0, 0, 0, 541, 126, 1, 0, 0, 0, 542, + 543, 7, 10, 0, 0, 543, 544, 7, 13, 0, 0, 544, 128, 1, 0, 0, 0, 545, 546, + 7, 7, 0, 0, 546, 547, 7, 9, 0, 0, 547, 548, 7, 22, 0, 0, 548, 549, 7, 5, + 0, 0, 549, 130, 1, 0, 0, 0, 550, 551, 7, 9, 0, 0, 551, 552, 7, 11, 0, 0, + 552, 132, 1, 0, 0, 0, 553, 554, 7, 3, 0, 0, 554, 555, 7, 5, 0, 0, 555, + 556, 7, 2, 0, 0, 556, 557, 7, 15, 0, 0, 557, 558, 7, 5, 0, 0, 558, 559, + 7, 5, 0, 0, 559, 560, 7, 11, 0, 0, 560, 134, 1, 0, 0, 0, 561, 562, 7, 9, + 0, 0, 562, 563, 7, 4, 0, 0, 563, 136, 1, 0, 0, 0, 564, 565, 7, 5, 0, 0, + 565, 566, 7, 17, 0, 0, 566, 567, 7, 9, 0, 0, 567, 568, 7, 4, 0, 0, 568, + 569, 7, 2, 0, 0, 569, 570, 7, 4, 0, 0, 570, 138, 1, 0, 0, 0, 571, 572, + 7, 1, 0, 0, 572, 573, 7, 7, 0, 0, 573, 574, 7, 7, 0, 0, 574, 140, 1, 0, + 0, 0, 575, 576, 7, 1, 0, 0, 576, 577, 7, 11, 0, 0, 577, 578, 7, 21, 0, + 0, 578, 142, 1, 0, 0, 0, 579, 580, 7, 23, 0, 0, 580, 581, 7, 10, 0, 0, + 581, 582, 7, 9, 0, 0, 582, 583, 7, 11, 0, 0, 583, 144, 1, 0, 0, 0, 584, + 585, 7, 7, 0, 0, 585, 586, 7, 5, 0, 0, 586, 587, 7, 19, 0, 0, 587, 588, + 7, 2, 0, 0, 588, 146, 1, 0, 0, 0, 589, 590, 7, 13, 0, 0, 590, 591, 7, 9, + 0, 0, 591, 592, 7, 20, 0, 0, 592, 593, 7, 24, 0, 0, 593, 594, 7, 2, 0, + 0, 594, 148, 1, 0, 0, 0, 595, 596, 7, 9, 0, 0, 596, 597, 7, 11, 0, 0, 597, + 598, 7, 11, 0, 0, 598, 599, 7, 5, 0, 0, 599, 600, 7, 13, 0, 0, 600, 150, + 1, 0, 0, 0, 601, 602, 7, 1, 0, 0, 602, 603, 7, 4, 0, 0, 603, 152, 1, 0, + 0, 0, 604, 605, 7, 1, 0, 0, 605, 606, 7, 4, 0, 0, 606, 607, 7, 8, 0, 0, + 607, 154, 1, 0, 0, 0, 608, 609, 7, 0, 0, 0, 609, 610, 7, 5, 0, 0, 610, + 611, 7, 4, 0, 0, 611, 612, 7, 8, 0, 0, 612, 156, 1, 0, 0, 0, 613, 614, + 7, 7, 0, 0, 614, 615, 7, 9, 0, 0, 615, 616, 7, 16, 0, 0, 616, 617, 7, 9, + 0, 0, 617, 618, 7, 2, 0, 0, 618, 158, 1, 0, 0, 0, 619, 620, 7, 10, 0, 0, + 620, 621, 7, 19, 0, 0, 621, 622, 7, 19, 0, 0, 622, 623, 7, 4, 0, 0, 623, + 624, 7, 5, 0, 0, 624, 625, 7, 2, 0, 0, 625, 160, 1, 0, 0, 0, 626, 627, + 7, 10, 0, 0, 627, 628, 7, 13, 0, 0, 628, 629, 7, 0, 0, 0, 629, 630, 7, + 5, 0, 0, 630, 631, 7, 13, 0, 0, 631, 162, 1, 0, 0, 0, 632, 633, 7, 3, 0, + 0, 633, 634, 7, 21, 0, 0, 634, 164, 1, 0, 0, 0, 635, 636, 7, 20, 0, 0, + 636, 637, 7, 13, 0, 0, 637, 638, 7, 10, 0, 0, 638, 639, 7, 6, 0, 0, 639, + 640, 7, 12, 0, 0, 640, 166, 1, 0, 0, 0, 641, 642, 7, 24, 0, 0, 642, 643, + 7, 1, 0, 0, 643, 644, 7, 14, 0, 0, 644, 645, 7, 9, 0, 0, 645, 646, 7, 11, + 0, 0, 646, 647, 7, 20, 0, 0, 647, 168, 1, 0, 0, 0, 648, 649, 7, 13, 0, + 0, 649, 650, 7, 5, 0, 0, 650, 651, 7, 2, 0, 0, 651, 652, 7, 6, 0, 0, 652, + 653, 7, 13, 0, 0, 653, 654, 7, 11, 0, 0, 654, 655, 7, 4, 0, 0, 655, 170, + 1, 0, 0, 0, 656, 657, 7, 11, 0, 0, 657, 658, 7, 10, 0, 0, 658, 172, 1, + 0, 0, 0, 659, 660, 7, 11, 0, 0, 660, 661, 7, 10, 0, 0, 661, 662, 7, 2, + 0, 0, 662, 663, 7, 11, 0, 0, 663, 664, 7, 6, 0, 0, 664, 665, 7, 7, 0, 0, + 665, 666, 7, 7, 0, 0, 666, 174, 1, 0, 0, 0, 667, 668, 7, 15, 0, 0, 668, + 669, 7, 9, 0, 0, 669, 670, 7, 2, 0, 0, 670, 671, 7, 24, 0, 0, 671, 176, + 1, 0, 0, 0, 672, 673, 7, 8, 0, 0, 673, 674, 7, 1, 0, 0, 674, 675, 7, 4, + 0, 0, 675, 676, 7, 5, 0, 0, 676, 178, 1, 0, 0, 0, 677, 678, 7, 15, 0, 0, + 678, 679, 7, 24, 0, 0, 679, 680, 7, 5, 0, 0, 680, 681, 7, 11, 0, 0, 681, + 180, 1, 0, 0, 0, 682, 683, 7, 2, 0, 0, 683, 684, 7, 24, 0, 0, 684, 685, + 7, 5, 0, 0, 685, 686, 7, 11, 0, 0, 686, 182, 1, 0, 0, 0, 687, 688, 7, 5, + 0, 0, 688, 689, 7, 11, 0, 0, 689, 690, 7, 0, 0, 0, 690, 184, 1, 0, 0, 0, + 691, 692, 7, 0, 0, 0, 692, 693, 7, 9, 0, 0, 693, 694, 7, 4, 0, 0, 694, + 695, 7, 2, 0, 0, 695, 696, 7, 9, 0, 0, 696, 697, 7, 11, 0, 0, 697, 698, + 7, 8, 0, 0, 698, 699, 7, 2, 0, 0, 699, 186, 1, 0, 0, 0, 700, 701, 7, 19, + 0, 0, 701, 702, 7, 13, 0, 0, 702, 703, 7, 10, 0, 0, 703, 704, 7, 16, 0, + 0, 704, 188, 1, 0, 0, 0, 705, 706, 7, 15, 0, 0, 706, 707, 7, 24, 0, 0, + 707, 708, 7, 5, 0, 0, 708, 709, 7, 13, 0, 0, 709, 710, 7, 5, 0, 0, 710, + 190, 1, 0, 0, 0, 711, 712, 7, 8, 0, 0, 712, 713, 7, 10, 0, 0, 713, 714, + 7, 7, 0, 0, 714, 715, 7, 7, 0, 0, 715, 716, 7, 1, 0, 0, 716, 717, 7, 2, + 0, 0, 717, 718, 7, 5, 0, 0, 718, 192, 1, 0, 0, 0, 719, 720, 7, 4, 0, 0, + 720, 721, 7, 5, 0, 0, 721, 722, 7, 7, 0, 0, 722, 723, 7, 5, 0, 0, 723, + 724, 7, 8, 0, 0, 724, 725, 7, 2, 0, 0, 725, 194, 1, 0, 0, 0, 726, 727, + 7, 9, 0, 0, 727, 728, 7, 11, 0, 0, 728, 729, 7, 4, 0, 0, 729, 730, 7, 5, + 0, 0, 730, 731, 7, 13, 0, 0, 731, 732, 7, 2, 0, 0, 732, 196, 1, 0, 0, 0, + 733, 734, 7, 14, 0, 0, 734, 735, 7, 1, 0, 0, 735, 736, 7, 7, 0, 0, 736, + 737, 7, 6, 0, 0, 737, 738, 7, 5, 0, 0, 738, 739, 7, 4, 0, 0, 739, 198, + 1, 0, 0, 0, 740, 741, 7, 19, 0, 0, 741, 742, 7, 6, 0, 0, 742, 743, 7, 7, + 0, 0, 743, 744, 7, 7, 0, 0, 744, 200, 1, 0, 0, 0, 745, 746, 7, 6, 0, 0, + 746, 747, 7, 11, 0, 0, 747, 748, 7, 9, 0, 0, 748, 749, 7, 10, 0, 0, 749, + 750, 7, 11, 0, 0, 750, 202, 1, 0, 0, 0, 751, 752, 7, 9, 0, 0, 752, 753, + 7, 11, 0, 0, 753, 754, 7, 2, 0, 0, 754, 755, 7, 5, 0, 0, 755, 756, 7, 13, + 0, 0, 756, 757, 7, 4, 0, 0, 757, 758, 7, 5, 0, 0, 758, 759, 7, 8, 0, 0, + 759, 760, 7, 2, 0, 0, 760, 204, 1, 0, 0, 0, 761, 762, 7, 5, 0, 0, 762, + 763, 7, 17, 0, 0, 763, 764, 7, 8, 0, 0, 764, 765, 7, 5, 0, 0, 765, 766, + 7, 12, 0, 0, 766, 767, 7, 2, 0, 0, 767, 206, 1, 0, 0, 0, 768, 769, 7, 11, + 0, 0, 769, 770, 7, 6, 0, 0, 770, 771, 7, 7, 0, 0, 771, 772, 7, 7, 0, 0, + 772, 773, 7, 4, 0, 0, 773, 208, 1, 0, 0, 0, 774, 775, 7, 19, 0, 0, 775, + 776, 7, 9, 0, 0, 776, 777, 7, 13, 0, 0, 777, 778, 7, 4, 0, 0, 778, 779, + 7, 2, 0, 0, 779, 210, 1, 0, 0, 0, 780, 781, 7, 7, 0, 0, 781, 782, 7, 1, + 0, 0, 782, 783, 7, 4, 0, 0, 783, 784, 7, 2, 0, 0, 784, 212, 1, 0, 0, 0, + 785, 786, 7, 13, 0, 0, 786, 787, 7, 5, 0, 0, 787, 788, 7, 2, 0, 0, 788, + 789, 7, 6, 0, 0, 789, 790, 7, 13, 0, 0, 790, 791, 7, 11, 0, 0, 791, 792, + 7, 9, 0, 0, 792, 793, 7, 11, 0, 0, 793, 794, 7, 20, 0, 0, 794, 214, 1, + 0, 0, 0, 795, 796, 7, 9, 0, 0, 796, 797, 7, 11, 0, 0, 797, 798, 7, 2, 0, + 0, 798, 799, 7, 10, 0, 0, 799, 216, 1, 0, 0, 0, 800, 801, 7, 8, 0, 0, 801, + 802, 7, 10, 0, 0, 802, 803, 7, 11, 0, 0, 803, 804, 7, 19, 0, 0, 804, 805, + 7, 7, 0, 0, 805, 806, 7, 9, 0, 0, 806, 807, 7, 8, 0, 0, 807, 808, 7, 2, + 0, 0, 808, 218, 1, 0, 0, 0, 809, 810, 7, 11, 0, 0, 810, 811, 7, 10, 0, + 0, 811, 812, 7, 2, 0, 0, 812, 813, 7, 24, 0, 0, 813, 814, 7, 9, 0, 0, 814, + 815, 7, 11, 0, 0, 815, 816, 7, 20, 0, 0, 816, 220, 1, 0, 0, 0, 817, 818, + 7, 19, 0, 0, 818, 819, 7, 10, 0, 0, 819, 820, 7, 13, 0, 0, 820, 222, 1, + 0, 0, 0, 821, 822, 7, 9, 0, 0, 822, 823, 7, 19, 0, 0, 823, 224, 1, 0, 0, + 0, 824, 825, 7, 5, 0, 0, 825, 826, 7, 7, 0, 0, 826, 827, 7, 4, 0, 0, 827, + 828, 7, 5, 0, 0, 828, 829, 7, 9, 0, 0, 829, 830, 7, 19, 0, 0, 830, 226, + 1, 0, 0, 0, 831, 832, 7, 5, 0, 0, 832, 833, 7, 7, 0, 0, 833, 834, 7, 4, + 0, 0, 834, 835, 7, 5, 0, 0, 835, 228, 1, 0, 0, 0, 836, 837, 7, 3, 0, 0, + 837, 838, 7, 13, 0, 0, 838, 839, 7, 5, 0, 0, 839, 840, 7, 1, 0, 0, 840, + 841, 7, 22, 0, 0, 841, 230, 1, 0, 0, 0, 842, 843, 7, 13, 0, 0, 843, 844, + 7, 5, 0, 0, 844, 845, 7, 2, 0, 0, 845, 846, 7, 6, 0, 0, 846, 847, 7, 13, + 0, 0, 847, 848, 7, 11, 0, 0, 848, 232, 1, 0, 0, 0, 849, 850, 7, 11, 0, + 0, 850, 851, 7, 5, 0, 0, 851, 852, 7, 17, 0, 0, 852, 853, 7, 2, 0, 0, 853, + 234, 1, 0, 0, 0, 854, 860, 5, 39, 0, 0, 855, 859, 8, 25, 0, 0, 856, 857, + 5, 92, 0, 0, 857, 859, 9, 0, 0, 0, 858, 855, 1, 0, 0, 0, 858, 856, 1, 0, + 0, 0, 859, 862, 1, 0, 0, 0, 860, 858, 1, 0, 0, 0, 860, 861, 1, 0, 0, 0, + 861, 863, 1, 0, 0, 0, 862, 860, 1, 0, 0, 0, 863, 864, 5, 39, 0, 0, 864, + 236, 1, 0, 0, 0, 865, 866, 7, 2, 0, 0, 866, 867, 7, 13, 0, 0, 867, 868, + 7, 6, 0, 0, 868, 869, 7, 5, 0, 0, 869, 238, 1, 0, 0, 0, 870, 871, 7, 19, + 0, 0, 871, 872, 7, 1, 0, 0, 872, 873, 7, 7, 0, 0, 873, 874, 7, 4, 0, 0, + 874, 875, 7, 5, 0, 0, 875, 240, 1, 0, 0, 0, 876, 878, 7, 26, 0, 0, 877, + 876, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 877, 1, 0, 0, 0, 879, 880, + 1, 0, 0, 0, 880, 242, 1, 0, 0, 0, 881, 882, 5, 48, 0, 0, 882, 883, 7, 17, + 0, 0, 883, 885, 1, 0, 0, 0, 884, 886, 7, 27, 0, 0, 885, 884, 1, 0, 0, 0, + 886, 887, 1, 0, 0, 0, 887, 885, 1, 0, 0, 0, 887, 888, 1, 0, 0, 0, 888, + 244, 1, 0, 0, 0, 889, 890, 7, 12, 0, 0, 890, 891, 7, 13, 0, 0, 891, 892, + 7, 9, 0, 0, 892, 893, 7, 16, 0, 0, 893, 894, 7, 1, 0, 0, 894, 895, 7, 13, + 0, 0, 895, 896, 7, 21, 0, 0, 896, 897, 5, 95, 0, 0, 897, 898, 7, 22, 0, + 0, 898, 899, 7, 5, 0, 0, 899, 903, 7, 21, 0, 0, 900, 901, 7, 12, 0, 0, + 901, 903, 7, 22, 0, 0, 902, 889, 1, 0, 0, 0, 902, 900, 1, 0, 0, 0, 903, + 246, 1, 0, 0, 0, 904, 905, 7, 19, 0, 0, 905, 906, 7, 10, 0, 0, 906, 907, + 7, 13, 0, 0, 907, 908, 7, 5, 0, 0, 908, 909, 7, 9, 0, 0, 909, 910, 7, 20, + 0, 0, 910, 911, 7, 11, 0, 0, 911, 912, 5, 95, 0, 0, 912, 913, 7, 22, 0, + 0, 913, 914, 7, 5, 0, 0, 914, 918, 7, 21, 0, 0, 915, 916, 7, 19, 0, 0, + 916, 918, 7, 22, 0, 0, 917, 904, 1, 0, 0, 0, 917, 915, 1, 0, 0, 0, 918, + 248, 1, 0, 0, 0, 919, 920, 7, 10, 0, 0, 920, 921, 7, 11, 0, 0, 921, 922, + 5, 95, 0, 0, 922, 923, 7, 6, 0, 0, 923, 924, 7, 12, 0, 0, 924, 925, 7, + 0, 0, 0, 925, 926, 7, 1, 0, 0, 926, 927, 7, 2, 0, 0, 927, 928, 7, 5, 0, + 0, 928, 250, 1, 0, 0, 0, 929, 930, 7, 10, 0, 0, 930, 931, 7, 11, 0, 0, + 931, 932, 5, 95, 0, 0, 932, 933, 7, 0, 0, 0, 933, 934, 7, 5, 0, 0, 934, + 935, 7, 7, 0, 0, 935, 936, 7, 5, 0, 0, 936, 937, 7, 2, 0, 0, 937, 938, + 7, 5, 0, 0, 938, 252, 1, 0, 0, 0, 939, 940, 7, 4, 0, 0, 940, 941, 7, 5, + 0, 0, 941, 942, 7, 2, 0, 0, 942, 943, 5, 95, 0, 0, 943, 944, 7, 0, 0, 0, + 944, 945, 7, 5, 0, 0, 945, 946, 7, 19, 0, 0, 946, 947, 7, 1, 0, 0, 947, + 948, 7, 6, 0, 0, 948, 949, 7, 7, 0, 0, 949, 950, 7, 2, 0, 0, 950, 254, + 1, 0, 0, 0, 951, 952, 7, 4, 0, 0, 952, 953, 7, 5, 0, 0, 953, 954, 7, 2, + 0, 0, 954, 955, 5, 95, 0, 0, 955, 956, 7, 11, 0, 0, 956, 957, 7, 6, 0, + 0, 957, 958, 7, 7, 0, 0, 958, 959, 7, 7, 0, 0, 959, 256, 1, 0, 0, 0, 960, + 961, 7, 11, 0, 0, 961, 962, 7, 10, 0, 0, 962, 963, 5, 95, 0, 0, 963, 964, + 7, 1, 0, 0, 964, 965, 7, 8, 0, 0, 965, 966, 7, 2, 0, 0, 966, 967, 7, 9, + 0, 0, 967, 968, 7, 10, 0, 0, 968, 969, 7, 11, 0, 0, 969, 258, 1, 0, 0, + 0, 970, 974, 7, 28, 0, 0, 971, 973, 7, 29, 0, 0, 972, 971, 1, 0, 0, 0, + 973, 976, 1, 0, 0, 0, 974, 972, 1, 0, 0, 0, 974, 975, 1, 0, 0, 0, 975, + 260, 1, 0, 0, 0, 976, 974, 1, 0, 0, 0, 977, 978, 3, 35, 17, 0, 978, 979, + 3, 259, 129, 0, 979, 262, 1, 0, 0, 0, 980, 981, 3, 19, 9, 0, 981, 982, + 3, 259, 129, 0, 982, 264, 1, 0, 0, 0, 983, 984, 3, 33, 16, 0, 984, 985, + 3, 259, 129, 0, 985, 266, 1, 0, 0, 0, 986, 987, 7, 30, 0, 0, 987, 988, + 1, 0, 0, 0, 988, 989, 6, 133, 0, 0, 989, 268, 1, 0, 0, 0, 990, 991, 5, + 47, 0, 0, 991, 992, 5, 42, 0, 0, 992, 996, 1, 0, 0, 0, 993, 995, 9, 0, + 0, 0, 994, 993, 1, 0, 0, 0, 995, 998, 1, 0, 0, 0, 996, 997, 1, 0, 0, 0, + 996, 994, 1, 0, 0, 0, 997, 999, 1, 0, 0, 0, 998, 996, 1, 0, 0, 0, 999, + 1000, 5, 42, 0, 0, 1000, 1001, 5, 47, 0, 0, 1001, 1002, 1, 0, 0, 0, 1002, + 1003, 6, 134, 0, 0, 1003, 270, 1, 0, 0, 0, 1004, 1005, 5, 47, 0, 0, 1005, + 1006, 5, 47, 0, 0, 1006, 1010, 1, 0, 0, 0, 1007, 1009, 8, 31, 0, 0, 1008, + 1007, 1, 0, 0, 0, 1009, 1012, 1, 0, 0, 0, 1010, 1008, 1, 0, 0, 0, 1010, + 1011, 1, 0, 0, 0, 1011, 1013, 1, 0, 0, 0, 1012, 1010, 1, 0, 0, 0, 1013, + 1014, 6, 135, 0, 0, 1014, 272, 1, 0, 0, 0, 11, 0, 323, 858, 860, 879, 887, + 902, 917, 974, 996, 1010, 1, 0, 1, 0, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// KuneiformLexerInit initializes any static state used to implement KuneiformLexer. By default the +// static state used to implement the lexer is lazily initialized during the first call to +// NewKuneiformLexer(). You can call this function if you wish to initialize the static state ahead +// of time. +func KuneiformLexerInit() { + staticData := &KuneiformLexerLexerStaticData + staticData.once.Do(kuneiformlexerLexerInit) +} + +// NewKuneiformLexer produces a new lexer instance for the optional input antlr.CharStream. +func NewKuneiformLexer(input antlr.CharStream) *KuneiformLexer { + KuneiformLexerInit() + l := new(KuneiformLexer) + l.BaseLexer = antlr.NewBaseLexer(input) + staticData := &KuneiformLexerLexerStaticData + l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) + l.channelNames = staticData.ChannelNames + l.modeNames = staticData.ModeNames + l.RuleNames = staticData.RuleNames + l.LiteralNames = staticData.LiteralNames + l.SymbolicNames = staticData.SymbolicNames + l.GrammarFileName = "KuneiformLexer.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// KuneiformLexer tokens. +const ( + KuneiformLexerLBRACE = 1 + KuneiformLexerRBRACE = 2 + KuneiformLexerLBRACKET = 3 + KuneiformLexerRBRACKET = 4 + KuneiformLexerCOL = 5 + KuneiformLexerSCOL = 6 + KuneiformLexerLPAREN = 7 + KuneiformLexerRPAREN = 8 + KuneiformLexerCOMMA = 9 + KuneiformLexerAT = 10 + KuneiformLexerEXCL = 11 + KuneiformLexerPERIOD = 12 + KuneiformLexerCONCAT = 13 + KuneiformLexerSTAR = 14 + KuneiformLexerEQUALS = 15 + KuneiformLexerEQUATE = 16 + KuneiformLexerHASH = 17 + KuneiformLexerDOLLAR = 18 + KuneiformLexerMOD = 19 + KuneiformLexerPLUS = 20 + KuneiformLexerMINUS = 21 + KuneiformLexerDIV = 22 + KuneiformLexerNEQ = 23 + KuneiformLexerLT = 24 + KuneiformLexerLTE = 25 + KuneiformLexerGT = 26 + KuneiformLexerGTE = 27 + KuneiformLexerTYPE_CAST = 28 + KuneiformLexerUNDERSCORE = 29 + KuneiformLexerASSIGN = 30 + KuneiformLexerRANGE = 31 + KuneiformLexerDOUBLE_QUOTE = 32 + KuneiformLexerDATABASE = 33 + KuneiformLexerUSE = 34 + KuneiformLexerTABLE = 35 + KuneiformLexerACTION = 36 + KuneiformLexerPROCEDURE = 37 + KuneiformLexerPUBLIC = 38 + KuneiformLexerPRIVATE = 39 + KuneiformLexerVIEW = 40 + KuneiformLexerOWNER = 41 + KuneiformLexerMIN = 42 + KuneiformLexerMAX = 43 + KuneiformLexerMINLEN = 44 + KuneiformLexerMAXLEN = 45 + KuneiformLexerUNIQUE = 46 + KuneiformLexerFOREIGN = 47 + KuneiformLexerPRIMARY = 48 + KuneiformLexerKEY = 49 + KuneiformLexerON = 50 + KuneiformLexerDO = 51 + KuneiformLexerCASCADE = 52 + KuneiformLexerRESTRICT = 53 + KuneiformLexerSET = 54 + KuneiformLexerDEFAULT = 55 + KuneiformLexerNULL = 56 + KuneiformLexerDELETE = 57 + KuneiformLexerUPDATE = 58 + KuneiformLexerREFERENCES = 59 + KuneiformLexerREF = 60 + KuneiformLexerNOT = 61 + KuneiformLexerINDEX = 62 + KuneiformLexerAND = 63 + KuneiformLexerOR = 64 + KuneiformLexerLIKE = 65 + KuneiformLexerIN = 66 + KuneiformLexerBETWEEN = 67 + KuneiformLexerIS = 68 + KuneiformLexerEXISTS = 69 + KuneiformLexerALL = 70 + KuneiformLexerANY = 71 + KuneiformLexerJOIN = 72 + KuneiformLexerLEFT = 73 + KuneiformLexerRIGHT = 74 + KuneiformLexerINNER = 75 + KuneiformLexerAS = 76 + KuneiformLexerASC = 77 + KuneiformLexerDESC = 78 + KuneiformLexerLIMIT = 79 + KuneiformLexerOFFSET = 80 + KuneiformLexerORDER = 81 + KuneiformLexerBY = 82 + KuneiformLexerGROUP = 83 + KuneiformLexerHAVING = 84 + KuneiformLexerRETURNS = 85 + KuneiformLexerNO = 86 + KuneiformLexerNOTNULL = 87 + KuneiformLexerWITH = 88 + KuneiformLexerCASE = 89 + KuneiformLexerWHEN = 90 + KuneiformLexerTHEN = 91 + KuneiformLexerEND = 92 + KuneiformLexerDISTINCT = 93 + KuneiformLexerFROM = 94 + KuneiformLexerWHERE = 95 + KuneiformLexerCOLLATE = 96 + KuneiformLexerSELECT = 97 + KuneiformLexerINSERT = 98 + KuneiformLexerVALUES = 99 + KuneiformLexerFULL = 100 + KuneiformLexerUNION = 101 + KuneiformLexerINTERSECT = 102 + KuneiformLexerEXCEPT = 103 + KuneiformLexerNULLS = 104 + KuneiformLexerFIRST = 105 + KuneiformLexerLAST = 106 + KuneiformLexerRETURNING = 107 + KuneiformLexerINTO = 108 + KuneiformLexerCONFLICT = 109 + KuneiformLexerNOTHING = 110 + KuneiformLexerFOR = 111 + KuneiformLexerIF = 112 + KuneiformLexerELSEIF = 113 + KuneiformLexerELSE = 114 + KuneiformLexerBREAK = 115 + KuneiformLexerRETURN = 116 + KuneiformLexerNEXT = 117 + KuneiformLexerSTRING_ = 118 + KuneiformLexerTRUE = 119 + KuneiformLexerFALSE = 120 + KuneiformLexerDIGITS_ = 121 + KuneiformLexerBINARY_ = 122 + KuneiformLexerLEGACY_PRIMARY_KEY = 123 + KuneiformLexerLEGACY_FOREIGN_KEY = 124 + KuneiformLexerLEGACY_ON_UPDATE = 125 + KuneiformLexerLEGACY_ON_DELETE = 126 + KuneiformLexerLEGACY_SET_DEFAULT = 127 + KuneiformLexerLEGACY_SET_NULL = 128 + KuneiformLexerLEGACY_NO_ACTION = 129 + KuneiformLexerIDENTIFIER = 130 + KuneiformLexerVARIABLE = 131 + KuneiformLexerCONTEXTUAL_VARIABLE = 132 + KuneiformLexerHASH_IDENTIFIER = 133 + KuneiformLexerWS = 134 + KuneiformLexerBLOCK_COMMENT = 135 + KuneiformLexerLINE_COMMENT = 136 +) diff --git a/parse/gen/kuneiform_parser.go b/parse/gen/kuneiform_parser.go new file mode 100644 index 000000000..4030cbe86 --- /dev/null +++ b/parse/gen/kuneiform_parser.go @@ -0,0 +1,19902 @@ +// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. + +package gen // KuneiformParser +import ( + "fmt" + "strconv" + "sync" + + "github.com/antlr4-go/antlr/v4" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = strconv.Itoa +var _ = sync.Once{} + +type KuneiformParser struct { + *antlr.BaseParser +} + +var KuneiformParserParserStaticData struct { + once sync.Once + serializedATN []int32 + LiteralNames []string + SymbolicNames []string + RuleNames []string + PredictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func kuneiformparserParserInit() { + staticData := &KuneiformParserParserStaticData + staticData.LiteralNames = []string{ + "", "'{'", "'}'", "'['", "']'", "':'", "';'", "'('", "')'", "','", "'@'", + "'!'", "'.'", "'||'", "'*'", "'='", "'=='", "'#'", "'$'", "'%'", "'+'", + "'-'", "'/'", "", "'<'", "'<='", "'>'", "'>='", "'::'", "'_'", "':='", + "'..'", "'\"'", "'database'", "'use'", "'table'", "'action'", "'procedure'", + "'public'", "'private'", "'view'", "'owner'", "'min'", "'max'", "'minlen'", + "'maxlen'", "'unique'", "'foreign'", "'primary'", "'key'", "'on'", "'do'", + "'cascade'", "'restrict'", "'set'", "'default'", "'null'", "'delete'", + "'update'", "'references'", "'ref'", "'not'", "'index'", "'and'", "'or'", + "'like'", "'in'", "'between'", "'is'", "'exists'", "'all'", "'any'", + "'join'", "'left'", "'right'", "'inner'", "'as'", "'asc'", "'desc'", + "'limit'", "'offset'", "'order'", "'by'", "'group'", "'having'", "'returns'", + "'no'", "'notnull'", "'with'", "'case'", "'when'", "'then'", "'end'", + "'distinct'", "'from'", "'where'", "'collate'", "'select'", "'insert'", + "'values'", "'full'", "'union'", "'intersect'", "'except'", "'nulls'", + "'first'", "'last'", "'returning'", "'into'", "'conflict'", "'nothing'", + "'for'", "'if'", "'elseif'", "'else'", "'break'", "'return'", "'next'", + "", "'true'", "'false'", "", "", "", "", "'on_update'", "'on_delete'", + "'set_default'", "'set_null'", "'no_action'", + } + staticData.SymbolicNames = []string{ + "", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", + "RPAREN", "COMMA", "AT", "EXCL", "PERIOD", "CONCAT", "STAR", "EQUALS", + "EQUATE", "HASH", "DOLLAR", "MOD", "PLUS", "MINUS", "DIV", "NEQ", "LT", + "LTE", "GT", "GTE", "TYPE_CAST", "UNDERSCORE", "ASSIGN", "RANGE", "DOUBLE_QUOTE", + "DATABASE", "USE", "TABLE", "ACTION", "PROCEDURE", "PUBLIC", "PRIVATE", + "VIEW", "OWNER", "MIN", "MAX", "MINLEN", "MAXLEN", "UNIQUE", "FOREIGN", + "PRIMARY", "KEY", "ON", "DO", "CASCADE", "RESTRICT", "SET", "DEFAULT", + "NULL", "DELETE", "UPDATE", "REFERENCES", "REF", "NOT", "INDEX", "AND", + "OR", "LIKE", "IN", "BETWEEN", "IS", "EXISTS", "ALL", "ANY", "JOIN", + "LEFT", "RIGHT", "INNER", "AS", "ASC", "DESC", "LIMIT", "OFFSET", "ORDER", + "BY", "GROUP", "HAVING", "RETURNS", "NO", "NOTNULL", "WITH", "CASE", + "WHEN", "THEN", "END", "DISTINCT", "FROM", "WHERE", "COLLATE", "SELECT", + "INSERT", "VALUES", "FULL", "UNION", "INTERSECT", "EXCEPT", "NULLS", + "FIRST", "LAST", "RETURNING", "INTO", "CONFLICT", "NOTHING", "FOR", + "IF", "ELSEIF", "ELSE", "BREAK", "RETURN", "NEXT", "STRING_", "TRUE", + "FALSE", "DIGITS_", "BINARY_", "LEGACY_PRIMARY_KEY", "LEGACY_FOREIGN_KEY", + "LEGACY_ON_UPDATE", "LEGACY_ON_DELETE", "LEGACY_SET_DEFAULT", "LEGACY_SET_NULL", + "LEGACY_NO_ACTION", "IDENTIFIER", "VARIABLE", "CONTEXTUAL_VARIABLE", + "HASH_IDENTIFIER", "WS", "BLOCK_COMMENT", "LINE_COMMENT", + } + staticData.RuleNames = []string{ + "entry", "literal", "identifier", "identifier_list", "type", "type_cast", + "variable", "variable_list", "schema", "annotation", "database_declaration", + "use_declaration", "table_declaration", "column_def", "index_def", "foreign_key_def", + "foreign_key_action", "type_list", "named_type_list", "typed_variable_list", + "constraint", "access_modifier", "action_declaration", "procedure_declaration", + "foreign_procedure_declaration", "procedure_return", "sql", "sql_statement", + "common_table_expression", "select_statement", "compound_operator", + "ordering_term", "select_core", "relation", "join", "result_column", + "update_statement", "update_set_clause", "insert_statement", "upsert_clause", + "delete_statement", "sql_expr", "when_then_clause", "sql_expr_list", + "sql_function_call", "action_block", "action_statement", "procedure_block", + "procedure_expr", "procedure_expr_list", "proc_statement", "variable_or_underscore", + "procedure_function_call", "if_then_block", "range", + } + staticData.PredictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 1, 136, 1125, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, + 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, + 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, + 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, + 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, + 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, + 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, + 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, + 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, + 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, + 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 115, 8, + 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 121, 8, 1, 1, 1, 1, 1, 3, 1, 125, 8, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 133, 8, 1, 1, 2, 1, 2, 1, 2, + 1, 2, 3, 2, 139, 8, 2, 1, 3, 1, 3, 1, 3, 5, 3, 144, 8, 3, 10, 3, 12, 3, + 147, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 155, 8, 4, 1, 4, 1, + 4, 3, 4, 159, 8, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 5, + 7, 169, 8, 7, 10, 7, 12, 7, 172, 9, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, + 8, 5, 8, 180, 8, 8, 10, 8, 12, 8, 183, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, + 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 194, 8, 9, 10, 9, 12, 9, 197, 9, 9, 3, + 9, 199, 8, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, + 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 217, 8, 11, + 10, 11, 12, 11, 220, 9, 11, 1, 11, 1, 11, 3, 11, 224, 8, 11, 1, 11, 1, + 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, + 3, 12, 238, 8, 12, 5, 12, 240, 8, 12, 10, 12, 12, 12, 243, 9, 12, 1, 12, + 1, 12, 1, 13, 1, 13, 1, 13, 5, 13, 250, 8, 13, 10, 13, 12, 13, 253, 9, + 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 3, 15, + 264, 8, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, + 15, 5, 15, 275, 8, 15, 10, 15, 12, 15, 278, 9, 15, 1, 16, 1, 16, 1, 16, + 3, 16, 283, 8, 16, 1, 16, 1, 16, 1, 16, 3, 16, 288, 8, 16, 3, 16, 290, + 8, 16, 1, 16, 3, 16, 293, 8, 16, 1, 16, 1, 16, 1, 16, 3, 16, 298, 8, 16, + 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 304, 8, 16, 1, 16, 1, 16, 1, 16, 3, + 16, 309, 8, 16, 1, 16, 3, 16, 312, 8, 16, 1, 17, 1, 17, 1, 17, 5, 17, 317, + 8, 17, 10, 17, 12, 17, 320, 9, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 5, + 18, 327, 8, 18, 10, 18, 12, 18, 330, 9, 18, 1, 19, 1, 19, 1, 19, 1, 19, + 1, 19, 1, 19, 5, 19, 338, 8, 19, 10, 19, 12, 19, 341, 9, 19, 1, 20, 1, + 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, + 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, + 20, 3, 20, 366, 8, 20, 1, 20, 1, 20, 1, 20, 3, 20, 371, 8, 20, 3, 20, 373, + 8, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 381, 8, 20, 1, + 21, 1, 21, 1, 22, 5, 22, 386, 8, 22, 10, 22, 12, 22, 389, 9, 22, 1, 22, + 1, 22, 1, 22, 1, 22, 3, 22, 395, 8, 22, 1, 22, 1, 22, 4, 22, 399, 8, 22, + 11, 22, 12, 22, 400, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 5, 23, 408, 8, + 23, 10, 23, 12, 23, 411, 9, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 417, + 8, 23, 1, 23, 1, 23, 4, 23, 421, 8, 23, 11, 23, 12, 23, 422, 1, 23, 3, + 23, 426, 8, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, + 1, 24, 1, 24, 3, 24, 438, 8, 24, 1, 24, 1, 24, 3, 24, 442, 8, 24, 1, 25, + 1, 25, 3, 25, 446, 8, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, + 25, 1, 25, 3, 25, 456, 8, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, + 1, 27, 5, 27, 465, 8, 27, 10, 27, 12, 27, 468, 9, 27, 3, 27, 470, 8, 27, + 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 476, 8, 27, 1, 28, 1, 28, 1, 28, 1, + 28, 1, 28, 5, 28, 483, 8, 28, 10, 28, 12, 28, 486, 9, 28, 3, 28, 488, 8, + 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, + 5, 29, 500, 8, 29, 10, 29, 12, 29, 503, 9, 29, 1, 29, 1, 29, 1, 29, 1, + 29, 1, 29, 5, 29, 510, 8, 29, 10, 29, 12, 29, 513, 9, 29, 3, 29, 515, 8, + 29, 1, 29, 1, 29, 3, 29, 519, 8, 29, 1, 29, 1, 29, 3, 29, 523, 8, 29, 1, + 30, 1, 30, 3, 30, 527, 8, 30, 1, 30, 1, 30, 3, 30, 531, 8, 30, 1, 31, 1, + 31, 3, 31, 535, 8, 31, 1, 31, 1, 31, 3, 31, 539, 8, 31, 1, 32, 1, 32, 3, + 32, 543, 8, 32, 1, 32, 1, 32, 1, 32, 5, 32, 548, 8, 32, 10, 32, 12, 32, + 551, 9, 32, 1, 32, 1, 32, 1, 32, 5, 32, 556, 8, 32, 10, 32, 12, 32, 559, + 9, 32, 3, 32, 561, 8, 32, 1, 32, 1, 32, 3, 32, 565, 8, 32, 1, 32, 1, 32, + 1, 32, 1, 32, 1, 32, 3, 32, 572, 8, 32, 3, 32, 574, 8, 32, 1, 33, 1, 33, + 3, 33, 578, 8, 33, 1, 33, 3, 33, 581, 8, 33, 1, 33, 1, 33, 1, 33, 1, 33, + 3, 33, 587, 8, 33, 1, 33, 3, 33, 590, 8, 33, 1, 33, 1, 33, 3, 33, 594, + 8, 33, 1, 33, 3, 33, 597, 8, 33, 3, 33, 599, 8, 33, 1, 34, 1, 34, 1, 34, + 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 3, 35, 609, 8, 35, 1, 35, 3, 35, 612, + 8, 35, 1, 35, 1, 35, 1, 35, 3, 35, 617, 8, 35, 1, 35, 3, 35, 620, 8, 35, + 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 626, 8, 36, 1, 36, 1, 36, 1, 36, 1, + 36, 5, 36, 632, 8, 36, 10, 36, 12, 36, 635, 9, 36, 1, 36, 1, 36, 1, 36, + 5, 36, 640, 8, 36, 10, 36, 12, 36, 643, 9, 36, 3, 36, 645, 8, 36, 1, 36, + 1, 36, 3, 36, 649, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, + 38, 1, 38, 1, 38, 3, 38, 660, 8, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, + 666, 8, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, + 38, 5, 38, 677, 8, 38, 10, 38, 12, 38, 680, 9, 38, 1, 38, 3, 38, 683, 8, + 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 692, 8, 39, + 3, 39, 694, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, + 39, 703, 8, 39, 10, 39, 12, 39, 706, 9, 39, 1, 39, 1, 39, 3, 39, 710, 8, + 39, 3, 39, 712, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 719, 8, + 40, 1, 40, 1, 40, 3, 40, 723, 8, 40, 1, 41, 1, 41, 1, 41, 3, 41, 728, 8, + 41, 1, 41, 1, 41, 3, 41, 732, 8, 41, 1, 41, 1, 41, 3, 41, 736, 8, 41, 1, + 41, 1, 41, 1, 41, 3, 41, 741, 8, 41, 1, 41, 1, 41, 3, 41, 745, 8, 41, 1, + 41, 1, 41, 1, 41, 1, 41, 3, 41, 751, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, + 3, 41, 757, 8, 41, 1, 41, 4, 41, 760, 8, 41, 11, 41, 12, 41, 761, 1, 41, + 1, 41, 3, 41, 766, 8, 41, 1, 41, 1, 41, 1, 41, 3, 41, 771, 8, 41, 1, 41, + 3, 41, 774, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 780, 8, 41, 3, 41, + 782, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 789, 8, 41, 1, 41, + 1, 41, 1, 41, 1, 41, 3, 41, 795, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, + 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, + 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, + 41, 1, 41, 1, 41, 3, 41, 825, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, + 831, 8, 41, 1, 41, 1, 41, 3, 41, 835, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, + 3, 41, 841, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 848, 8, 41, + 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 856, 8, 41, 5, 41, 858, + 8, 41, 10, 41, 12, 41, 861, 9, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, + 43, 1, 43, 1, 43, 5, 43, 871, 8, 43, 10, 43, 12, 43, 874, 9, 43, 1, 44, + 1, 44, 1, 44, 3, 44, 879, 8, 44, 1, 44, 1, 44, 3, 44, 883, 8, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 895, + 8, 44, 1, 44, 1, 44, 3, 44, 899, 8, 44, 1, 45, 1, 45, 1, 45, 5, 45, 904, + 8, 45, 10, 45, 12, 45, 907, 9, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 913, + 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 919, 8, 46, 1, 46, 1, 46, 1, + 46, 1, 46, 1, 46, 3, 46, 926, 8, 46, 1, 46, 3, 46, 929, 8, 46, 1, 47, 5, + 47, 932, 8, 47, 10, 47, 12, 47, 935, 9, 47, 1, 48, 1, 48, 1, 48, 3, 48, + 940, 8, 48, 1, 48, 1, 48, 3, 48, 944, 8, 48, 1, 48, 1, 48, 3, 48, 948, + 8, 48, 1, 48, 1, 48, 3, 48, 952, 8, 48, 1, 48, 1, 48, 3, 48, 956, 8, 48, + 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 962, 8, 48, 1, 48, 1, 48, 3, 48, 966, + 8, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, + 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 985, 8, 48, + 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 991, 8, 48, 5, 48, 993, 8, 48, 10, 48, + 12, 48, 996, 9, 48, 1, 49, 1, 49, 1, 49, 5, 49, 1001, 8, 49, 10, 49, 12, + 49, 1004, 9, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 5, 50, + 1013, 8, 50, 10, 50, 12, 50, 1016, 9, 50, 1, 50, 1, 50, 3, 50, 1020, 8, + 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 1027, 8, 50, 1, 50, 1, 50, + 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 1039, 8, + 50, 1, 50, 1, 50, 5, 50, 1043, 8, 50, 10, 50, 12, 50, 1046, 9, 50, 1, 50, + 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 5, 50, 1054, 8, 50, 10, 50, 12, 50, + 1057, 9, 50, 1, 50, 1, 50, 1, 50, 5, 50, 1062, 8, 50, 10, 50, 12, 50, 1065, + 9, 50, 1, 50, 3, 50, 1068, 8, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, + 50, 1, 50, 1, 50, 3, 50, 1078, 8, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, + 1, 50, 1, 50, 3, 50, 1087, 8, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 3, + 52, 1094, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, + 1, 52, 3, 52, 1105, 8, 52, 1, 52, 1, 52, 3, 52, 1109, 8, 52, 1, 53, 1, + 53, 1, 53, 5, 53, 1114, 8, 53, 10, 53, 12, 53, 1117, 9, 53, 1, 53, 1, 53, + 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 0, 2, 82, 96, 55, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, + 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, + 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 0, 14, 1, 0, 20, + 21, 1, 0, 119, 120, 1, 0, 131, 132, 3, 0, 46, 46, 48, 48, 62, 62, 1, 0, + 59, 60, 1, 0, 38, 41, 1, 0, 77, 78, 1, 0, 105, 106, 2, 0, 73, 75, 100, + 100, 2, 0, 20, 21, 61, 61, 2, 0, 15, 16, 23, 27, 3, 0, 14, 14, 19, 19, + 22, 22, 2, 0, 11, 11, 20, 21, 2, 0, 29, 29, 131, 131, 1284, 0, 114, 1, + 0, 0, 0, 2, 132, 1, 0, 0, 0, 4, 138, 1, 0, 0, 0, 6, 140, 1, 0, 0, 0, 8, + 148, 1, 0, 0, 0, 10, 160, 1, 0, 0, 0, 12, 163, 1, 0, 0, 0, 14, 165, 1, + 0, 0, 0, 16, 173, 1, 0, 0, 0, 18, 184, 1, 0, 0, 0, 20, 202, 1, 0, 0, 0, + 22, 206, 1, 0, 0, 0, 24, 229, 1, 0, 0, 0, 26, 246, 1, 0, 0, 0, 28, 254, + 1, 0, 0, 0, 30, 263, 1, 0, 0, 0, 32, 289, 1, 0, 0, 0, 34, 313, 1, 0, 0, + 0, 36, 321, 1, 0, 0, 0, 38, 331, 1, 0, 0, 0, 40, 380, 1, 0, 0, 0, 42, 382, + 1, 0, 0, 0, 44, 387, 1, 0, 0, 0, 46, 409, 1, 0, 0, 0, 48, 431, 1, 0, 0, + 0, 50, 443, 1, 0, 0, 0, 52, 457, 1, 0, 0, 0, 54, 469, 1, 0, 0, 0, 56, 477, + 1, 0, 0, 0, 58, 495, 1, 0, 0, 0, 60, 530, 1, 0, 0, 0, 62, 532, 1, 0, 0, + 0, 64, 540, 1, 0, 0, 0, 66, 598, 1, 0, 0, 0, 68, 600, 1, 0, 0, 0, 70, 619, + 1, 0, 0, 0, 72, 621, 1, 0, 0, 0, 74, 650, 1, 0, 0, 0, 76, 654, 1, 0, 0, + 0, 78, 684, 1, 0, 0, 0, 80, 713, 1, 0, 0, 0, 82, 781, 1, 0, 0, 0, 84, 862, + 1, 0, 0, 0, 86, 867, 1, 0, 0, 0, 88, 898, 1, 0, 0, 0, 90, 905, 1, 0, 0, + 0, 92, 928, 1, 0, 0, 0, 94, 933, 1, 0, 0, 0, 96, 965, 1, 0, 0, 0, 98, 997, + 1, 0, 0, 0, 100, 1086, 1, 0, 0, 0, 102, 1088, 1, 0, 0, 0, 104, 1108, 1, + 0, 0, 0, 106, 1110, 1, 0, 0, 0, 108, 1120, 1, 0, 0, 0, 110, 115, 3, 16, + 8, 0, 111, 115, 3, 52, 26, 0, 112, 115, 3, 90, 45, 0, 113, 115, 3, 94, + 47, 0, 114, 110, 1, 0, 0, 0, 114, 111, 1, 0, 0, 0, 114, 112, 1, 0, 0, 0, + 114, 113, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 117, 5, 0, 0, 1, 117, + 1, 1, 0, 0, 0, 118, 133, 5, 118, 0, 0, 119, 121, 7, 0, 0, 0, 120, 119, + 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 1, 0, 0, 0, 122, 133, 5, 121, + 0, 0, 123, 125, 7, 0, 0, 0, 124, 123, 1, 0, 0, 0, 124, 125, 1, 0, 0, 0, + 125, 126, 1, 0, 0, 0, 126, 127, 5, 121, 0, 0, 127, 128, 5, 12, 0, 0, 128, + 133, 5, 121, 0, 0, 129, 133, 7, 1, 0, 0, 130, 133, 5, 56, 0, 0, 131, 133, + 5, 122, 0, 0, 132, 118, 1, 0, 0, 0, 132, 120, 1, 0, 0, 0, 132, 124, 1, + 0, 0, 0, 132, 129, 1, 0, 0, 0, 132, 130, 1, 0, 0, 0, 132, 131, 1, 0, 0, + 0, 133, 3, 1, 0, 0, 0, 134, 135, 5, 32, 0, 0, 135, 136, 5, 130, 0, 0, 136, + 139, 5, 32, 0, 0, 137, 139, 5, 130, 0, 0, 138, 134, 1, 0, 0, 0, 138, 137, + 1, 0, 0, 0, 139, 5, 1, 0, 0, 0, 140, 145, 3, 4, 2, 0, 141, 142, 5, 9, 0, + 0, 142, 144, 3, 4, 2, 0, 143, 141, 1, 0, 0, 0, 144, 147, 1, 0, 0, 0, 145, + 143, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 7, 1, 0, 0, 0, 147, 145, 1, + 0, 0, 0, 148, 154, 5, 130, 0, 0, 149, 150, 5, 7, 0, 0, 150, 151, 5, 121, + 0, 0, 151, 152, 5, 9, 0, 0, 152, 153, 5, 121, 0, 0, 153, 155, 5, 8, 0, + 0, 154, 149, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 158, 1, 0, 0, 0, 156, + 157, 5, 3, 0, 0, 157, 159, 5, 4, 0, 0, 158, 156, 1, 0, 0, 0, 158, 159, + 1, 0, 0, 0, 159, 9, 1, 0, 0, 0, 160, 161, 5, 28, 0, 0, 161, 162, 3, 8, + 4, 0, 162, 11, 1, 0, 0, 0, 163, 164, 7, 2, 0, 0, 164, 13, 1, 0, 0, 0, 165, + 170, 3, 12, 6, 0, 166, 167, 5, 9, 0, 0, 167, 169, 3, 12, 6, 0, 168, 166, + 1, 0, 0, 0, 169, 172, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 170, 171, 1, 0, + 0, 0, 171, 15, 1, 0, 0, 0, 172, 170, 1, 0, 0, 0, 173, 181, 3, 20, 10, 0, + 174, 180, 3, 22, 11, 0, 175, 180, 3, 24, 12, 0, 176, 180, 3, 44, 22, 0, + 177, 180, 3, 46, 23, 0, 178, 180, 3, 48, 24, 0, 179, 174, 1, 0, 0, 0, 179, + 175, 1, 0, 0, 0, 179, 176, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 178, + 1, 0, 0, 0, 180, 183, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, + 0, 0, 182, 17, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 184, 185, 5, 132, 0, 0, + 185, 198, 5, 7, 0, 0, 186, 187, 5, 130, 0, 0, 187, 188, 5, 15, 0, 0, 188, + 195, 3, 2, 1, 0, 189, 190, 5, 9, 0, 0, 190, 191, 5, 130, 0, 0, 191, 192, + 5, 15, 0, 0, 192, 194, 3, 2, 1, 0, 193, 189, 1, 0, 0, 0, 194, 197, 1, 0, + 0, 0, 195, 193, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 199, 1, 0, 0, 0, + 197, 195, 1, 0, 0, 0, 198, 186, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, + 200, 1, 0, 0, 0, 200, 201, 5, 8, 0, 0, 201, 19, 1, 0, 0, 0, 202, 203, 5, + 33, 0, 0, 203, 204, 5, 130, 0, 0, 204, 205, 5, 6, 0, 0, 205, 21, 1, 0, + 0, 0, 206, 207, 5, 34, 0, 0, 207, 223, 5, 130, 0, 0, 208, 209, 5, 1, 0, + 0, 209, 210, 5, 130, 0, 0, 210, 211, 5, 5, 0, 0, 211, 218, 3, 2, 1, 0, + 212, 213, 5, 9, 0, 0, 213, 214, 5, 130, 0, 0, 214, 215, 5, 5, 0, 0, 215, + 217, 3, 2, 1, 0, 216, 212, 1, 0, 0, 0, 217, 220, 1, 0, 0, 0, 218, 216, + 1, 0, 0, 0, 218, 219, 1, 0, 0, 0, 219, 221, 1, 0, 0, 0, 220, 218, 1, 0, + 0, 0, 221, 222, 5, 2, 0, 0, 222, 224, 1, 0, 0, 0, 223, 208, 1, 0, 0, 0, + 223, 224, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 226, 5, 76, 0, 0, 226, + 227, 5, 130, 0, 0, 227, 228, 5, 6, 0, 0, 228, 23, 1, 0, 0, 0, 229, 230, + 5, 35, 0, 0, 230, 231, 5, 130, 0, 0, 231, 232, 5, 1, 0, 0, 232, 241, 3, + 26, 13, 0, 233, 237, 5, 9, 0, 0, 234, 238, 3, 26, 13, 0, 235, 238, 3, 28, + 14, 0, 236, 238, 3, 30, 15, 0, 237, 234, 1, 0, 0, 0, 237, 235, 1, 0, 0, + 0, 237, 236, 1, 0, 0, 0, 238, 240, 1, 0, 0, 0, 239, 233, 1, 0, 0, 0, 240, + 243, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 244, + 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 244, 245, 5, 2, 0, 0, 245, 25, 1, 0, + 0, 0, 246, 247, 5, 130, 0, 0, 247, 251, 3, 8, 4, 0, 248, 250, 3, 40, 20, + 0, 249, 248, 1, 0, 0, 0, 250, 253, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 251, + 252, 1, 0, 0, 0, 252, 27, 1, 0, 0, 0, 253, 251, 1, 0, 0, 0, 254, 255, 5, + 133, 0, 0, 255, 256, 7, 3, 0, 0, 256, 257, 5, 7, 0, 0, 257, 258, 3, 6, + 3, 0, 258, 259, 5, 8, 0, 0, 259, 29, 1, 0, 0, 0, 260, 261, 5, 47, 0, 0, + 261, 264, 5, 49, 0, 0, 262, 264, 5, 124, 0, 0, 263, 260, 1, 0, 0, 0, 263, + 262, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 266, 5, 7, 0, 0, 266, 267, + 3, 6, 3, 0, 267, 268, 5, 8, 0, 0, 268, 269, 7, 4, 0, 0, 269, 270, 5, 130, + 0, 0, 270, 271, 5, 7, 0, 0, 271, 272, 3, 6, 3, 0, 272, 276, 5, 8, 0, 0, + 273, 275, 3, 32, 16, 0, 274, 273, 1, 0, 0, 0, 275, 278, 1, 0, 0, 0, 276, + 274, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 31, 1, 0, 0, 0, 278, 276, 1, + 0, 0, 0, 279, 280, 5, 50, 0, 0, 280, 283, 5, 58, 0, 0, 281, 283, 5, 125, + 0, 0, 282, 279, 1, 0, 0, 0, 282, 281, 1, 0, 0, 0, 283, 290, 1, 0, 0, 0, + 284, 285, 5, 50, 0, 0, 285, 288, 5, 57, 0, 0, 286, 288, 5, 126, 0, 0, 287, + 284, 1, 0, 0, 0, 287, 286, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, 289, 282, + 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 290, 292, 1, 0, 0, 0, 291, 293, 5, 51, + 0, 0, 292, 291, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 311, 1, 0, 0, 0, + 294, 295, 5, 86, 0, 0, 295, 298, 5, 36, 0, 0, 296, 298, 5, 129, 0, 0, 297, + 294, 1, 0, 0, 0, 297, 296, 1, 0, 0, 0, 298, 312, 1, 0, 0, 0, 299, 312, + 5, 52, 0, 0, 300, 301, 5, 54, 0, 0, 301, 304, 5, 56, 0, 0, 302, 304, 5, + 128, 0, 0, 303, 300, 1, 0, 0, 0, 303, 302, 1, 0, 0, 0, 304, 312, 1, 0, + 0, 0, 305, 306, 5, 54, 0, 0, 306, 309, 5, 55, 0, 0, 307, 309, 5, 127, 0, + 0, 308, 305, 1, 0, 0, 0, 308, 307, 1, 0, 0, 0, 309, 312, 1, 0, 0, 0, 310, + 312, 5, 53, 0, 0, 311, 297, 1, 0, 0, 0, 311, 299, 1, 0, 0, 0, 311, 303, + 1, 0, 0, 0, 311, 308, 1, 0, 0, 0, 311, 310, 1, 0, 0, 0, 312, 33, 1, 0, + 0, 0, 313, 318, 3, 8, 4, 0, 314, 315, 5, 9, 0, 0, 315, 317, 3, 8, 4, 0, + 316, 314, 1, 0, 0, 0, 317, 320, 1, 0, 0, 0, 318, 316, 1, 0, 0, 0, 318, + 319, 1, 0, 0, 0, 319, 35, 1, 0, 0, 0, 320, 318, 1, 0, 0, 0, 321, 322, 5, + 130, 0, 0, 322, 328, 3, 8, 4, 0, 323, 324, 5, 9, 0, 0, 324, 325, 5, 130, + 0, 0, 325, 327, 3, 8, 4, 0, 326, 323, 1, 0, 0, 0, 327, 330, 1, 0, 0, 0, + 328, 326, 1, 0, 0, 0, 328, 329, 1, 0, 0, 0, 329, 37, 1, 0, 0, 0, 330, 328, + 1, 0, 0, 0, 331, 332, 3, 12, 6, 0, 332, 339, 3, 8, 4, 0, 333, 334, 5, 9, + 0, 0, 334, 335, 3, 12, 6, 0, 335, 336, 3, 8, 4, 0, 336, 338, 1, 0, 0, 0, + 337, 333, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, + 340, 1, 0, 0, 0, 340, 39, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, + 42, 0, 0, 343, 344, 5, 7, 0, 0, 344, 345, 3, 2, 1, 0, 345, 346, 5, 8, 0, + 0, 346, 381, 1, 0, 0, 0, 347, 348, 5, 43, 0, 0, 348, 349, 5, 7, 0, 0, 349, + 350, 3, 2, 1, 0, 350, 351, 5, 8, 0, 0, 351, 381, 1, 0, 0, 0, 352, 353, + 5, 44, 0, 0, 353, 354, 5, 7, 0, 0, 354, 355, 3, 2, 1, 0, 355, 356, 5, 8, + 0, 0, 356, 381, 1, 0, 0, 0, 357, 358, 5, 45, 0, 0, 358, 359, 5, 7, 0, 0, + 359, 360, 3, 2, 1, 0, 360, 361, 5, 8, 0, 0, 361, 381, 1, 0, 0, 0, 362, + 366, 5, 87, 0, 0, 363, 364, 5, 61, 0, 0, 364, 366, 5, 56, 0, 0, 365, 362, + 1, 0, 0, 0, 365, 363, 1, 0, 0, 0, 366, 381, 1, 0, 0, 0, 367, 373, 5, 123, + 0, 0, 368, 370, 5, 48, 0, 0, 369, 371, 5, 49, 0, 0, 370, 369, 1, 0, 0, + 0, 370, 371, 1, 0, 0, 0, 371, 373, 1, 0, 0, 0, 372, 367, 1, 0, 0, 0, 372, + 368, 1, 0, 0, 0, 373, 381, 1, 0, 0, 0, 374, 375, 5, 55, 0, 0, 375, 376, + 5, 7, 0, 0, 376, 377, 3, 2, 1, 0, 377, 378, 5, 8, 0, 0, 378, 381, 1, 0, + 0, 0, 379, 381, 5, 46, 0, 0, 380, 342, 1, 0, 0, 0, 380, 347, 1, 0, 0, 0, + 380, 352, 1, 0, 0, 0, 380, 357, 1, 0, 0, 0, 380, 365, 1, 0, 0, 0, 380, + 372, 1, 0, 0, 0, 380, 374, 1, 0, 0, 0, 380, 379, 1, 0, 0, 0, 381, 41, 1, + 0, 0, 0, 382, 383, 7, 5, 0, 0, 383, 43, 1, 0, 0, 0, 384, 386, 3, 18, 9, + 0, 385, 384, 1, 0, 0, 0, 386, 389, 1, 0, 0, 0, 387, 385, 1, 0, 0, 0, 387, + 388, 1, 0, 0, 0, 388, 390, 1, 0, 0, 0, 389, 387, 1, 0, 0, 0, 390, 391, + 5, 36, 0, 0, 391, 392, 5, 130, 0, 0, 392, 394, 5, 7, 0, 0, 393, 395, 3, + 14, 7, 0, 394, 393, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 395, 396, 1, 0, 0, + 0, 396, 398, 5, 8, 0, 0, 397, 399, 3, 42, 21, 0, 398, 397, 1, 0, 0, 0, + 399, 400, 1, 0, 0, 0, 400, 398, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, + 402, 1, 0, 0, 0, 402, 403, 5, 1, 0, 0, 403, 404, 3, 90, 45, 0, 404, 405, + 5, 2, 0, 0, 405, 45, 1, 0, 0, 0, 406, 408, 3, 18, 9, 0, 407, 406, 1, 0, + 0, 0, 408, 411, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, + 410, 412, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 412, 413, 5, 37, 0, 0, 413, + 414, 5, 130, 0, 0, 414, 416, 5, 7, 0, 0, 415, 417, 3, 38, 19, 0, 416, 415, + 1, 0, 0, 0, 416, 417, 1, 0, 0, 0, 417, 418, 1, 0, 0, 0, 418, 420, 5, 8, + 0, 0, 419, 421, 3, 42, 21, 0, 420, 419, 1, 0, 0, 0, 421, 422, 1, 0, 0, + 0, 422, 420, 1, 0, 0, 0, 422, 423, 1, 0, 0, 0, 423, 425, 1, 0, 0, 0, 424, + 426, 3, 50, 25, 0, 425, 424, 1, 0, 0, 0, 425, 426, 1, 0, 0, 0, 426, 427, + 1, 0, 0, 0, 427, 428, 5, 1, 0, 0, 428, 429, 3, 94, 47, 0, 429, 430, 5, + 2, 0, 0, 430, 47, 1, 0, 0, 0, 431, 432, 5, 47, 0, 0, 432, 433, 5, 37, 0, + 0, 433, 434, 5, 130, 0, 0, 434, 437, 5, 7, 0, 0, 435, 438, 3, 34, 17, 0, + 436, 438, 3, 38, 19, 0, 437, 435, 1, 0, 0, 0, 437, 436, 1, 0, 0, 0, 437, + 438, 1, 0, 0, 0, 438, 439, 1, 0, 0, 0, 439, 441, 5, 8, 0, 0, 440, 442, + 3, 50, 25, 0, 441, 440, 1, 0, 0, 0, 441, 442, 1, 0, 0, 0, 442, 49, 1, 0, + 0, 0, 443, 455, 5, 85, 0, 0, 444, 446, 5, 35, 0, 0, 445, 444, 1, 0, 0, + 0, 445, 446, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 448, 5, 7, 0, 0, 448, + 449, 3, 36, 18, 0, 449, 450, 5, 8, 0, 0, 450, 456, 1, 0, 0, 0, 451, 452, + 5, 7, 0, 0, 452, 453, 3, 34, 17, 0, 453, 454, 5, 8, 0, 0, 454, 456, 1, + 0, 0, 0, 455, 445, 1, 0, 0, 0, 455, 451, 1, 0, 0, 0, 456, 51, 1, 0, 0, + 0, 457, 458, 3, 54, 27, 0, 458, 459, 5, 6, 0, 0, 459, 53, 1, 0, 0, 0, 460, + 461, 5, 88, 0, 0, 461, 466, 3, 56, 28, 0, 462, 463, 5, 9, 0, 0, 463, 465, + 3, 56, 28, 0, 464, 462, 1, 0, 0, 0, 465, 468, 1, 0, 0, 0, 466, 464, 1, + 0, 0, 0, 466, 467, 1, 0, 0, 0, 467, 470, 1, 0, 0, 0, 468, 466, 1, 0, 0, + 0, 469, 460, 1, 0, 0, 0, 469, 470, 1, 0, 0, 0, 470, 475, 1, 0, 0, 0, 471, + 476, 3, 58, 29, 0, 472, 476, 3, 72, 36, 0, 473, 476, 3, 76, 38, 0, 474, + 476, 3, 80, 40, 0, 475, 471, 1, 0, 0, 0, 475, 472, 1, 0, 0, 0, 475, 473, + 1, 0, 0, 0, 475, 474, 1, 0, 0, 0, 476, 55, 1, 0, 0, 0, 477, 478, 3, 4, + 2, 0, 478, 487, 5, 7, 0, 0, 479, 484, 3, 4, 2, 0, 480, 481, 5, 9, 0, 0, + 481, 483, 3, 4, 2, 0, 482, 480, 1, 0, 0, 0, 483, 486, 1, 0, 0, 0, 484, + 482, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 488, 1, 0, 0, 0, 486, 484, + 1, 0, 0, 0, 487, 479, 1, 0, 0, 0, 487, 488, 1, 0, 0, 0, 488, 489, 1, 0, + 0, 0, 489, 490, 5, 8, 0, 0, 490, 491, 5, 76, 0, 0, 491, 492, 5, 7, 0, 0, + 492, 493, 3, 58, 29, 0, 493, 494, 5, 8, 0, 0, 494, 57, 1, 0, 0, 0, 495, + 501, 3, 64, 32, 0, 496, 497, 3, 60, 30, 0, 497, 498, 3, 64, 32, 0, 498, + 500, 1, 0, 0, 0, 499, 496, 1, 0, 0, 0, 500, 503, 1, 0, 0, 0, 501, 499, + 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 514, 1, 0, 0, 0, 503, 501, 1, 0, + 0, 0, 504, 505, 5, 81, 0, 0, 505, 506, 5, 82, 0, 0, 506, 511, 3, 62, 31, + 0, 507, 508, 5, 9, 0, 0, 508, 510, 3, 62, 31, 0, 509, 507, 1, 0, 0, 0, + 510, 513, 1, 0, 0, 0, 511, 509, 1, 0, 0, 0, 511, 512, 1, 0, 0, 0, 512, + 515, 1, 0, 0, 0, 513, 511, 1, 0, 0, 0, 514, 504, 1, 0, 0, 0, 514, 515, + 1, 0, 0, 0, 515, 518, 1, 0, 0, 0, 516, 517, 5, 79, 0, 0, 517, 519, 3, 82, + 41, 0, 518, 516, 1, 0, 0, 0, 518, 519, 1, 0, 0, 0, 519, 522, 1, 0, 0, 0, + 520, 521, 5, 80, 0, 0, 521, 523, 3, 82, 41, 0, 522, 520, 1, 0, 0, 0, 522, + 523, 1, 0, 0, 0, 523, 59, 1, 0, 0, 0, 524, 526, 5, 101, 0, 0, 525, 527, + 5, 70, 0, 0, 526, 525, 1, 0, 0, 0, 526, 527, 1, 0, 0, 0, 527, 531, 1, 0, + 0, 0, 528, 531, 5, 102, 0, 0, 529, 531, 5, 103, 0, 0, 530, 524, 1, 0, 0, + 0, 530, 528, 1, 0, 0, 0, 530, 529, 1, 0, 0, 0, 531, 61, 1, 0, 0, 0, 532, + 534, 3, 82, 41, 0, 533, 535, 7, 6, 0, 0, 534, 533, 1, 0, 0, 0, 534, 535, + 1, 0, 0, 0, 535, 538, 1, 0, 0, 0, 536, 537, 5, 104, 0, 0, 537, 539, 7, + 7, 0, 0, 538, 536, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 63, 1, 0, 0, + 0, 540, 542, 5, 97, 0, 0, 541, 543, 5, 93, 0, 0, 542, 541, 1, 0, 0, 0, + 542, 543, 1, 0, 0, 0, 543, 544, 1, 0, 0, 0, 544, 549, 3, 70, 35, 0, 545, + 546, 5, 9, 0, 0, 546, 548, 3, 70, 35, 0, 547, 545, 1, 0, 0, 0, 548, 551, + 1, 0, 0, 0, 549, 547, 1, 0, 0, 0, 549, 550, 1, 0, 0, 0, 550, 560, 1, 0, + 0, 0, 551, 549, 1, 0, 0, 0, 552, 553, 5, 94, 0, 0, 553, 557, 3, 66, 33, + 0, 554, 556, 3, 68, 34, 0, 555, 554, 1, 0, 0, 0, 556, 559, 1, 0, 0, 0, + 557, 555, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 558, 561, 1, 0, 0, 0, 559, + 557, 1, 0, 0, 0, 560, 552, 1, 0, 0, 0, 560, 561, 1, 0, 0, 0, 561, 564, + 1, 0, 0, 0, 562, 563, 5, 95, 0, 0, 563, 565, 3, 82, 41, 0, 564, 562, 1, + 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 573, 1, 0, 0, 0, 566, 567, 5, 83, 0, + 0, 567, 568, 5, 82, 0, 0, 568, 571, 3, 86, 43, 0, 569, 570, 5, 84, 0, 0, + 570, 572, 3, 82, 41, 0, 571, 569, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, + 574, 1, 0, 0, 0, 573, 566, 1, 0, 0, 0, 573, 574, 1, 0, 0, 0, 574, 65, 1, + 0, 0, 0, 575, 580, 3, 4, 2, 0, 576, 578, 5, 76, 0, 0, 577, 576, 1, 0, 0, + 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 581, 3, 4, 2, 0, 580, + 577, 1, 0, 0, 0, 580, 581, 1, 0, 0, 0, 581, 599, 1, 0, 0, 0, 582, 583, + 5, 7, 0, 0, 583, 584, 3, 58, 29, 0, 584, 589, 5, 8, 0, 0, 585, 587, 5, + 76, 0, 0, 586, 585, 1, 0, 0, 0, 586, 587, 1, 0, 0, 0, 587, 588, 1, 0, 0, + 0, 588, 590, 3, 4, 2, 0, 589, 586, 1, 0, 0, 0, 589, 590, 1, 0, 0, 0, 590, + 599, 1, 0, 0, 0, 591, 593, 3, 88, 44, 0, 592, 594, 5, 76, 0, 0, 593, 592, + 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 596, 1, 0, 0, 0, 595, 597, 3, 4, + 2, 0, 596, 595, 1, 0, 0, 0, 596, 597, 1, 0, 0, 0, 597, 599, 1, 0, 0, 0, + 598, 575, 1, 0, 0, 0, 598, 582, 1, 0, 0, 0, 598, 591, 1, 0, 0, 0, 599, + 67, 1, 0, 0, 0, 600, 601, 7, 8, 0, 0, 601, 602, 5, 72, 0, 0, 602, 603, + 3, 66, 33, 0, 603, 604, 5, 50, 0, 0, 604, 605, 3, 82, 41, 0, 605, 69, 1, + 0, 0, 0, 606, 611, 3, 82, 41, 0, 607, 609, 5, 76, 0, 0, 608, 607, 1, 0, + 0, 0, 608, 609, 1, 0, 0, 0, 609, 610, 1, 0, 0, 0, 610, 612, 3, 4, 2, 0, + 611, 608, 1, 0, 0, 0, 611, 612, 1, 0, 0, 0, 612, 620, 1, 0, 0, 0, 613, + 614, 3, 4, 2, 0, 614, 615, 5, 12, 0, 0, 615, 617, 1, 0, 0, 0, 616, 613, + 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 617, 618, 1, 0, 0, 0, 618, 620, 5, 14, + 0, 0, 619, 606, 1, 0, 0, 0, 619, 616, 1, 0, 0, 0, 620, 71, 1, 0, 0, 0, + 621, 622, 5, 58, 0, 0, 622, 625, 3, 4, 2, 0, 623, 624, 5, 76, 0, 0, 624, + 626, 3, 4, 2, 0, 625, 623, 1, 0, 0, 0, 625, 626, 1, 0, 0, 0, 626, 627, + 1, 0, 0, 0, 627, 628, 5, 54, 0, 0, 628, 633, 3, 74, 37, 0, 629, 630, 5, + 9, 0, 0, 630, 632, 3, 74, 37, 0, 631, 629, 1, 0, 0, 0, 632, 635, 1, 0, + 0, 0, 633, 631, 1, 0, 0, 0, 633, 634, 1, 0, 0, 0, 634, 644, 1, 0, 0, 0, + 635, 633, 1, 0, 0, 0, 636, 637, 5, 94, 0, 0, 637, 641, 3, 66, 33, 0, 638, + 640, 3, 68, 34, 0, 639, 638, 1, 0, 0, 0, 640, 643, 1, 0, 0, 0, 641, 639, + 1, 0, 0, 0, 641, 642, 1, 0, 0, 0, 642, 645, 1, 0, 0, 0, 643, 641, 1, 0, + 0, 0, 644, 636, 1, 0, 0, 0, 644, 645, 1, 0, 0, 0, 645, 648, 1, 0, 0, 0, + 646, 647, 5, 95, 0, 0, 647, 649, 3, 82, 41, 0, 648, 646, 1, 0, 0, 0, 648, + 649, 1, 0, 0, 0, 649, 73, 1, 0, 0, 0, 650, 651, 3, 4, 2, 0, 651, 652, 5, + 15, 0, 0, 652, 653, 3, 82, 41, 0, 653, 75, 1, 0, 0, 0, 654, 655, 5, 98, + 0, 0, 655, 656, 5, 108, 0, 0, 656, 659, 3, 4, 2, 0, 657, 658, 5, 76, 0, + 0, 658, 660, 3, 4, 2, 0, 659, 657, 1, 0, 0, 0, 659, 660, 1, 0, 0, 0, 660, + 665, 1, 0, 0, 0, 661, 662, 5, 7, 0, 0, 662, 663, 3, 6, 3, 0, 663, 664, + 5, 8, 0, 0, 664, 666, 1, 0, 0, 0, 665, 661, 1, 0, 0, 0, 665, 666, 1, 0, + 0, 0, 666, 667, 1, 0, 0, 0, 667, 668, 5, 99, 0, 0, 668, 669, 5, 7, 0, 0, + 669, 670, 3, 86, 43, 0, 670, 678, 5, 8, 0, 0, 671, 672, 5, 9, 0, 0, 672, + 673, 5, 7, 0, 0, 673, 674, 3, 86, 43, 0, 674, 675, 5, 8, 0, 0, 675, 677, + 1, 0, 0, 0, 676, 671, 1, 0, 0, 0, 677, 680, 1, 0, 0, 0, 678, 676, 1, 0, + 0, 0, 678, 679, 1, 0, 0, 0, 679, 682, 1, 0, 0, 0, 680, 678, 1, 0, 0, 0, + 681, 683, 3, 78, 39, 0, 682, 681, 1, 0, 0, 0, 682, 683, 1, 0, 0, 0, 683, + 77, 1, 0, 0, 0, 684, 685, 5, 50, 0, 0, 685, 693, 5, 109, 0, 0, 686, 687, + 5, 7, 0, 0, 687, 688, 3, 6, 3, 0, 688, 691, 5, 8, 0, 0, 689, 690, 5, 95, + 0, 0, 690, 692, 3, 82, 41, 0, 691, 689, 1, 0, 0, 0, 691, 692, 1, 0, 0, + 0, 692, 694, 1, 0, 0, 0, 693, 686, 1, 0, 0, 0, 693, 694, 1, 0, 0, 0, 694, + 695, 1, 0, 0, 0, 695, 711, 5, 51, 0, 0, 696, 712, 5, 110, 0, 0, 697, 698, + 5, 58, 0, 0, 698, 699, 5, 54, 0, 0, 699, 704, 3, 74, 37, 0, 700, 701, 5, + 9, 0, 0, 701, 703, 3, 74, 37, 0, 702, 700, 1, 0, 0, 0, 703, 706, 1, 0, + 0, 0, 704, 702, 1, 0, 0, 0, 704, 705, 1, 0, 0, 0, 705, 709, 1, 0, 0, 0, + 706, 704, 1, 0, 0, 0, 707, 708, 5, 95, 0, 0, 708, 710, 3, 82, 41, 0, 709, + 707, 1, 0, 0, 0, 709, 710, 1, 0, 0, 0, 710, 712, 1, 0, 0, 0, 711, 696, + 1, 0, 0, 0, 711, 697, 1, 0, 0, 0, 712, 79, 1, 0, 0, 0, 713, 714, 5, 57, + 0, 0, 714, 715, 5, 94, 0, 0, 715, 718, 3, 4, 2, 0, 716, 717, 5, 76, 0, + 0, 717, 719, 3, 4, 2, 0, 718, 716, 1, 0, 0, 0, 718, 719, 1, 0, 0, 0, 719, + 722, 1, 0, 0, 0, 720, 721, 5, 95, 0, 0, 721, 723, 3, 82, 41, 0, 722, 720, + 1, 0, 0, 0, 722, 723, 1, 0, 0, 0, 723, 81, 1, 0, 0, 0, 724, 725, 6, 41, + -1, 0, 725, 727, 3, 2, 1, 0, 726, 728, 3, 10, 5, 0, 727, 726, 1, 0, 0, + 0, 727, 728, 1, 0, 0, 0, 728, 782, 1, 0, 0, 0, 729, 731, 3, 88, 44, 0, + 730, 732, 3, 10, 5, 0, 731, 730, 1, 0, 0, 0, 731, 732, 1, 0, 0, 0, 732, + 782, 1, 0, 0, 0, 733, 735, 3, 12, 6, 0, 734, 736, 3, 10, 5, 0, 735, 734, + 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 782, 1, 0, 0, 0, 737, 738, 3, 4, + 2, 0, 738, 739, 5, 12, 0, 0, 739, 741, 1, 0, 0, 0, 740, 737, 1, 0, 0, 0, + 740, 741, 1, 0, 0, 0, 741, 742, 1, 0, 0, 0, 742, 744, 3, 4, 2, 0, 743, + 745, 3, 10, 5, 0, 744, 743, 1, 0, 0, 0, 744, 745, 1, 0, 0, 0, 745, 782, + 1, 0, 0, 0, 746, 747, 5, 7, 0, 0, 747, 748, 3, 82, 41, 0, 748, 750, 5, + 8, 0, 0, 749, 751, 3, 10, 5, 0, 750, 749, 1, 0, 0, 0, 750, 751, 1, 0, 0, + 0, 751, 782, 1, 0, 0, 0, 752, 753, 7, 9, 0, 0, 753, 782, 3, 82, 41, 10, + 754, 756, 5, 89, 0, 0, 755, 757, 3, 82, 41, 0, 756, 755, 1, 0, 0, 0, 756, + 757, 1, 0, 0, 0, 757, 759, 1, 0, 0, 0, 758, 760, 3, 84, 42, 0, 759, 758, + 1, 0, 0, 0, 760, 761, 1, 0, 0, 0, 761, 759, 1, 0, 0, 0, 761, 762, 1, 0, + 0, 0, 762, 765, 1, 0, 0, 0, 763, 764, 5, 114, 0, 0, 764, 766, 3, 82, 41, + 0, 765, 763, 1, 0, 0, 0, 765, 766, 1, 0, 0, 0, 766, 767, 1, 0, 0, 0, 767, + 768, 5, 92, 0, 0, 768, 782, 1, 0, 0, 0, 769, 771, 5, 61, 0, 0, 770, 769, + 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 1, 0, 0, 0, 772, 774, 5, 69, + 0, 0, 773, 770, 1, 0, 0, 0, 773, 774, 1, 0, 0, 0, 774, 775, 1, 0, 0, 0, + 775, 776, 5, 7, 0, 0, 776, 777, 3, 58, 29, 0, 777, 779, 5, 8, 0, 0, 778, + 780, 3, 10, 5, 0, 779, 778, 1, 0, 0, 0, 779, 780, 1, 0, 0, 0, 780, 782, + 1, 0, 0, 0, 781, 724, 1, 0, 0, 0, 781, 729, 1, 0, 0, 0, 781, 733, 1, 0, + 0, 0, 781, 740, 1, 0, 0, 0, 781, 746, 1, 0, 0, 0, 781, 752, 1, 0, 0, 0, + 781, 754, 1, 0, 0, 0, 781, 773, 1, 0, 0, 0, 782, 859, 1, 0, 0, 0, 783, + 784, 10, 13, 0, 0, 784, 785, 7, 10, 0, 0, 785, 858, 3, 82, 41, 14, 786, + 788, 10, 11, 0, 0, 787, 789, 5, 61, 0, 0, 788, 787, 1, 0, 0, 0, 788, 789, + 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 791, 5, 65, 0, 0, 791, 858, 3, 82, + 41, 12, 792, 794, 10, 9, 0, 0, 793, 795, 5, 61, 0, 0, 794, 793, 1, 0, 0, + 0, 794, 795, 1, 0, 0, 0, 795, 796, 1, 0, 0, 0, 796, 797, 5, 67, 0, 0, 797, + 798, 3, 82, 41, 0, 798, 799, 5, 63, 0, 0, 799, 800, 3, 82, 41, 10, 800, + 858, 1, 0, 0, 0, 801, 802, 10, 5, 0, 0, 802, 803, 5, 13, 0, 0, 803, 858, + 3, 82, 41, 6, 804, 805, 10, 4, 0, 0, 805, 806, 7, 11, 0, 0, 806, 858, 3, + 82, 41, 5, 807, 808, 10, 3, 0, 0, 808, 809, 7, 0, 0, 0, 809, 858, 3, 82, + 41, 4, 810, 811, 10, 2, 0, 0, 811, 812, 5, 63, 0, 0, 812, 858, 3, 82, 41, + 3, 813, 814, 10, 1, 0, 0, 814, 815, 5, 64, 0, 0, 815, 858, 3, 82, 41, 2, + 816, 817, 10, 20, 0, 0, 817, 818, 5, 96, 0, 0, 818, 858, 3, 4, 2, 0, 819, + 820, 10, 16, 0, 0, 820, 821, 5, 3, 0, 0, 821, 822, 3, 82, 41, 0, 822, 824, + 5, 4, 0, 0, 823, 825, 3, 10, 5, 0, 824, 823, 1, 0, 0, 0, 824, 825, 1, 0, + 0, 0, 825, 858, 1, 0, 0, 0, 826, 827, 10, 15, 0, 0, 827, 828, 5, 12, 0, + 0, 828, 830, 3, 4, 2, 0, 829, 831, 3, 10, 5, 0, 830, 829, 1, 0, 0, 0, 830, + 831, 1, 0, 0, 0, 831, 858, 1, 0, 0, 0, 832, 834, 10, 12, 0, 0, 833, 835, + 5, 61, 0, 0, 834, 833, 1, 0, 0, 0, 834, 835, 1, 0, 0, 0, 835, 836, 1, 0, + 0, 0, 836, 837, 5, 66, 0, 0, 837, 840, 5, 7, 0, 0, 838, 841, 3, 86, 43, + 0, 839, 841, 3, 58, 29, 0, 840, 838, 1, 0, 0, 0, 840, 839, 1, 0, 0, 0, + 841, 842, 1, 0, 0, 0, 842, 843, 5, 8, 0, 0, 843, 858, 1, 0, 0, 0, 844, + 845, 10, 8, 0, 0, 845, 847, 5, 68, 0, 0, 846, 848, 5, 61, 0, 0, 847, 846, + 1, 0, 0, 0, 847, 848, 1, 0, 0, 0, 848, 855, 1, 0, 0, 0, 849, 850, 5, 93, + 0, 0, 850, 851, 5, 94, 0, 0, 851, 856, 3, 82, 41, 0, 852, 856, 5, 56, 0, + 0, 853, 856, 5, 119, 0, 0, 854, 856, 5, 120, 0, 0, 855, 849, 1, 0, 0, 0, + 855, 852, 1, 0, 0, 0, 855, 853, 1, 0, 0, 0, 855, 854, 1, 0, 0, 0, 856, + 858, 1, 0, 0, 0, 857, 783, 1, 0, 0, 0, 857, 786, 1, 0, 0, 0, 857, 792, + 1, 0, 0, 0, 857, 801, 1, 0, 0, 0, 857, 804, 1, 0, 0, 0, 857, 807, 1, 0, + 0, 0, 857, 810, 1, 0, 0, 0, 857, 813, 1, 0, 0, 0, 857, 816, 1, 0, 0, 0, + 857, 819, 1, 0, 0, 0, 857, 826, 1, 0, 0, 0, 857, 832, 1, 0, 0, 0, 857, + 844, 1, 0, 0, 0, 858, 861, 1, 0, 0, 0, 859, 857, 1, 0, 0, 0, 859, 860, + 1, 0, 0, 0, 860, 83, 1, 0, 0, 0, 861, 859, 1, 0, 0, 0, 862, 863, 5, 90, + 0, 0, 863, 864, 3, 82, 41, 0, 864, 865, 5, 91, 0, 0, 865, 866, 3, 82, 41, + 0, 866, 85, 1, 0, 0, 0, 867, 872, 3, 82, 41, 0, 868, 869, 5, 9, 0, 0, 869, + 871, 3, 82, 41, 0, 870, 868, 1, 0, 0, 0, 871, 874, 1, 0, 0, 0, 872, 870, + 1, 0, 0, 0, 872, 873, 1, 0, 0, 0, 873, 87, 1, 0, 0, 0, 874, 872, 1, 0, + 0, 0, 875, 876, 3, 4, 2, 0, 876, 882, 5, 7, 0, 0, 877, 879, 5, 93, 0, 0, + 878, 877, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 1, 0, 0, 0, 880, + 883, 3, 86, 43, 0, 881, 883, 5, 14, 0, 0, 882, 878, 1, 0, 0, 0, 882, 881, + 1, 0, 0, 0, 882, 883, 1, 0, 0, 0, 883, 884, 1, 0, 0, 0, 884, 885, 5, 8, + 0, 0, 885, 899, 1, 0, 0, 0, 886, 887, 3, 4, 2, 0, 887, 888, 5, 3, 0, 0, + 888, 889, 3, 82, 41, 0, 889, 890, 5, 9, 0, 0, 890, 891, 3, 82, 41, 0, 891, + 892, 5, 4, 0, 0, 892, 894, 5, 7, 0, 0, 893, 895, 3, 86, 43, 0, 894, 893, + 1, 0, 0, 0, 894, 895, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 5, 8, + 0, 0, 897, 899, 1, 0, 0, 0, 898, 875, 1, 0, 0, 0, 898, 886, 1, 0, 0, 0, + 899, 89, 1, 0, 0, 0, 900, 901, 3, 92, 46, 0, 901, 902, 5, 6, 0, 0, 902, + 904, 1, 0, 0, 0, 903, 900, 1, 0, 0, 0, 904, 907, 1, 0, 0, 0, 905, 903, + 1, 0, 0, 0, 905, 906, 1, 0, 0, 0, 906, 91, 1, 0, 0, 0, 907, 905, 1, 0, + 0, 0, 908, 929, 3, 54, 27, 0, 909, 910, 5, 130, 0, 0, 910, 912, 5, 7, 0, + 0, 911, 913, 3, 98, 49, 0, 912, 911, 1, 0, 0, 0, 912, 913, 1, 0, 0, 0, + 913, 914, 1, 0, 0, 0, 914, 929, 5, 8, 0, 0, 915, 916, 3, 14, 7, 0, 916, + 917, 5, 15, 0, 0, 917, 919, 1, 0, 0, 0, 918, 915, 1, 0, 0, 0, 918, 919, + 1, 0, 0, 0, 919, 920, 1, 0, 0, 0, 920, 921, 5, 130, 0, 0, 921, 922, 5, + 12, 0, 0, 922, 923, 5, 130, 0, 0, 923, 925, 5, 7, 0, 0, 924, 926, 3, 98, + 49, 0, 925, 924, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, + 927, 929, 5, 8, 0, 0, 928, 908, 1, 0, 0, 0, 928, 909, 1, 0, 0, 0, 928, + 918, 1, 0, 0, 0, 929, 93, 1, 0, 0, 0, 930, 932, 3, 100, 50, 0, 931, 930, + 1, 0, 0, 0, 932, 935, 1, 0, 0, 0, 933, 931, 1, 0, 0, 0, 933, 934, 1, 0, + 0, 0, 934, 95, 1, 0, 0, 0, 935, 933, 1, 0, 0, 0, 936, 937, 6, 48, -1, 0, + 937, 939, 3, 2, 1, 0, 938, 940, 3, 10, 5, 0, 939, 938, 1, 0, 0, 0, 939, + 940, 1, 0, 0, 0, 940, 966, 1, 0, 0, 0, 941, 943, 3, 104, 52, 0, 942, 944, + 3, 10, 5, 0, 943, 942, 1, 0, 0, 0, 943, 944, 1, 0, 0, 0, 944, 966, 1, 0, + 0, 0, 945, 947, 3, 12, 6, 0, 946, 948, 3, 10, 5, 0, 947, 946, 1, 0, 0, + 0, 947, 948, 1, 0, 0, 0, 948, 966, 1, 0, 0, 0, 949, 951, 5, 3, 0, 0, 950, + 952, 3, 98, 49, 0, 951, 950, 1, 0, 0, 0, 951, 952, 1, 0, 0, 0, 952, 953, + 1, 0, 0, 0, 953, 955, 5, 4, 0, 0, 954, 956, 3, 10, 5, 0, 955, 954, 1, 0, + 0, 0, 955, 956, 1, 0, 0, 0, 956, 966, 1, 0, 0, 0, 957, 958, 5, 7, 0, 0, + 958, 959, 3, 96, 48, 0, 959, 961, 5, 8, 0, 0, 960, 962, 3, 10, 5, 0, 961, + 960, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 966, 1, 0, 0, 0, 963, 964, + 7, 12, 0, 0, 964, 966, 3, 96, 48, 4, 965, 936, 1, 0, 0, 0, 965, 941, 1, + 0, 0, 0, 965, 945, 1, 0, 0, 0, 965, 949, 1, 0, 0, 0, 965, 957, 1, 0, 0, + 0, 965, 963, 1, 0, 0, 0, 966, 994, 1, 0, 0, 0, 967, 968, 10, 5, 0, 0, 968, + 969, 7, 10, 0, 0, 969, 993, 3, 96, 48, 6, 970, 971, 10, 3, 0, 0, 971, 972, + 5, 13, 0, 0, 972, 993, 3, 96, 48, 4, 973, 974, 10, 2, 0, 0, 974, 975, 7, + 11, 0, 0, 975, 993, 3, 96, 48, 3, 976, 977, 10, 1, 0, 0, 977, 978, 7, 0, + 0, 0, 978, 993, 3, 96, 48, 2, 979, 980, 10, 8, 0, 0, 980, 981, 5, 3, 0, + 0, 981, 982, 3, 96, 48, 0, 982, 984, 5, 4, 0, 0, 983, 985, 3, 10, 5, 0, + 984, 983, 1, 0, 0, 0, 984, 985, 1, 0, 0, 0, 985, 993, 1, 0, 0, 0, 986, + 987, 10, 6, 0, 0, 987, 988, 5, 12, 0, 0, 988, 990, 5, 130, 0, 0, 989, 991, + 3, 10, 5, 0, 990, 989, 1, 0, 0, 0, 990, 991, 1, 0, 0, 0, 991, 993, 1, 0, + 0, 0, 992, 967, 1, 0, 0, 0, 992, 970, 1, 0, 0, 0, 992, 973, 1, 0, 0, 0, + 992, 976, 1, 0, 0, 0, 992, 979, 1, 0, 0, 0, 992, 986, 1, 0, 0, 0, 993, + 996, 1, 0, 0, 0, 994, 992, 1, 0, 0, 0, 994, 995, 1, 0, 0, 0, 995, 97, 1, + 0, 0, 0, 996, 994, 1, 0, 0, 0, 997, 1002, 3, 96, 48, 0, 998, 999, 5, 9, + 0, 0, 999, 1001, 3, 96, 48, 0, 1000, 998, 1, 0, 0, 0, 1001, 1004, 1, 0, + 0, 0, 1002, 1000, 1, 0, 0, 0, 1002, 1003, 1, 0, 0, 0, 1003, 99, 1, 0, 0, + 0, 1004, 1002, 1, 0, 0, 0, 1005, 1006, 5, 131, 0, 0, 1006, 1007, 3, 8, + 4, 0, 1007, 1008, 5, 6, 0, 0, 1008, 1087, 1, 0, 0, 0, 1009, 1014, 3, 102, + 51, 0, 1010, 1011, 5, 9, 0, 0, 1011, 1013, 3, 102, 51, 0, 1012, 1010, 1, + 0, 0, 0, 1013, 1016, 1, 0, 0, 0, 1014, 1012, 1, 0, 0, 0, 1014, 1015, 1, + 0, 0, 0, 1015, 1017, 1, 0, 0, 0, 1016, 1014, 1, 0, 0, 0, 1017, 1018, 5, + 30, 0, 0, 1018, 1020, 1, 0, 0, 0, 1019, 1009, 1, 0, 0, 0, 1019, 1020, 1, + 0, 0, 0, 1020, 1021, 1, 0, 0, 0, 1021, 1022, 3, 104, 52, 0, 1022, 1023, + 5, 6, 0, 0, 1023, 1087, 1, 0, 0, 0, 1024, 1026, 5, 131, 0, 0, 1025, 1027, + 3, 8, 4, 0, 1026, 1025, 1, 0, 0, 0, 1026, 1027, 1, 0, 0, 0, 1027, 1028, + 1, 0, 0, 0, 1028, 1029, 5, 30, 0, 0, 1029, 1030, 3, 96, 48, 0, 1030, 1031, + 5, 6, 0, 0, 1031, 1087, 1, 0, 0, 0, 1032, 1033, 5, 111, 0, 0, 1033, 1034, + 5, 131, 0, 0, 1034, 1038, 5, 66, 0, 0, 1035, 1039, 3, 108, 54, 0, 1036, + 1039, 3, 12, 6, 0, 1037, 1039, 3, 54, 27, 0, 1038, 1035, 1, 0, 0, 0, 1038, + 1036, 1, 0, 0, 0, 1038, 1037, 1, 0, 0, 0, 1039, 1040, 1, 0, 0, 0, 1040, + 1044, 5, 1, 0, 0, 1041, 1043, 3, 100, 50, 0, 1042, 1041, 1, 0, 0, 0, 1043, + 1046, 1, 0, 0, 0, 1044, 1042, 1, 0, 0, 0, 1044, 1045, 1, 0, 0, 0, 1045, + 1047, 1, 0, 0, 0, 1046, 1044, 1, 0, 0, 0, 1047, 1048, 5, 2, 0, 0, 1048, + 1087, 1, 0, 0, 0, 1049, 1050, 5, 112, 0, 0, 1050, 1055, 3, 106, 53, 0, + 1051, 1052, 5, 113, 0, 0, 1052, 1054, 3, 106, 53, 0, 1053, 1051, 1, 0, + 0, 0, 1054, 1057, 1, 0, 0, 0, 1055, 1053, 1, 0, 0, 0, 1055, 1056, 1, 0, + 0, 0, 1056, 1067, 1, 0, 0, 0, 1057, 1055, 1, 0, 0, 0, 1058, 1059, 5, 114, + 0, 0, 1059, 1063, 5, 1, 0, 0, 1060, 1062, 3, 100, 50, 0, 1061, 1060, 1, + 0, 0, 0, 1062, 1065, 1, 0, 0, 0, 1063, 1061, 1, 0, 0, 0, 1063, 1064, 1, + 0, 0, 0, 1064, 1066, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1066, 1068, 5, + 2, 0, 0, 1067, 1058, 1, 0, 0, 0, 1067, 1068, 1, 0, 0, 0, 1068, 1087, 1, + 0, 0, 0, 1069, 1070, 3, 54, 27, 0, 1070, 1071, 5, 6, 0, 0, 1071, 1087, + 1, 0, 0, 0, 1072, 1073, 5, 115, 0, 0, 1073, 1087, 5, 6, 0, 0, 1074, 1077, + 5, 116, 0, 0, 1075, 1078, 3, 98, 49, 0, 1076, 1078, 3, 54, 27, 0, 1077, + 1075, 1, 0, 0, 0, 1077, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, + 1080, 5, 6, 0, 0, 1080, 1087, 1, 0, 0, 0, 1081, 1082, 5, 116, 0, 0, 1082, + 1083, 5, 117, 0, 0, 1083, 1084, 3, 98, 49, 0, 1084, 1085, 5, 6, 0, 0, 1085, + 1087, 1, 0, 0, 0, 1086, 1005, 1, 0, 0, 0, 1086, 1019, 1, 0, 0, 0, 1086, + 1024, 1, 0, 0, 0, 1086, 1032, 1, 0, 0, 0, 1086, 1049, 1, 0, 0, 0, 1086, + 1069, 1, 0, 0, 0, 1086, 1072, 1, 0, 0, 0, 1086, 1074, 1, 0, 0, 0, 1086, + 1081, 1, 0, 0, 0, 1087, 101, 1, 0, 0, 0, 1088, 1089, 7, 13, 0, 0, 1089, + 103, 1, 0, 0, 0, 1090, 1091, 5, 130, 0, 0, 1091, 1093, 5, 7, 0, 0, 1092, + 1094, 3, 98, 49, 0, 1093, 1092, 1, 0, 0, 0, 1093, 1094, 1, 0, 0, 0, 1094, + 1095, 1, 0, 0, 0, 1095, 1109, 5, 8, 0, 0, 1096, 1097, 5, 130, 0, 0, 1097, + 1098, 5, 3, 0, 0, 1098, 1099, 3, 96, 48, 0, 1099, 1100, 5, 9, 0, 0, 1100, + 1101, 3, 96, 48, 0, 1101, 1102, 5, 4, 0, 0, 1102, 1104, 5, 7, 0, 0, 1103, + 1105, 3, 98, 49, 0, 1104, 1103, 1, 0, 0, 0, 1104, 1105, 1, 0, 0, 0, 1105, + 1106, 1, 0, 0, 0, 1106, 1107, 5, 8, 0, 0, 1107, 1109, 1, 0, 0, 0, 1108, + 1090, 1, 0, 0, 0, 1108, 1096, 1, 0, 0, 0, 1109, 105, 1, 0, 0, 0, 1110, + 1111, 3, 96, 48, 0, 1111, 1115, 5, 1, 0, 0, 1112, 1114, 3, 100, 50, 0, + 1113, 1112, 1, 0, 0, 0, 1114, 1117, 1, 0, 0, 0, 1115, 1113, 1, 0, 0, 0, + 1115, 1116, 1, 0, 0, 0, 1116, 1118, 1, 0, 0, 0, 1117, 1115, 1, 0, 0, 0, + 1118, 1119, 5, 2, 0, 0, 1119, 107, 1, 0, 0, 0, 1120, 1121, 3, 96, 48, 0, + 1121, 1122, 5, 31, 0, 0, 1122, 1123, 3, 96, 48, 0, 1123, 109, 1, 0, 0, + 0, 154, 114, 120, 124, 132, 138, 145, 154, 158, 170, 179, 181, 195, 198, + 218, 223, 237, 241, 251, 263, 276, 282, 287, 289, 292, 297, 303, 308, 311, + 318, 328, 339, 365, 370, 372, 380, 387, 394, 400, 409, 416, 422, 425, 437, + 441, 445, 455, 466, 469, 475, 484, 487, 501, 511, 514, 518, 522, 526, 530, + 534, 538, 542, 549, 557, 560, 564, 571, 573, 577, 580, 586, 589, 593, 596, + 598, 608, 611, 616, 619, 625, 633, 641, 644, 648, 659, 665, 678, 682, 691, + 693, 704, 709, 711, 718, 722, 727, 731, 735, 740, 744, 750, 756, 761, 765, + 770, 773, 779, 781, 788, 794, 824, 830, 834, 840, 847, 855, 857, 859, 872, + 878, 882, 894, 898, 905, 912, 918, 925, 928, 933, 939, 943, 947, 951, 955, + 961, 965, 984, 990, 992, 994, 1002, 1014, 1019, 1026, 1038, 1044, 1055, + 1063, 1067, 1077, 1086, 1093, 1104, 1108, 1115, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// KuneiformParserInit initializes any static state used to implement KuneiformParser. By default the +// static state used to implement the parser is lazily initialized during the first call to +// NewKuneiformParser(). You can call this function if you wish to initialize the static state ahead +// of time. +func KuneiformParserInit() { + staticData := &KuneiformParserParserStaticData + staticData.once.Do(kuneiformparserParserInit) +} + +// NewKuneiformParser produces a new parser instance for the optional input antlr.TokenStream. +func NewKuneiformParser(input antlr.TokenStream) *KuneiformParser { + KuneiformParserInit() + this := new(KuneiformParser) + this.BaseParser = antlr.NewBaseParser(input) + staticData := &KuneiformParserParserStaticData + this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) + this.RuleNames = staticData.RuleNames + this.LiteralNames = staticData.LiteralNames + this.SymbolicNames = staticData.SymbolicNames + this.GrammarFileName = "KuneiformParser.g4" + + return this +} + +// KuneiformParser tokens. +const ( + KuneiformParserEOF = antlr.TokenEOF + KuneiformParserLBRACE = 1 + KuneiformParserRBRACE = 2 + KuneiformParserLBRACKET = 3 + KuneiformParserRBRACKET = 4 + KuneiformParserCOL = 5 + KuneiformParserSCOL = 6 + KuneiformParserLPAREN = 7 + KuneiformParserRPAREN = 8 + KuneiformParserCOMMA = 9 + KuneiformParserAT = 10 + KuneiformParserEXCL = 11 + KuneiformParserPERIOD = 12 + KuneiformParserCONCAT = 13 + KuneiformParserSTAR = 14 + KuneiformParserEQUALS = 15 + KuneiformParserEQUATE = 16 + KuneiformParserHASH = 17 + KuneiformParserDOLLAR = 18 + KuneiformParserMOD = 19 + KuneiformParserPLUS = 20 + KuneiformParserMINUS = 21 + KuneiformParserDIV = 22 + KuneiformParserNEQ = 23 + KuneiformParserLT = 24 + KuneiformParserLTE = 25 + KuneiformParserGT = 26 + KuneiformParserGTE = 27 + KuneiformParserTYPE_CAST = 28 + KuneiformParserUNDERSCORE = 29 + KuneiformParserASSIGN = 30 + KuneiformParserRANGE = 31 + KuneiformParserDOUBLE_QUOTE = 32 + KuneiformParserDATABASE = 33 + KuneiformParserUSE = 34 + KuneiformParserTABLE = 35 + KuneiformParserACTION = 36 + KuneiformParserPROCEDURE = 37 + KuneiformParserPUBLIC = 38 + KuneiformParserPRIVATE = 39 + KuneiformParserVIEW = 40 + KuneiformParserOWNER = 41 + KuneiformParserMIN = 42 + KuneiformParserMAX = 43 + KuneiformParserMINLEN = 44 + KuneiformParserMAXLEN = 45 + KuneiformParserUNIQUE = 46 + KuneiformParserFOREIGN = 47 + KuneiformParserPRIMARY = 48 + KuneiformParserKEY = 49 + KuneiformParserON = 50 + KuneiformParserDO = 51 + KuneiformParserCASCADE = 52 + KuneiformParserRESTRICT = 53 + KuneiformParserSET = 54 + KuneiformParserDEFAULT = 55 + KuneiformParserNULL = 56 + KuneiformParserDELETE = 57 + KuneiformParserUPDATE = 58 + KuneiformParserREFERENCES = 59 + KuneiformParserREF = 60 + KuneiformParserNOT = 61 + KuneiformParserINDEX = 62 + KuneiformParserAND = 63 + KuneiformParserOR = 64 + KuneiformParserLIKE = 65 + KuneiformParserIN = 66 + KuneiformParserBETWEEN = 67 + KuneiformParserIS = 68 + KuneiformParserEXISTS = 69 + KuneiformParserALL = 70 + KuneiformParserANY = 71 + KuneiformParserJOIN = 72 + KuneiformParserLEFT = 73 + KuneiformParserRIGHT = 74 + KuneiformParserINNER = 75 + KuneiformParserAS = 76 + KuneiformParserASC = 77 + KuneiformParserDESC = 78 + KuneiformParserLIMIT = 79 + KuneiformParserOFFSET = 80 + KuneiformParserORDER = 81 + KuneiformParserBY = 82 + KuneiformParserGROUP = 83 + KuneiformParserHAVING = 84 + KuneiformParserRETURNS = 85 + KuneiformParserNO = 86 + KuneiformParserNOTNULL = 87 + KuneiformParserWITH = 88 + KuneiformParserCASE = 89 + KuneiformParserWHEN = 90 + KuneiformParserTHEN = 91 + KuneiformParserEND = 92 + KuneiformParserDISTINCT = 93 + KuneiformParserFROM = 94 + KuneiformParserWHERE = 95 + KuneiformParserCOLLATE = 96 + KuneiformParserSELECT = 97 + KuneiformParserINSERT = 98 + KuneiformParserVALUES = 99 + KuneiformParserFULL = 100 + KuneiformParserUNION = 101 + KuneiformParserINTERSECT = 102 + KuneiformParserEXCEPT = 103 + KuneiformParserNULLS = 104 + KuneiformParserFIRST = 105 + KuneiformParserLAST = 106 + KuneiformParserRETURNING = 107 + KuneiformParserINTO = 108 + KuneiformParserCONFLICT = 109 + KuneiformParserNOTHING = 110 + KuneiformParserFOR = 111 + KuneiformParserIF = 112 + KuneiformParserELSEIF = 113 + KuneiformParserELSE = 114 + KuneiformParserBREAK = 115 + KuneiformParserRETURN = 116 + KuneiformParserNEXT = 117 + KuneiformParserSTRING_ = 118 + KuneiformParserTRUE = 119 + KuneiformParserFALSE = 120 + KuneiformParserDIGITS_ = 121 + KuneiformParserBINARY_ = 122 + KuneiformParserLEGACY_PRIMARY_KEY = 123 + KuneiformParserLEGACY_FOREIGN_KEY = 124 + KuneiformParserLEGACY_ON_UPDATE = 125 + KuneiformParserLEGACY_ON_DELETE = 126 + KuneiformParserLEGACY_SET_DEFAULT = 127 + KuneiformParserLEGACY_SET_NULL = 128 + KuneiformParserLEGACY_NO_ACTION = 129 + KuneiformParserIDENTIFIER = 130 + KuneiformParserVARIABLE = 131 + KuneiformParserCONTEXTUAL_VARIABLE = 132 + KuneiformParserHASH_IDENTIFIER = 133 + KuneiformParserWS = 134 + KuneiformParserBLOCK_COMMENT = 135 + KuneiformParserLINE_COMMENT = 136 +) + +// KuneiformParser rules. +const ( + KuneiformParserRULE_entry = 0 + KuneiformParserRULE_literal = 1 + KuneiformParserRULE_identifier = 2 + KuneiformParserRULE_identifier_list = 3 + KuneiformParserRULE_type = 4 + KuneiformParserRULE_type_cast = 5 + KuneiformParserRULE_variable = 6 + KuneiformParserRULE_variable_list = 7 + KuneiformParserRULE_schema = 8 + KuneiformParserRULE_annotation = 9 + KuneiformParserRULE_database_declaration = 10 + KuneiformParserRULE_use_declaration = 11 + KuneiformParserRULE_table_declaration = 12 + KuneiformParserRULE_column_def = 13 + KuneiformParserRULE_index_def = 14 + KuneiformParserRULE_foreign_key_def = 15 + KuneiformParserRULE_foreign_key_action = 16 + KuneiformParserRULE_type_list = 17 + KuneiformParserRULE_named_type_list = 18 + KuneiformParserRULE_typed_variable_list = 19 + KuneiformParserRULE_constraint = 20 + KuneiformParserRULE_access_modifier = 21 + KuneiformParserRULE_action_declaration = 22 + KuneiformParserRULE_procedure_declaration = 23 + KuneiformParserRULE_foreign_procedure_declaration = 24 + KuneiformParserRULE_procedure_return = 25 + KuneiformParserRULE_sql = 26 + KuneiformParserRULE_sql_statement = 27 + KuneiformParserRULE_common_table_expression = 28 + KuneiformParserRULE_select_statement = 29 + KuneiformParserRULE_compound_operator = 30 + KuneiformParserRULE_ordering_term = 31 + KuneiformParserRULE_select_core = 32 + KuneiformParserRULE_relation = 33 + KuneiformParserRULE_join = 34 + KuneiformParserRULE_result_column = 35 + KuneiformParserRULE_update_statement = 36 + KuneiformParserRULE_update_set_clause = 37 + KuneiformParserRULE_insert_statement = 38 + KuneiformParserRULE_upsert_clause = 39 + KuneiformParserRULE_delete_statement = 40 + KuneiformParserRULE_sql_expr = 41 + KuneiformParserRULE_when_then_clause = 42 + KuneiformParserRULE_sql_expr_list = 43 + KuneiformParserRULE_sql_function_call = 44 + KuneiformParserRULE_action_block = 45 + KuneiformParserRULE_action_statement = 46 + KuneiformParserRULE_procedure_block = 47 + KuneiformParserRULE_procedure_expr = 48 + KuneiformParserRULE_procedure_expr_list = 49 + KuneiformParserRULE_proc_statement = 50 + KuneiformParserRULE_variable_or_underscore = 51 + KuneiformParserRULE_procedure_function_call = 52 + KuneiformParserRULE_if_then_block = 53 + KuneiformParserRULE_range = 54 +) + +// IEntryContext is an interface to support dynamic dispatch. +type IEntryContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + EOF() antlr.TerminalNode + Schema() ISchemaContext + Sql() ISqlContext + Action_block() IAction_blockContext + Procedure_block() IProcedure_blockContext + + // IsEntryContext differentiates from other interfaces. + IsEntryContext() +} + +type EntryContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyEntryContext() *EntryContext { + var p = new(EntryContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_entry + return p +} + +func InitEmptyEntryContext(p *EntryContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_entry +} + +func (*EntryContext) IsEntryContext() {} + +func NewEntryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *EntryContext { + var p = new(EntryContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_entry + + return p +} + +func (s *EntryContext) GetParser() antlr.Parser { return s.parser } + +func (s *EntryContext) EOF() antlr.TerminalNode { + return s.GetToken(KuneiformParserEOF, 0) +} + +func (s *EntryContext) Schema() ISchemaContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISchemaContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISchemaContext) +} + +func (s *EntryContext) Sql() ISqlContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISqlContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISqlContext) +} + +func (s *EntryContext) Action_block() IAction_blockContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAction_blockContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IAction_blockContext) +} + +func (s *EntryContext) Procedure_block() IProcedure_blockContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_blockContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_blockContext) +} + +func (s *EntryContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *EntryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *EntryContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitEntry(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Entry() (localctx IEntryContext) { + localctx = NewEntryContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, KuneiformParserRULE_entry) + p.EnterOuterAlt(localctx, 1) + p.SetState(114) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext()) { + case 1: + { + p.SetState(110) + p.Schema() + } + + case 2: + { + p.SetState(111) + p.Sql() + } + + case 3: + { + p.SetState(112) + p.Action_block() + } + + case 4: + { + p.SetState(113) + p.Procedure_block() + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + { + p.SetState(116) + p.Match(KuneiformParserEOF) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ILiteralContext is an interface to support dynamic dispatch. +type ILiteralContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsLiteralContext differentiates from other interfaces. + IsLiteralContext() +} + +type LiteralContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyLiteralContext() *LiteralContext { + var p = new(LiteralContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_literal + return p +} + +func InitEmptyLiteralContext(p *LiteralContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_literal +} + +func (*LiteralContext) IsLiteralContext() {} + +func NewLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LiteralContext { + var p = new(LiteralContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_literal + + return p +} + +func (s *LiteralContext) GetParser() antlr.Parser { return s.parser } + +func (s *LiteralContext) CopyAll(ctx *LiteralContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *LiteralContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *LiteralContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type String_literalContext struct { + LiteralContext +} + +func NewString_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *String_literalContext { + var p = new(String_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *String_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *String_literalContext) STRING_() antlr.TerminalNode { + return s.GetToken(KuneiformParserSTRING_, 0) +} + +func (s *String_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitString_literal(s) + + default: + return t.VisitChildren(s) + } +} + +type Decimal_literalContext struct { + LiteralContext +} + +func NewDecimal_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Decimal_literalContext { + var p = new(Decimal_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *Decimal_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Decimal_literalContext) AllDIGITS_() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserDIGITS_) +} + +func (s *Decimal_literalContext) DIGITS_(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserDIGITS_, i) +} + +func (s *Decimal_literalContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Decimal_literalContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Decimal_literalContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Decimal_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitDecimal_literal(s) + + default: + return t.VisitChildren(s) + } +} + +type Null_literalContext struct { + LiteralContext +} + +func NewNull_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Null_literalContext { + var p = new(Null_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *Null_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Null_literalContext) NULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserNULL, 0) +} + +func (s *Null_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitNull_literal(s) + + default: + return t.VisitChildren(s) + } +} + +type Boolean_literalContext struct { + LiteralContext +} + +func NewBoolean_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Boolean_literalContext { + var p = new(Boolean_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *Boolean_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Boolean_literalContext) TRUE() antlr.TerminalNode { + return s.GetToken(KuneiformParserTRUE, 0) +} + +func (s *Boolean_literalContext) FALSE() antlr.TerminalNode { + return s.GetToken(KuneiformParserFALSE, 0) +} + +func (s *Boolean_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitBoolean_literal(s) + + default: + return t.VisitChildren(s) + } +} + +type Integer_literalContext struct { + LiteralContext +} + +func NewInteger_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Integer_literalContext { + var p = new(Integer_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *Integer_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Integer_literalContext) DIGITS_() antlr.TerminalNode { + return s.GetToken(KuneiformParserDIGITS_, 0) +} + +func (s *Integer_literalContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Integer_literalContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Integer_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitInteger_literal(s) + + default: + return t.VisitChildren(s) + } +} + +type Binary_literalContext struct { + LiteralContext +} + +func NewBinary_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Binary_literalContext { + var p = new(Binary_literalContext) + + InitEmptyLiteralContext(&p.LiteralContext) + p.parser = parser + p.CopyAll(ctx.(*LiteralContext)) + + return p +} + +func (s *Binary_literalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Binary_literalContext) BINARY_() antlr.TerminalNode { + return s.GetToken(KuneiformParserBINARY_, 0) +} + +func (s *Binary_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitBinary_literal(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Literal() (localctx ILiteralContext) { + localctx = NewLiteralContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 2, KuneiformParserRULE_literal) + var _la int + + p.SetState(132) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) { + case 1: + localctx = NewString_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(118) + p.Match(KuneiformParserSTRING_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 2: + localctx = NewInteger_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + p.SetState(120) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserPLUS || _la == KuneiformParserMINUS { + { + p.SetState(119) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserPLUS || _la == KuneiformParserMINUS) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + + } + { + p.SetState(122) + p.Match(KuneiformParserDIGITS_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 3: + localctx = NewDecimal_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 3) + p.SetState(124) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserPLUS || _la == KuneiformParserMINUS { + { + p.SetState(123) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserPLUS || _la == KuneiformParserMINUS) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + + } + { + p.SetState(126) + p.Match(KuneiformParserDIGITS_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(127) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(128) + p.Match(KuneiformParserDIGITS_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 4: + localctx = NewBoolean_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 4) + { + p.SetState(129) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserTRUE || _la == KuneiformParserFALSE) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + + case 5: + localctx = NewNull_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 5) + { + p.SetState(130) + p.Match(KuneiformParserNULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 6: + localctx = NewBinary_literalContext(p, localctx) + p.EnterOuterAlt(localctx, 6) + { + p.SetState(131) + p.Match(KuneiformParserBINARY_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IIdentifierContext is an interface to support dynamic dispatch. +type IIdentifierContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllDOUBLE_QUOTE() []antlr.TerminalNode + DOUBLE_QUOTE(i int) antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + + // IsIdentifierContext differentiates from other interfaces. + IsIdentifierContext() +} + +type IdentifierContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyIdentifierContext() *IdentifierContext { + var p = new(IdentifierContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_identifier + return p +} + +func InitEmptyIdentifierContext(p *IdentifierContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_identifier +} + +func (*IdentifierContext) IsIdentifierContext() {} + +func NewIdentifierContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IdentifierContext { + var p = new(IdentifierContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_identifier + + return p +} + +func (s *IdentifierContext) GetParser() antlr.Parser { return s.parser } + +func (s *IdentifierContext) AllDOUBLE_QUOTE() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserDOUBLE_QUOTE) +} + +func (s *IdentifierContext) DOUBLE_QUOTE(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserDOUBLE_QUOTE, i) +} + +func (s *IdentifierContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *IdentifierContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *IdentifierContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *IdentifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIdentifier(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Identifier() (localctx IIdentifierContext) { + localctx = NewIdentifierContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 4, KuneiformParserRULE_identifier) + p.SetState(138) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserDOUBLE_QUOTE: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(134) + p.Match(KuneiformParserDOUBLE_QUOTE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(135) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(136) + p.Match(KuneiformParserDOUBLE_QUOTE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserIDENTIFIER: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(137) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IIdentifier_listContext is an interface to support dynamic dispatch. +type IIdentifier_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllIdentifier() []IIdentifierContext + Identifier(i int) IIdentifierContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsIdentifier_listContext differentiates from other interfaces. + IsIdentifier_listContext() +} + +type Identifier_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyIdentifier_listContext() *Identifier_listContext { + var p = new(Identifier_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_identifier_list + return p +} + +func InitEmptyIdentifier_listContext(p *Identifier_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_identifier_list +} + +func (*Identifier_listContext) IsIdentifier_listContext() {} + +func NewIdentifier_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Identifier_listContext { + var p = new(Identifier_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_identifier_list + + return p +} + +func (s *Identifier_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Identifier_listContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Identifier_listContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Identifier_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Identifier_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Identifier_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Identifier_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Identifier_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIdentifier_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Identifier_list() (localctx IIdentifier_listContext) { + localctx = NewIdentifier_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 6, KuneiformParserRULE_identifier_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(140) + p.Identifier() + } + p.SetState(145) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(141) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(142) + p.Identifier() + } + + p.SetState(147) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ITypeContext is an interface to support dynamic dispatch. +type ITypeContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + IDENTIFIER() antlr.TerminalNode + LPAREN() antlr.TerminalNode + AllDIGITS_() []antlr.TerminalNode + DIGITS_(i int) antlr.TerminalNode + COMMA() antlr.TerminalNode + RPAREN() antlr.TerminalNode + LBRACKET() antlr.TerminalNode + RBRACKET() antlr.TerminalNode + + // IsTypeContext differentiates from other interfaces. + IsTypeContext() +} + +type TypeContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyTypeContext() *TypeContext { + var p = new(TypeContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type + return p +} + +func InitEmptyTypeContext(p *TypeContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type +} + +func (*TypeContext) IsTypeContext() {} + +func NewTypeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeContext { + var p = new(TypeContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_type + + return p +} + +func (s *TypeContext) GetParser() antlr.Parser { return s.parser } + +func (s *TypeContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *TypeContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *TypeContext) AllDIGITS_() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserDIGITS_) +} + +func (s *TypeContext) DIGITS_(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserDIGITS_, i) +} + +func (s *TypeContext) COMMA() antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, 0) +} + +func (s *TypeContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *TypeContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *TypeContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *TypeContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TypeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *TypeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitType(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Type_() (localctx ITypeContext) { + localctx = NewTypeContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 8, KuneiformParserRULE_type) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(148) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(154) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 6, p.GetParserRuleContext()) == 1 { + { + p.SetState(149) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(150) + p.Match(KuneiformParserDIGITS_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(151) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(152) + p.Match(KuneiformParserDIGITS_) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(153) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } else if p.HasError() { // JIM + goto errorExit + } + p.SetState(158) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 7, p.GetParserRuleContext()) == 1 { + { + p.SetState(156) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(157) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } else if p.HasError() { // JIM + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IType_castContext is an interface to support dynamic dispatch. +type IType_castContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + TYPE_CAST() antlr.TerminalNode + Type_() ITypeContext + + // IsType_castContext differentiates from other interfaces. + IsType_castContext() +} + +type Type_castContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyType_castContext() *Type_castContext { + var p = new(Type_castContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type_cast + return p +} + +func InitEmptyType_castContext(p *Type_castContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type_cast +} + +func (*Type_castContext) IsType_castContext() {} + +func NewType_castContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_castContext { + var p = new(Type_castContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_type_cast + + return p +} + +func (s *Type_castContext) GetParser() antlr.Parser { return s.parser } + +func (s *Type_castContext) TYPE_CAST() antlr.TerminalNode { + return s.GetToken(KuneiformParserTYPE_CAST, 0) +} + +func (s *Type_castContext) Type_() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Type_castContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Type_castContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Type_castContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitType_cast(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Type_cast() (localctx IType_castContext) { + localctx = NewType_castContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 10, KuneiformParserRULE_type_cast) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(160) + p.Match(KuneiformParserTYPE_CAST) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(161) + p.Type_() + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IVariableContext is an interface to support dynamic dispatch. +type IVariableContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + VARIABLE() antlr.TerminalNode + CONTEXTUAL_VARIABLE() antlr.TerminalNode + + // IsVariableContext differentiates from other interfaces. + IsVariableContext() +} + +type VariableContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyVariableContext() *VariableContext { + var p = new(VariableContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable + return p +} + +func InitEmptyVariableContext(p *VariableContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable +} + +func (*VariableContext) IsVariableContext() {} + +func NewVariableContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableContext { + var p = new(VariableContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_variable + + return p +} + +func (s *VariableContext) GetParser() antlr.Parser { return s.parser } + +func (s *VariableContext) VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserVARIABLE, 0) +} + +func (s *VariableContext) CONTEXTUAL_VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserCONTEXTUAL_VARIABLE, 0) +} + +func (s *VariableContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *VariableContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *VariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitVariable(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Variable() (localctx IVariableContext) { + localctx = NewVariableContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 12, KuneiformParserRULE_variable) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(163) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserVARIABLE || _la == KuneiformParserCONTEXTUAL_VARIABLE) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IVariable_listContext is an interface to support dynamic dispatch. +type IVariable_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllVariable() []IVariableContext + Variable(i int) IVariableContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsVariable_listContext differentiates from other interfaces. + IsVariable_listContext() +} + +type Variable_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyVariable_listContext() *Variable_listContext { + var p = new(Variable_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable_list + return p +} + +func InitEmptyVariable_listContext(p *Variable_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable_list +} + +func (*Variable_listContext) IsVariable_listContext() {} + +func NewVariable_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Variable_listContext { + var p = new(Variable_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_variable_list + + return p +} + +func (s *Variable_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Variable_listContext) AllVariable() []IVariableContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IVariableContext); ok { + len++ + } + } + + tst := make([]IVariableContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IVariableContext); ok { + tst[i] = t.(IVariableContext) + i++ + } + } + + return tst +} + +func (s *Variable_listContext) Variable(i int) IVariableContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariableContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IVariableContext) +} + +func (s *Variable_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Variable_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Variable_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Variable_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Variable_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitVariable_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Variable_list() (localctx IVariable_listContext) { + localctx = NewVariable_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 14, KuneiformParserRULE_variable_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(165) + p.Variable() + } + p.SetState(170) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(166) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(167) + p.Variable() + } + + p.SetState(172) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISchemaContext is an interface to support dynamic dispatch. +type ISchemaContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Database_declaration() IDatabase_declarationContext + AllUse_declaration() []IUse_declarationContext + Use_declaration(i int) IUse_declarationContext + AllTable_declaration() []ITable_declarationContext + Table_declaration(i int) ITable_declarationContext + AllAction_declaration() []IAction_declarationContext + Action_declaration(i int) IAction_declarationContext + AllProcedure_declaration() []IProcedure_declarationContext + Procedure_declaration(i int) IProcedure_declarationContext + AllForeign_procedure_declaration() []IForeign_procedure_declarationContext + Foreign_procedure_declaration(i int) IForeign_procedure_declarationContext + + // IsSchemaContext differentiates from other interfaces. + IsSchemaContext() +} + +type SchemaContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySchemaContext() *SchemaContext { + var p = new(SchemaContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_schema + return p +} + +func InitEmptySchemaContext(p *SchemaContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_schema +} + +func (*SchemaContext) IsSchemaContext() {} + +func NewSchemaContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SchemaContext { + var p = new(SchemaContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_schema + + return p +} + +func (s *SchemaContext) GetParser() antlr.Parser { return s.parser } + +func (s *SchemaContext) Database_declaration() IDatabase_declarationContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IDatabase_declarationContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IDatabase_declarationContext) +} + +func (s *SchemaContext) AllUse_declaration() []IUse_declarationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IUse_declarationContext); ok { + len++ + } + } + + tst := make([]IUse_declarationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IUse_declarationContext); ok { + tst[i] = t.(IUse_declarationContext) + i++ + } + } + + return tst +} + +func (s *SchemaContext) Use_declaration(i int) IUse_declarationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUse_declarationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IUse_declarationContext) +} + +func (s *SchemaContext) AllTable_declaration() []ITable_declarationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ITable_declarationContext); ok { + len++ + } + } + + tst := make([]ITable_declarationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ITable_declarationContext); ok { + tst[i] = t.(ITable_declarationContext) + i++ + } + } + + return tst +} + +func (s *SchemaContext) Table_declaration(i int) ITable_declarationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITable_declarationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ITable_declarationContext) +} + +func (s *SchemaContext) AllAction_declaration() []IAction_declarationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAction_declarationContext); ok { + len++ + } + } + + tst := make([]IAction_declarationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAction_declarationContext); ok { + tst[i] = t.(IAction_declarationContext) + i++ + } + } + + return tst +} + +func (s *SchemaContext) Action_declaration(i int) IAction_declarationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAction_declarationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAction_declarationContext) +} + +func (s *SchemaContext) AllProcedure_declaration() []IProcedure_declarationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_declarationContext); ok { + len++ + } + } + + tst := make([]IProcedure_declarationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_declarationContext); ok { + tst[i] = t.(IProcedure_declarationContext) + i++ + } + } + + return tst +} + +func (s *SchemaContext) Procedure_declaration(i int) IProcedure_declarationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_declarationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_declarationContext) +} + +func (s *SchemaContext) AllForeign_procedure_declaration() []IForeign_procedure_declarationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IForeign_procedure_declarationContext); ok { + len++ + } + } + + tst := make([]IForeign_procedure_declarationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IForeign_procedure_declarationContext); ok { + tst[i] = t.(IForeign_procedure_declarationContext) + i++ + } + } + + return tst +} + +func (s *SchemaContext) Foreign_procedure_declaration(i int) IForeign_procedure_declarationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IForeign_procedure_declarationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IForeign_procedure_declarationContext) +} + +func (s *SchemaContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *SchemaContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *SchemaContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSchema(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Schema() (localctx ISchemaContext) { + localctx = NewSchemaContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 16, KuneiformParserRULE_schema) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(173) + p.Database_declaration() + } + p.SetState(181) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&140995186393088) != 0) || _la == KuneiformParserCONTEXTUAL_VARIABLE { + p.SetState(179) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) { + case 1: + { + p.SetState(174) + p.Use_declaration() + } + + case 2: + { + p.SetState(175) + p.Table_declaration() + } + + case 3: + { + p.SetState(176) + p.Action_declaration() + } + + case 4: + { + p.SetState(177) + p.Procedure_declaration() + } + + case 5: + { + p.SetState(178) + p.Foreign_procedure_declaration() + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + + p.SetState(183) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IAnnotationContext is an interface to support dynamic dispatch. +type IAnnotationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + CONTEXTUAL_VARIABLE() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + AllIDENTIFIER() []antlr.TerminalNode + IDENTIFIER(i int) antlr.TerminalNode + AllEQUALS() []antlr.TerminalNode + EQUALS(i int) antlr.TerminalNode + AllLiteral() []ILiteralContext + Literal(i int) ILiteralContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsAnnotationContext differentiates from other interfaces. + IsAnnotationContext() +} + +type AnnotationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyAnnotationContext() *AnnotationContext { + var p = new(AnnotationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_annotation + return p +} + +func InitEmptyAnnotationContext(p *AnnotationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_annotation +} + +func (*AnnotationContext) IsAnnotationContext() {} + +func NewAnnotationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AnnotationContext { + var p = new(AnnotationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_annotation + + return p +} + +func (s *AnnotationContext) GetParser() antlr.Parser { return s.parser } + +func (s *AnnotationContext) CONTEXTUAL_VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserCONTEXTUAL_VARIABLE, 0) +} + +func (s *AnnotationContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *AnnotationContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *AnnotationContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserIDENTIFIER) +} + +func (s *AnnotationContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, i) +} + +func (s *AnnotationContext) AllEQUALS() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserEQUALS) +} + +func (s *AnnotationContext) EQUALS(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUALS, i) +} + +func (s *AnnotationContext) AllLiteral() []ILiteralContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ILiteralContext); ok { + len++ + } + } + + tst := make([]ILiteralContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ILiteralContext); ok { + tst[i] = t.(ILiteralContext) + i++ + } + } + + return tst +} + +func (s *AnnotationContext) Literal(i int) ILiteralContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *AnnotationContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *AnnotationContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *AnnotationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *AnnotationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *AnnotationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitAnnotation(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Annotation() (localctx IAnnotationContext) { + localctx = NewAnnotationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 18, KuneiformParserRULE_annotation) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(184) + p.Match(KuneiformParserCONTEXTUAL_VARIABLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(185) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(198) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserIDENTIFIER { + { + p.SetState(186) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(187) + p.Match(KuneiformParserEQUALS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(188) + p.Literal() + } + p.SetState(195) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(189) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(190) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(191) + p.Match(KuneiformParserEQUALS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(192) + p.Literal() + } + + p.SetState(197) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + { + p.SetState(200) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IDatabase_declarationContext is an interface to support dynamic dispatch. +type IDatabase_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + DATABASE() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + SCOL() antlr.TerminalNode + + // IsDatabase_declarationContext differentiates from other interfaces. + IsDatabase_declarationContext() +} + +type Database_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyDatabase_declarationContext() *Database_declarationContext { + var p = new(Database_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_database_declaration + return p +} + +func InitEmptyDatabase_declarationContext(p *Database_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_database_declaration +} + +func (*Database_declarationContext) IsDatabase_declarationContext() {} + +func NewDatabase_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Database_declarationContext { + var p = new(Database_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_database_declaration + + return p +} + +func (s *Database_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Database_declarationContext) DATABASE() antlr.TerminalNode { + return s.GetToken(KuneiformParserDATABASE, 0) +} + +func (s *Database_declarationContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Database_declarationContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Database_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Database_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Database_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitDatabase_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Database_declaration() (localctx IDatabase_declarationContext) { + localctx = NewDatabase_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 20, KuneiformParserRULE_database_declaration) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(202) + p.Match(KuneiformParserDATABASE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(203) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(204) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IUse_declarationContext is an interface to support dynamic dispatch. +type IUse_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + USE() antlr.TerminalNode + AllIDENTIFIER() []antlr.TerminalNode + IDENTIFIER(i int) antlr.TerminalNode + AS() antlr.TerminalNode + SCOL() antlr.TerminalNode + LBRACE() antlr.TerminalNode + AllCOL() []antlr.TerminalNode + COL(i int) antlr.TerminalNode + AllLiteral() []ILiteralContext + Literal(i int) ILiteralContext + RBRACE() antlr.TerminalNode + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsUse_declarationContext differentiates from other interfaces. + IsUse_declarationContext() +} + +type Use_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyUse_declarationContext() *Use_declarationContext { + var p = new(Use_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_use_declaration + return p +} + +func InitEmptyUse_declarationContext(p *Use_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_use_declaration +} + +func (*Use_declarationContext) IsUse_declarationContext() {} + +func NewUse_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Use_declarationContext { + var p = new(Use_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_use_declaration + + return p +} + +func (s *Use_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Use_declarationContext) USE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUSE, 0) +} + +func (s *Use_declarationContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserIDENTIFIER) +} + +func (s *Use_declarationContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, i) +} + +func (s *Use_declarationContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Use_declarationContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Use_declarationContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Use_declarationContext) AllCOL() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOL) +} + +func (s *Use_declarationContext) COL(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOL, i) +} + +func (s *Use_declarationContext) AllLiteral() []ILiteralContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ILiteralContext); ok { + len++ + } + } + + tst := make([]ILiteralContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ILiteralContext); ok { + tst[i] = t.(ILiteralContext) + i++ + } + } + + return tst +} + +func (s *Use_declarationContext) Literal(i int) ILiteralContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Use_declarationContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Use_declarationContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Use_declarationContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Use_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Use_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Use_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUse_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Use_declaration() (localctx IUse_declarationContext) { + localctx = NewUse_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 22, KuneiformParserRULE_use_declaration) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(206) + p.Match(KuneiformParserUSE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(207) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(223) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserLBRACE { + { + p.SetState(208) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(209) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(210) + p.Match(KuneiformParserCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(211) + p.Literal() + } + p.SetState(218) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(212) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(213) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(214) + p.Match(KuneiformParserCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(215) + p.Literal() + } + + p.SetState(220) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(221) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(225) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(226) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(227) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ITable_declarationContext is an interface to support dynamic dispatch. +type ITable_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + TABLE() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + LBRACE() antlr.TerminalNode + AllColumn_def() []IColumn_defContext + Column_def(i int) IColumn_defContext + RBRACE() antlr.TerminalNode + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + AllIndex_def() []IIndex_defContext + Index_def(i int) IIndex_defContext + AllForeign_key_def() []IForeign_key_defContext + Foreign_key_def(i int) IForeign_key_defContext + + // IsTable_declarationContext differentiates from other interfaces. + IsTable_declarationContext() +} + +type Table_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyTable_declarationContext() *Table_declarationContext { + var p = new(Table_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_table_declaration + return p +} + +func InitEmptyTable_declarationContext(p *Table_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_table_declaration +} + +func (*Table_declarationContext) IsTable_declarationContext() {} + +func NewTable_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Table_declarationContext { + var p = new(Table_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_table_declaration + + return p +} + +func (s *Table_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Table_declarationContext) TABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserTABLE, 0) +} + +func (s *Table_declarationContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Table_declarationContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Table_declarationContext) AllColumn_def() []IColumn_defContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IColumn_defContext); ok { + len++ + } + } + + tst := make([]IColumn_defContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IColumn_defContext); ok { + tst[i] = t.(IColumn_defContext) + i++ + } + } + + return tst +} + +func (s *Table_declarationContext) Column_def(i int) IColumn_defContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IColumn_defContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IColumn_defContext) +} + +func (s *Table_declarationContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Table_declarationContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Table_declarationContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Table_declarationContext) AllIndex_def() []IIndex_defContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIndex_defContext); ok { + len++ + } + } + + tst := make([]IIndex_defContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIndex_defContext); ok { + tst[i] = t.(IIndex_defContext) + i++ + } + } + + return tst +} + +func (s *Table_declarationContext) Index_def(i int) IIndex_defContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIndex_defContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIndex_defContext) +} + +func (s *Table_declarationContext) AllForeign_key_def() []IForeign_key_defContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IForeign_key_defContext); ok { + len++ + } + } + + tst := make([]IForeign_key_defContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IForeign_key_defContext); ok { + tst[i] = t.(IForeign_key_defContext) + i++ + } + } + + return tst +} + +func (s *Table_declarationContext) Foreign_key_def(i int) IForeign_key_defContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IForeign_key_defContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IForeign_key_defContext) +} + +func (s *Table_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Table_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Table_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitTable_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Table_declaration() (localctx ITable_declarationContext) { + localctx = NewTable_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 24, KuneiformParserRULE_table_declaration) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(229) + p.Match(KuneiformParserTABLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(230) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(231) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(232) + p.Column_def() + } + p.SetState(241) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(233) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(237) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserIDENTIFIER: + { + p.SetState(234) + p.Column_def() + } + + case KuneiformParserHASH_IDENTIFIER: + { + p.SetState(235) + p.Index_def() + } + + case KuneiformParserFOREIGN, KuneiformParserLEGACY_FOREIGN_KEY: + { + p.SetState(236) + p.Foreign_key_def() + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + p.SetState(243) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(244) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IColumn_defContext is an interface to support dynamic dispatch. +type IColumn_defContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetName returns the name token. + GetName() antlr.Token + + // SetName sets the name token. + SetName(antlr.Token) + + // Getter signatures + Type_() ITypeContext + IDENTIFIER() antlr.TerminalNode + AllConstraint() []IConstraintContext + Constraint(i int) IConstraintContext + + // IsColumn_defContext differentiates from other interfaces. + IsColumn_defContext() +} + +type Column_defContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + name antlr.Token +} + +func NewEmptyColumn_defContext() *Column_defContext { + var p = new(Column_defContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_column_def + return p +} + +func InitEmptyColumn_defContext(p *Column_defContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_column_def +} + +func (*Column_defContext) IsColumn_defContext() {} + +func NewColumn_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_defContext { + var p = new(Column_defContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_column_def + + return p +} + +func (s *Column_defContext) GetParser() antlr.Parser { return s.parser } + +func (s *Column_defContext) GetName() antlr.Token { return s.name } + +func (s *Column_defContext) SetName(v antlr.Token) { s.name = v } + +func (s *Column_defContext) Type_() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Column_defContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Column_defContext) AllConstraint() []IConstraintContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IConstraintContext); ok { + len++ + } + } + + tst := make([]IConstraintContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IConstraintContext); ok { + tst[i] = t.(IConstraintContext) + i++ + } + } + + return tst +} + +func (s *Column_defContext) Constraint(i int) IConstraintContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IConstraintContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IConstraintContext) +} + +func (s *Column_defContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Column_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Column_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitColumn_def(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Column_def() (localctx IColumn_defContext) { + localctx = NewColumn_defContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 26, KuneiformParserRULE_column_def) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(246) + + var _m = p.Match(KuneiformParserIDENTIFIER) + + localctx.(*Column_defContext).name = _m + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(247) + p.Type_() + } + p.SetState(251) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2342289620651212800) != 0) || _la == KuneiformParserNOTNULL || _la == KuneiformParserLEGACY_PRIMARY_KEY { + { + p.SetState(248) + p.Constraint() + } + + p.SetState(253) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IIndex_defContext is an interface to support dynamic dispatch. +type IIndex_defContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetColumns returns the columns rule contexts. + GetColumns() IIdentifier_listContext + + // SetColumns sets the columns rule contexts. + SetColumns(IIdentifier_listContext) + + // Getter signatures + HASH_IDENTIFIER() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + UNIQUE() antlr.TerminalNode + INDEX() antlr.TerminalNode + PRIMARY() antlr.TerminalNode + Identifier_list() IIdentifier_listContext + + // IsIndex_defContext differentiates from other interfaces. + IsIndex_defContext() +} + +type Index_defContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + columns IIdentifier_listContext +} + +func NewEmptyIndex_defContext() *Index_defContext { + var p = new(Index_defContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_index_def + return p +} + +func InitEmptyIndex_defContext(p *Index_defContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_index_def +} + +func (*Index_defContext) IsIndex_defContext() {} + +func NewIndex_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Index_defContext { + var p = new(Index_defContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_index_def + + return p +} + +func (s *Index_defContext) GetParser() antlr.Parser { return s.parser } + +func (s *Index_defContext) GetColumns() IIdentifier_listContext { return s.columns } + +func (s *Index_defContext) SetColumns(v IIdentifier_listContext) { s.columns = v } + +func (s *Index_defContext) HASH_IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserHASH_IDENTIFIER, 0) +} + +func (s *Index_defContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Index_defContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Index_defContext) UNIQUE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUNIQUE, 0) +} + +func (s *Index_defContext) INDEX() antlr.TerminalNode { + return s.GetToken(KuneiformParserINDEX, 0) +} + +func (s *Index_defContext) PRIMARY() antlr.TerminalNode { + return s.GetToken(KuneiformParserPRIMARY, 0) +} + +func (s *Index_defContext) Identifier_list() IIdentifier_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifier_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifier_listContext) +} + +func (s *Index_defContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Index_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Index_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIndex_def(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Index_def() (localctx IIndex_defContext) { + localctx = NewIndex_defContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 28, KuneiformParserRULE_index_def) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(254) + p.Match(KuneiformParserHASH_IDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(255) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4612037862148276224) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(256) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(257) + + var _x = p.Identifier_list() + + localctx.(*Index_defContext).columns = _x + } + { + p.SetState(258) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IForeign_key_defContext is an interface to support dynamic dispatch. +type IForeign_key_defContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetParent_table returns the parent_table token. + GetParent_table() antlr.Token + + // SetParent_table sets the parent_table token. + SetParent_table(antlr.Token) + + // GetChild_keys returns the child_keys rule contexts. + GetChild_keys() IIdentifier_listContext + + // GetParent_keys returns the parent_keys rule contexts. + GetParent_keys() IIdentifier_listContext + + // SetChild_keys sets the child_keys rule contexts. + SetChild_keys(IIdentifier_listContext) + + // SetParent_keys sets the parent_keys rule contexts. + SetParent_keys(IIdentifier_listContext) + + // Getter signatures + AllLPAREN() []antlr.TerminalNode + LPAREN(i int) antlr.TerminalNode + AllRPAREN() []antlr.TerminalNode + RPAREN(i int) antlr.TerminalNode + AllIdentifier_list() []IIdentifier_listContext + Identifier_list(i int) IIdentifier_listContext + REFERENCES() antlr.TerminalNode + REF() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + FOREIGN() antlr.TerminalNode + KEY() antlr.TerminalNode + LEGACY_FOREIGN_KEY() antlr.TerminalNode + AllForeign_key_action() []IForeign_key_actionContext + Foreign_key_action(i int) IForeign_key_actionContext + + // IsForeign_key_defContext differentiates from other interfaces. + IsForeign_key_defContext() +} + +type Foreign_key_defContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + child_keys IIdentifier_listContext + parent_table antlr.Token + parent_keys IIdentifier_listContext +} + +func NewEmptyForeign_key_defContext() *Foreign_key_defContext { + var p = new(Foreign_key_defContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_key_def + return p +} + +func InitEmptyForeign_key_defContext(p *Foreign_key_defContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_key_def +} + +func (*Foreign_key_defContext) IsForeign_key_defContext() {} + +func NewForeign_key_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_key_defContext { + var p = new(Foreign_key_defContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_foreign_key_def + + return p +} + +func (s *Foreign_key_defContext) GetParser() antlr.Parser { return s.parser } + +func (s *Foreign_key_defContext) GetParent_table() antlr.Token { return s.parent_table } + +func (s *Foreign_key_defContext) SetParent_table(v antlr.Token) { s.parent_table = v } + +func (s *Foreign_key_defContext) GetChild_keys() IIdentifier_listContext { return s.child_keys } + +func (s *Foreign_key_defContext) GetParent_keys() IIdentifier_listContext { return s.parent_keys } + +func (s *Foreign_key_defContext) SetChild_keys(v IIdentifier_listContext) { s.child_keys = v } + +func (s *Foreign_key_defContext) SetParent_keys(v IIdentifier_listContext) { s.parent_keys = v } + +func (s *Foreign_key_defContext) AllLPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserLPAREN) +} + +func (s *Foreign_key_defContext) LPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, i) +} + +func (s *Foreign_key_defContext) AllRPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserRPAREN) +} + +func (s *Foreign_key_defContext) RPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, i) +} + +func (s *Foreign_key_defContext) AllIdentifier_list() []IIdentifier_listContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifier_listContext); ok { + len++ + } + } + + tst := make([]IIdentifier_listContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifier_listContext); ok { + tst[i] = t.(IIdentifier_listContext) + i++ + } + } + + return tst +} + +func (s *Foreign_key_defContext) Identifier_list(i int) IIdentifier_listContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifier_listContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifier_listContext) +} + +func (s *Foreign_key_defContext) REFERENCES() antlr.TerminalNode { + return s.GetToken(KuneiformParserREFERENCES, 0) +} + +func (s *Foreign_key_defContext) REF() antlr.TerminalNode { + return s.GetToken(KuneiformParserREF, 0) +} + +func (s *Foreign_key_defContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Foreign_key_defContext) FOREIGN() antlr.TerminalNode { + return s.GetToken(KuneiformParserFOREIGN, 0) +} + +func (s *Foreign_key_defContext) KEY() antlr.TerminalNode { + return s.GetToken(KuneiformParserKEY, 0) +} + +func (s *Foreign_key_defContext) LEGACY_FOREIGN_KEY() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_FOREIGN_KEY, 0) +} + +func (s *Foreign_key_defContext) AllForeign_key_action() []IForeign_key_actionContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IForeign_key_actionContext); ok { + len++ + } + } + + tst := make([]IForeign_key_actionContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IForeign_key_actionContext); ok { + tst[i] = t.(IForeign_key_actionContext) + i++ + } + } + + return tst +} + +func (s *Foreign_key_defContext) Foreign_key_action(i int) IForeign_key_actionContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IForeign_key_actionContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IForeign_key_actionContext) +} + +func (s *Foreign_key_defContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Foreign_key_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Foreign_key_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitForeign_key_def(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Foreign_key_def() (localctx IForeign_key_defContext) { + localctx = NewForeign_key_defContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 30, KuneiformParserRULE_foreign_key_def) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(263) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserFOREIGN: + { + p.SetState(260) + p.Match(KuneiformParserFOREIGN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(261) + p.Match(KuneiformParserKEY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_FOREIGN_KEY: + { + p.SetState(262) + p.Match(KuneiformParserLEGACY_FOREIGN_KEY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + { + p.SetState(265) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(266) + + var _x = p.Identifier_list() + + localctx.(*Foreign_key_defContext).child_keys = _x + } + { + p.SetState(267) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(268) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserREFERENCES || _la == KuneiformParserREF) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(269) + + var _m = p.Match(KuneiformParserIDENTIFIER) + + localctx.(*Foreign_key_defContext).parent_table = _m + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(270) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(271) + + var _x = p.Identifier_list() + + localctx.(*Foreign_key_defContext).parent_keys = _x + } + { + p.SetState(272) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(276) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserON || _la == KuneiformParserLEGACY_ON_UPDATE || _la == KuneiformParserLEGACY_ON_DELETE { + { + p.SetState(273) + p.Foreign_key_action() + } + + p.SetState(278) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IForeign_key_actionContext is an interface to support dynamic dispatch. +type IForeign_key_actionContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + CASCADE() antlr.TerminalNode + RESTRICT() antlr.TerminalNode + DO() antlr.TerminalNode + ON() antlr.TerminalNode + UPDATE() antlr.TerminalNode + LEGACY_ON_UPDATE() antlr.TerminalNode + DELETE() antlr.TerminalNode + LEGACY_ON_DELETE() antlr.TerminalNode + NO() antlr.TerminalNode + ACTION() antlr.TerminalNode + LEGACY_NO_ACTION() antlr.TerminalNode + SET() antlr.TerminalNode + NULL() antlr.TerminalNode + LEGACY_SET_NULL() antlr.TerminalNode + DEFAULT() antlr.TerminalNode + LEGACY_SET_DEFAULT() antlr.TerminalNode + + // IsForeign_key_actionContext differentiates from other interfaces. + IsForeign_key_actionContext() +} + +type Foreign_key_actionContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyForeign_key_actionContext() *Foreign_key_actionContext { + var p = new(Foreign_key_actionContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_key_action + return p +} + +func InitEmptyForeign_key_actionContext(p *Foreign_key_actionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_key_action +} + +func (*Foreign_key_actionContext) IsForeign_key_actionContext() {} + +func NewForeign_key_actionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_key_actionContext { + var p = new(Foreign_key_actionContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_foreign_key_action + + return p +} + +func (s *Foreign_key_actionContext) GetParser() antlr.Parser { return s.parser } + +func (s *Foreign_key_actionContext) CASCADE() antlr.TerminalNode { + return s.GetToken(KuneiformParserCASCADE, 0) +} + +func (s *Foreign_key_actionContext) RESTRICT() antlr.TerminalNode { + return s.GetToken(KuneiformParserRESTRICT, 0) +} + +func (s *Foreign_key_actionContext) DO() antlr.TerminalNode { + return s.GetToken(KuneiformParserDO, 0) +} + +func (s *Foreign_key_actionContext) ON() antlr.TerminalNode { + return s.GetToken(KuneiformParserON, 0) +} + +func (s *Foreign_key_actionContext) UPDATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUPDATE, 0) +} + +func (s *Foreign_key_actionContext) LEGACY_ON_UPDATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_ON_UPDATE, 0) +} + +func (s *Foreign_key_actionContext) DELETE() antlr.TerminalNode { + return s.GetToken(KuneiformParserDELETE, 0) +} + +func (s *Foreign_key_actionContext) LEGACY_ON_DELETE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_ON_DELETE, 0) +} + +func (s *Foreign_key_actionContext) NO() antlr.TerminalNode { + return s.GetToken(KuneiformParserNO, 0) +} + +func (s *Foreign_key_actionContext) ACTION() antlr.TerminalNode { + return s.GetToken(KuneiformParserACTION, 0) +} + +func (s *Foreign_key_actionContext) LEGACY_NO_ACTION() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_NO_ACTION, 0) +} + +func (s *Foreign_key_actionContext) SET() antlr.TerminalNode { + return s.GetToken(KuneiformParserSET, 0) +} + +func (s *Foreign_key_actionContext) NULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserNULL, 0) +} + +func (s *Foreign_key_actionContext) LEGACY_SET_NULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_SET_NULL, 0) +} + +func (s *Foreign_key_actionContext) DEFAULT() antlr.TerminalNode { + return s.GetToken(KuneiformParserDEFAULT, 0) +} + +func (s *Foreign_key_actionContext) LEGACY_SET_DEFAULT() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_SET_DEFAULT, 0) +} + +func (s *Foreign_key_actionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Foreign_key_actionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Foreign_key_actionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitForeign_key_action(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Foreign_key_action() (localctx IForeign_key_actionContext) { + localctx = NewForeign_key_actionContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 32, KuneiformParserRULE_foreign_key_action) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(289) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 22, p.GetParserRuleContext()) { + case 1: + p.SetState(282) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserON: + { + p.SetState(279) + p.Match(KuneiformParserON) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(280) + p.Match(KuneiformParserUPDATE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_ON_UPDATE: + { + p.SetState(281) + p.Match(KuneiformParserLEGACY_ON_UPDATE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case 2: + p.SetState(287) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserON: + { + p.SetState(284) + p.Match(KuneiformParserON) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(285) + p.Match(KuneiformParserDELETE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_ON_DELETE: + { + p.SetState(286) + p.Match(KuneiformParserLEGACY_ON_DELETE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + p.SetState(292) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDO { + { + p.SetState(291) + p.Match(KuneiformParserDO) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + p.SetState(311) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 27, p.GetParserRuleContext()) { + case 1: + p.SetState(297) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserNO: + { + p.SetState(294) + p.Match(KuneiformParserNO) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(295) + p.Match(KuneiformParserACTION) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_NO_ACTION: + { + p.SetState(296) + p.Match(KuneiformParserLEGACY_NO_ACTION) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case 2: + { + p.SetState(299) + p.Match(KuneiformParserCASCADE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 3: + p.SetState(303) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserSET: + { + p.SetState(300) + p.Match(KuneiformParserSET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(301) + p.Match(KuneiformParserNULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_SET_NULL: + { + p.SetState(302) + p.Match(KuneiformParserLEGACY_SET_NULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case 4: + p.SetState(308) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserSET: + { + p.SetState(305) + p.Match(KuneiformParserSET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(306) + p.Match(KuneiformParserDEFAULT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserLEGACY_SET_DEFAULT: + { + p.SetState(307) + p.Match(KuneiformParserLEGACY_SET_DEFAULT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case 5: + { + p.SetState(310) + p.Match(KuneiformParserRESTRICT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IType_listContext is an interface to support dynamic dispatch. +type IType_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllType_() []ITypeContext + Type_(i int) ITypeContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsType_listContext differentiates from other interfaces. + IsType_listContext() +} + +type Type_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyType_listContext() *Type_listContext { + var p = new(Type_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type_list + return p +} + +func InitEmptyType_listContext(p *Type_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_type_list +} + +func (*Type_listContext) IsType_listContext() {} + +func NewType_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_listContext { + var p = new(Type_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_type_list + + return p +} + +func (s *Type_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Type_listContext) AllType_() []ITypeContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ITypeContext); ok { + len++ + } + } + + tst := make([]ITypeContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ITypeContext); ok { + tst[i] = t.(ITypeContext) + i++ + } + } + + return tst +} + +func (s *Type_listContext) Type_(i int) ITypeContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Type_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Type_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Type_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Type_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Type_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitType_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Type_list() (localctx IType_listContext) { + localctx = NewType_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 34, KuneiformParserRULE_type_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(313) + p.Type_() + } + p.SetState(318) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(314) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(315) + p.Type_() + } + + p.SetState(320) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// INamed_type_listContext is an interface to support dynamic dispatch. +type INamed_type_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllIDENTIFIER() []antlr.TerminalNode + IDENTIFIER(i int) antlr.TerminalNode + AllType_() []ITypeContext + Type_(i int) ITypeContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsNamed_type_listContext differentiates from other interfaces. + IsNamed_type_listContext() +} + +type Named_type_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyNamed_type_listContext() *Named_type_listContext { + var p = new(Named_type_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_named_type_list + return p +} + +func InitEmptyNamed_type_listContext(p *Named_type_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_named_type_list +} + +func (*Named_type_listContext) IsNamed_type_listContext() {} + +func NewNamed_type_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Named_type_listContext { + var p = new(Named_type_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_named_type_list + + return p +} + +func (s *Named_type_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Named_type_listContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserIDENTIFIER) +} + +func (s *Named_type_listContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, i) +} + +func (s *Named_type_listContext) AllType_() []ITypeContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ITypeContext); ok { + len++ + } + } + + tst := make([]ITypeContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ITypeContext); ok { + tst[i] = t.(ITypeContext) + i++ + } + } + + return tst +} + +func (s *Named_type_listContext) Type_(i int) ITypeContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Named_type_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Named_type_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Named_type_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Named_type_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Named_type_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitNamed_type_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Named_type_list() (localctx INamed_type_listContext) { + localctx = NewNamed_type_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 36, KuneiformParserRULE_named_type_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(321) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(322) + p.Type_() + } + p.SetState(328) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(323) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(324) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(325) + p.Type_() + } + + p.SetState(330) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ITyped_variable_listContext is an interface to support dynamic dispatch. +type ITyped_variable_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllVariable() []IVariableContext + Variable(i int) IVariableContext + AllType_() []ITypeContext + Type_(i int) ITypeContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsTyped_variable_listContext differentiates from other interfaces. + IsTyped_variable_listContext() +} + +type Typed_variable_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyTyped_variable_listContext() *Typed_variable_listContext { + var p = new(Typed_variable_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_typed_variable_list + return p +} + +func InitEmptyTyped_variable_listContext(p *Typed_variable_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_typed_variable_list +} + +func (*Typed_variable_listContext) IsTyped_variable_listContext() {} + +func NewTyped_variable_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Typed_variable_listContext { + var p = new(Typed_variable_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_typed_variable_list + + return p +} + +func (s *Typed_variable_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Typed_variable_listContext) AllVariable() []IVariableContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IVariableContext); ok { + len++ + } + } + + tst := make([]IVariableContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IVariableContext); ok { + tst[i] = t.(IVariableContext) + i++ + } + } + + return tst +} + +func (s *Typed_variable_listContext) Variable(i int) IVariableContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariableContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IVariableContext) +} + +func (s *Typed_variable_listContext) AllType_() []ITypeContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ITypeContext); ok { + len++ + } + } + + tst := make([]ITypeContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ITypeContext); ok { + tst[i] = t.(ITypeContext) + i++ + } + } + + return tst +} + +func (s *Typed_variable_listContext) Type_(i int) ITypeContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Typed_variable_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Typed_variable_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Typed_variable_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Typed_variable_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Typed_variable_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitTyped_variable_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Typed_variable_list() (localctx ITyped_variable_listContext) { + localctx = NewTyped_variable_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 38, KuneiformParserRULE_typed_variable_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(331) + p.Variable() + } + { + p.SetState(332) + p.Type_() + } + p.SetState(339) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(333) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(334) + p.Variable() + } + { + p.SetState(335) + p.Type_() + } + + p.SetState(341) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IConstraintContext is an interface to support dynamic dispatch. +type IConstraintContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsConstraintContext differentiates from other interfaces. + IsConstraintContext() +} + +type ConstraintContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyConstraintContext() *ConstraintContext { + var p = new(ConstraintContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_constraint + return p +} + +func InitEmptyConstraintContext(p *ConstraintContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_constraint +} + +func (*ConstraintContext) IsConstraintContext() {} + +func NewConstraintContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ConstraintContext { + var p = new(ConstraintContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_constraint + + return p +} + +func (s *ConstraintContext) GetParser() antlr.Parser { return s.parser } + +func (s *ConstraintContext) CopyAll(ctx *ConstraintContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *ConstraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ConstraintContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Max_len_constraintContext struct { + ConstraintContext +} + +func NewMax_len_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Max_len_constraintContext { + var p = new(Max_len_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Max_len_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Max_len_constraintContext) MAXLEN() antlr.TerminalNode { + return s.GetToken(KuneiformParserMAXLEN, 0) +} + +func (s *Max_len_constraintContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Max_len_constraintContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Max_len_constraintContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Max_len_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitMax_len_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Default_constraintContext struct { + ConstraintContext +} + +func NewDefault_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Default_constraintContext { + var p = new(Default_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Default_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Default_constraintContext) DEFAULT() antlr.TerminalNode { + return s.GetToken(KuneiformParserDEFAULT, 0) +} + +func (s *Default_constraintContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Default_constraintContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Default_constraintContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Default_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitDefault_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Min_len_constraintContext struct { + ConstraintContext +} + +func NewMin_len_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Min_len_constraintContext { + var p = new(Min_len_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Min_len_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Min_len_constraintContext) MINLEN() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINLEN, 0) +} + +func (s *Min_len_constraintContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Min_len_constraintContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Min_len_constraintContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Min_len_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitMin_len_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Max_constraintContext struct { + ConstraintContext +} + +func NewMax_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Max_constraintContext { + var p = new(Max_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Max_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Max_constraintContext) MAX() antlr.TerminalNode { + return s.GetToken(KuneiformParserMAX, 0) +} + +func (s *Max_constraintContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Max_constraintContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Max_constraintContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Max_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitMax_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Unique_constraintContext struct { + ConstraintContext +} + +func NewUnique_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Unique_constraintContext { + var p = new(Unique_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Unique_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Unique_constraintContext) UNIQUE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUNIQUE, 0) +} + +func (s *Unique_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUnique_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Not_null_constraintContext struct { + ConstraintContext +} + +func NewNot_null_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Not_null_constraintContext { + var p = new(Not_null_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Not_null_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Not_null_constraintContext) NOTNULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOTNULL, 0) +} + +func (s *Not_null_constraintContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Not_null_constraintContext) NULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserNULL, 0) +} + +func (s *Not_null_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitNot_null_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Min_constraintContext struct { + ConstraintContext +} + +func NewMin_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Min_constraintContext { + var p = new(Min_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Min_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Min_constraintContext) MIN() antlr.TerminalNode { + return s.GetToken(KuneiformParserMIN, 0) +} + +func (s *Min_constraintContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Min_constraintContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Min_constraintContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Min_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitMin_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +type Primary_key_constraintContext struct { + ConstraintContext +} + +func NewPrimary_key_constraintContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Primary_key_constraintContext { + var p = new(Primary_key_constraintContext) + + InitEmptyConstraintContext(&p.ConstraintContext) + p.parser = parser + p.CopyAll(ctx.(*ConstraintContext)) + + return p +} + +func (s *Primary_key_constraintContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Primary_key_constraintContext) LEGACY_PRIMARY_KEY() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEGACY_PRIMARY_KEY, 0) +} + +func (s *Primary_key_constraintContext) PRIMARY() antlr.TerminalNode { + return s.GetToken(KuneiformParserPRIMARY, 0) +} + +func (s *Primary_key_constraintContext) KEY() antlr.TerminalNode { + return s.GetToken(KuneiformParserKEY, 0) +} + +func (s *Primary_key_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitPrimary_key_constraint(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Constraint() (localctx IConstraintContext) { + localctx = NewConstraintContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 40, KuneiformParserRULE_constraint) + var _la int + + p.SetState(380) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserMIN: + localctx = NewMin_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(342) + p.Match(KuneiformParserMIN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(343) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(344) + p.Literal() + } + { + p.SetState(345) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserMAX: + localctx = NewMax_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + { + p.SetState(347) + p.Match(KuneiformParserMAX) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(348) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(349) + p.Literal() + } + { + p.SetState(350) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserMINLEN: + localctx = NewMin_len_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 3) + { + p.SetState(352) + p.Match(KuneiformParserMINLEN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(353) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(354) + p.Literal() + } + { + p.SetState(355) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserMAXLEN: + localctx = NewMax_len_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 4) + { + p.SetState(357) + p.Match(KuneiformParserMAXLEN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(358) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(359) + p.Literal() + } + { + p.SetState(360) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserNOT, KuneiformParserNOTNULL: + localctx = NewNot_null_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 5) + p.SetState(365) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserNOTNULL: + { + p.SetState(362) + p.Match(KuneiformParserNOTNULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserNOT: + { + p.SetState(363) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(364) + p.Match(KuneiformParserNULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case KuneiformParserPRIMARY, KuneiformParserLEGACY_PRIMARY_KEY: + localctx = NewPrimary_key_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 6) + p.SetState(372) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserLEGACY_PRIMARY_KEY: + { + p.SetState(367) + p.Match(KuneiformParserLEGACY_PRIMARY_KEY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserPRIMARY: + { + p.SetState(368) + p.Match(KuneiformParserPRIMARY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(370) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserKEY { + { + p.SetState(369) + p.Match(KuneiformParserKEY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case KuneiformParserDEFAULT: + localctx = NewDefault_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 7) + { + p.SetState(374) + p.Match(KuneiformParserDEFAULT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(375) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(376) + p.Literal() + } + { + p.SetState(377) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserUNIQUE: + localctx = NewUnique_constraintContext(p, localctx) + p.EnterOuterAlt(localctx, 8) + { + p.SetState(379) + p.Match(KuneiformParserUNIQUE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IAccess_modifierContext is an interface to support dynamic dispatch. +type IAccess_modifierContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + PUBLIC() antlr.TerminalNode + PRIVATE() antlr.TerminalNode + VIEW() antlr.TerminalNode + OWNER() antlr.TerminalNode + + // IsAccess_modifierContext differentiates from other interfaces. + IsAccess_modifierContext() +} + +type Access_modifierContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyAccess_modifierContext() *Access_modifierContext { + var p = new(Access_modifierContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_access_modifier + return p +} + +func InitEmptyAccess_modifierContext(p *Access_modifierContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_access_modifier +} + +func (*Access_modifierContext) IsAccess_modifierContext() {} + +func NewAccess_modifierContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Access_modifierContext { + var p = new(Access_modifierContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_access_modifier + + return p +} + +func (s *Access_modifierContext) GetParser() antlr.Parser { return s.parser } + +func (s *Access_modifierContext) PUBLIC() antlr.TerminalNode { + return s.GetToken(KuneiformParserPUBLIC, 0) +} + +func (s *Access_modifierContext) PRIVATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserPRIVATE, 0) +} + +func (s *Access_modifierContext) VIEW() antlr.TerminalNode { + return s.GetToken(KuneiformParserVIEW, 0) +} + +func (s *Access_modifierContext) OWNER() antlr.TerminalNode { + return s.GetToken(KuneiformParserOWNER, 0) +} + +func (s *Access_modifierContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Access_modifierContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Access_modifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitAccess_modifier(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Access_modifier() (localctx IAccess_modifierContext) { + localctx = NewAccess_modifierContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 42, KuneiformParserRULE_access_modifier) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(382) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4123168604160) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IAction_declarationContext is an interface to support dynamic dispatch. +type IAction_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + ACTION() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + LBRACE() antlr.TerminalNode + Action_block() IAction_blockContext + RBRACE() antlr.TerminalNode + AllAnnotation() []IAnnotationContext + Annotation(i int) IAnnotationContext + Variable_list() IVariable_listContext + AllAccess_modifier() []IAccess_modifierContext + Access_modifier(i int) IAccess_modifierContext + + // IsAction_declarationContext differentiates from other interfaces. + IsAction_declarationContext() +} + +type Action_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyAction_declarationContext() *Action_declarationContext { + var p = new(Action_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_declaration + return p +} + +func InitEmptyAction_declarationContext(p *Action_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_declaration +} + +func (*Action_declarationContext) IsAction_declarationContext() {} + +func NewAction_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Action_declarationContext { + var p = new(Action_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_action_declaration + + return p +} + +func (s *Action_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Action_declarationContext) ACTION() antlr.TerminalNode { + return s.GetToken(KuneiformParserACTION, 0) +} + +func (s *Action_declarationContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Action_declarationContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Action_declarationContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Action_declarationContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Action_declarationContext) Action_block() IAction_blockContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAction_blockContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IAction_blockContext) +} + +func (s *Action_declarationContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Action_declarationContext) AllAnnotation() []IAnnotationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAnnotationContext); ok { + len++ + } + } + + tst := make([]IAnnotationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAnnotationContext); ok { + tst[i] = t.(IAnnotationContext) + i++ + } + } + + return tst +} + +func (s *Action_declarationContext) Annotation(i int) IAnnotationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAnnotationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAnnotationContext) +} + +func (s *Action_declarationContext) Variable_list() IVariable_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariable_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVariable_listContext) +} + +func (s *Action_declarationContext) AllAccess_modifier() []IAccess_modifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAccess_modifierContext); ok { + len++ + } + } + + tst := make([]IAccess_modifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAccess_modifierContext); ok { + tst[i] = t.(IAccess_modifierContext) + i++ + } + } + + return tst +} + +func (s *Action_declarationContext) Access_modifier(i int) IAccess_modifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAccess_modifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAccess_modifierContext) +} + +func (s *Action_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Action_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Action_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitAction_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Action_declaration() (localctx IAction_declarationContext) { + localctx = NewAction_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 44, KuneiformParserRULE_action_declaration) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(387) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCONTEXTUAL_VARIABLE { + { + p.SetState(384) + p.Annotation() + } + + p.SetState(389) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(390) + p.Match(KuneiformParserACTION) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(391) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(392) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(394) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserVARIABLE || _la == KuneiformParserCONTEXTUAL_VARIABLE { + { + p.SetState(393) + p.Variable_list() + } + + } + { + p.SetState(396) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(398) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ok := true; ok; ok = ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4123168604160) != 0) { + { + p.SetState(397) + p.Access_modifier() + } + + p.SetState(400) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(402) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(403) + p.Action_block() + } + { + p.SetState(404) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_declarationContext is an interface to support dynamic dispatch. +type IProcedure_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + PROCEDURE() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + LBRACE() antlr.TerminalNode + Procedure_block() IProcedure_blockContext + RBRACE() antlr.TerminalNode + AllAnnotation() []IAnnotationContext + Annotation(i int) IAnnotationContext + Typed_variable_list() ITyped_variable_listContext + AllAccess_modifier() []IAccess_modifierContext + Access_modifier(i int) IAccess_modifierContext + Procedure_return() IProcedure_returnContext + + // IsProcedure_declarationContext differentiates from other interfaces. + IsProcedure_declarationContext() +} + +type Procedure_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProcedure_declarationContext() *Procedure_declarationContext { + var p = new(Procedure_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_declaration + return p +} + +func InitEmptyProcedure_declarationContext(p *Procedure_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_declaration +} + +func (*Procedure_declarationContext) IsProcedure_declarationContext() {} + +func NewProcedure_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_declarationContext { + var p = new(Procedure_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_declaration + + return p +} + +func (s *Procedure_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_declarationContext) PROCEDURE() antlr.TerminalNode { + return s.GetToken(KuneiformParserPROCEDURE, 0) +} + +func (s *Procedure_declarationContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Procedure_declarationContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Procedure_declarationContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Procedure_declarationContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Procedure_declarationContext) Procedure_block() IProcedure_blockContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_blockContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_blockContext) +} + +func (s *Procedure_declarationContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Procedure_declarationContext) AllAnnotation() []IAnnotationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAnnotationContext); ok { + len++ + } + } + + tst := make([]IAnnotationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAnnotationContext); ok { + tst[i] = t.(IAnnotationContext) + i++ + } + } + + return tst +} + +func (s *Procedure_declarationContext) Annotation(i int) IAnnotationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAnnotationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAnnotationContext) +} + +func (s *Procedure_declarationContext) Typed_variable_list() ITyped_variable_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITyped_variable_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITyped_variable_listContext) +} + +func (s *Procedure_declarationContext) AllAccess_modifier() []IAccess_modifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAccess_modifierContext); ok { + len++ + } + } + + tst := make([]IAccess_modifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAccess_modifierContext); ok { + tst[i] = t.(IAccess_modifierContext) + i++ + } + } + + return tst +} + +func (s *Procedure_declarationContext) Access_modifier(i int) IAccess_modifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAccess_modifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAccess_modifierContext) +} + +func (s *Procedure_declarationContext) Procedure_return() IProcedure_returnContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_returnContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_returnContext) +} + +func (s *Procedure_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Procedure_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitProcedure_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_declaration() (localctx IProcedure_declarationContext) { + localctx = NewProcedure_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 46, KuneiformParserRULE_procedure_declaration) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(409) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCONTEXTUAL_VARIABLE { + { + p.SetState(406) + p.Annotation() + } + + p.SetState(411) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(412) + p.Match(KuneiformParserPROCEDURE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(413) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(414) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(416) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserVARIABLE || _la == KuneiformParserCONTEXTUAL_VARIABLE { + { + p.SetState(415) + p.Typed_variable_list() + } + + } + { + p.SetState(418) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(420) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ok := true; ok; ok = ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4123168604160) != 0) { + { + p.SetState(419) + p.Access_modifier() + } + + p.SetState(422) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(425) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserRETURNS { + { + p.SetState(424) + p.Procedure_return() + } + + } + { + p.SetState(427) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(428) + p.Procedure_block() + } + { + p.SetState(429) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IForeign_procedure_declarationContext is an interface to support dynamic dispatch. +type IForeign_procedure_declarationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetUnnamed_params returns the unnamed_params rule contexts. + GetUnnamed_params() IType_listContext + + // GetNamed_params returns the named_params rule contexts. + GetNamed_params() ITyped_variable_listContext + + // SetUnnamed_params sets the unnamed_params rule contexts. + SetUnnamed_params(IType_listContext) + + // SetNamed_params sets the named_params rule contexts. + SetNamed_params(ITyped_variable_listContext) + + // Getter signatures + FOREIGN() antlr.TerminalNode + PROCEDURE() antlr.TerminalNode + IDENTIFIER() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + Procedure_return() IProcedure_returnContext + Type_list() IType_listContext + Typed_variable_list() ITyped_variable_listContext + + // IsForeign_procedure_declarationContext differentiates from other interfaces. + IsForeign_procedure_declarationContext() +} + +type Foreign_procedure_declarationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + unnamed_params IType_listContext + named_params ITyped_variable_listContext +} + +func NewEmptyForeign_procedure_declarationContext() *Foreign_procedure_declarationContext { + var p = new(Foreign_procedure_declarationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_procedure_declaration + return p +} + +func InitEmptyForeign_procedure_declarationContext(p *Foreign_procedure_declarationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_foreign_procedure_declaration +} + +func (*Foreign_procedure_declarationContext) IsForeign_procedure_declarationContext() {} + +func NewForeign_procedure_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_procedure_declarationContext { + var p = new(Foreign_procedure_declarationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_foreign_procedure_declaration + + return p +} + +func (s *Foreign_procedure_declarationContext) GetParser() antlr.Parser { return s.parser } + +func (s *Foreign_procedure_declarationContext) GetUnnamed_params() IType_listContext { + return s.unnamed_params +} + +func (s *Foreign_procedure_declarationContext) GetNamed_params() ITyped_variable_listContext { + return s.named_params +} + +func (s *Foreign_procedure_declarationContext) SetUnnamed_params(v IType_listContext) { + s.unnamed_params = v +} + +func (s *Foreign_procedure_declarationContext) SetNamed_params(v ITyped_variable_listContext) { + s.named_params = v +} + +func (s *Foreign_procedure_declarationContext) FOREIGN() antlr.TerminalNode { + return s.GetToken(KuneiformParserFOREIGN, 0) +} + +func (s *Foreign_procedure_declarationContext) PROCEDURE() antlr.TerminalNode { + return s.GetToken(KuneiformParserPROCEDURE, 0) +} + +func (s *Foreign_procedure_declarationContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Foreign_procedure_declarationContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Foreign_procedure_declarationContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Foreign_procedure_declarationContext) Procedure_return() IProcedure_returnContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_returnContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_returnContext) +} + +func (s *Foreign_procedure_declarationContext) Type_list() IType_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_listContext) +} + +func (s *Foreign_procedure_declarationContext) Typed_variable_list() ITyped_variable_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITyped_variable_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITyped_variable_listContext) +} + +func (s *Foreign_procedure_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Foreign_procedure_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Foreign_procedure_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitForeign_procedure_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Foreign_procedure_declaration() (localctx IForeign_procedure_declarationContext) { + localctx = NewForeign_procedure_declarationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 48, KuneiformParserRULE_foreign_procedure_declaration) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(431) + p.Match(KuneiformParserFOREIGN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(432) + p.Match(KuneiformParserPROCEDURE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(433) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(434) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(437) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + switch p.GetTokenStream().LA(1) { + case KuneiformParserIDENTIFIER: + { + p.SetState(435) + + var _x = p.Type_list() + + localctx.(*Foreign_procedure_declarationContext).unnamed_params = _x + } + + case KuneiformParserVARIABLE, KuneiformParserCONTEXTUAL_VARIABLE: + { + p.SetState(436) + + var _x = p.Typed_variable_list() + + localctx.(*Foreign_procedure_declarationContext).named_params = _x + } + + case KuneiformParserRPAREN: + + default: + } + { + p.SetState(439) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(441) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserRETURNS { + { + p.SetState(440) + p.Procedure_return() + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_returnContext is an interface to support dynamic dispatch. +type IProcedure_returnContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetReturn_columns returns the return_columns rule contexts. + GetReturn_columns() INamed_type_listContext + + // GetUnnamed_return_types returns the unnamed_return_types rule contexts. + GetUnnamed_return_types() IType_listContext + + // SetReturn_columns sets the return_columns rule contexts. + SetReturn_columns(INamed_type_listContext) + + // SetUnnamed_return_types sets the unnamed_return_types rule contexts. + SetUnnamed_return_types(IType_listContext) + + // Getter signatures + RETURNS() antlr.TerminalNode + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + Named_type_list() INamed_type_listContext + Type_list() IType_listContext + TABLE() antlr.TerminalNode + + // IsProcedure_returnContext differentiates from other interfaces. + IsProcedure_returnContext() +} + +type Procedure_returnContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + return_columns INamed_type_listContext + unnamed_return_types IType_listContext +} + +func NewEmptyProcedure_returnContext() *Procedure_returnContext { + var p = new(Procedure_returnContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_return + return p +} + +func InitEmptyProcedure_returnContext(p *Procedure_returnContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_return +} + +func (*Procedure_returnContext) IsProcedure_returnContext() {} + +func NewProcedure_returnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_returnContext { + var p = new(Procedure_returnContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_return + + return p +} + +func (s *Procedure_returnContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_returnContext) GetReturn_columns() INamed_type_listContext { + return s.return_columns +} + +func (s *Procedure_returnContext) GetUnnamed_return_types() IType_listContext { + return s.unnamed_return_types +} + +func (s *Procedure_returnContext) SetReturn_columns(v INamed_type_listContext) { s.return_columns = v } + +func (s *Procedure_returnContext) SetUnnamed_return_types(v IType_listContext) { + s.unnamed_return_types = v +} + +func (s *Procedure_returnContext) RETURNS() antlr.TerminalNode { + return s.GetToken(KuneiformParserRETURNS, 0) +} + +func (s *Procedure_returnContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Procedure_returnContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Procedure_returnContext) Named_type_list() INamed_type_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(INamed_type_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(INamed_type_listContext) +} + +func (s *Procedure_returnContext) Type_list() IType_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_listContext) +} + +func (s *Procedure_returnContext) TABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserTABLE, 0) +} + +func (s *Procedure_returnContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_returnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Procedure_returnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitProcedure_return(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_return() (localctx IProcedure_returnContext) { + localctx = NewProcedure_returnContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 50, KuneiformParserRULE_procedure_return) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(443) + p.Match(KuneiformParserRETURNS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(455) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 45, p.GetParserRuleContext()) { + case 1: + p.SetState(445) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserTABLE { + { + p.SetState(444) + p.Match(KuneiformParserTABLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(447) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(448) + + var _x = p.Named_type_list() + + localctx.(*Procedure_returnContext).return_columns = _x + } + { + p.SetState(449) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 2: + { + p.SetState(451) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(452) + + var _x = p.Type_list() + + localctx.(*Procedure_returnContext).unnamed_return_types = _x + } + { + p.SetState(453) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISqlContext is an interface to support dynamic dispatch. +type ISqlContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Sql_statement() ISql_statementContext + SCOL() antlr.TerminalNode + + // IsSqlContext differentiates from other interfaces. + IsSqlContext() +} + +type SqlContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySqlContext() *SqlContext { + var p = new(SqlContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql + return p +} + +func InitEmptySqlContext(p *SqlContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql +} + +func (*SqlContext) IsSqlContext() {} + +func NewSqlContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SqlContext { + var p = new(SqlContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_sql + + return p +} + +func (s *SqlContext) GetParser() antlr.Parser { return s.parser } + +func (s *SqlContext) Sql_statement() ISql_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_statementContext) +} + +func (s *SqlContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *SqlContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *SqlContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *SqlContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSql(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Sql() (localctx ISqlContext) { + localctx = NewSqlContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 52, KuneiformParserRULE_sql) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(457) + p.Sql_statement() + } + { + p.SetState(458) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISql_statementContext is an interface to support dynamic dispatch. +type ISql_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Select_statement() ISelect_statementContext + Update_statement() IUpdate_statementContext + Insert_statement() IInsert_statementContext + Delete_statement() IDelete_statementContext + WITH() antlr.TerminalNode + AllCommon_table_expression() []ICommon_table_expressionContext + Common_table_expression(i int) ICommon_table_expressionContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsSql_statementContext differentiates from other interfaces. + IsSql_statementContext() +} + +type Sql_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySql_statementContext() *Sql_statementContext { + var p = new(Sql_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_statement + return p +} + +func InitEmptySql_statementContext(p *Sql_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_statement +} + +func (*Sql_statementContext) IsSql_statementContext() {} + +func NewSql_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_statementContext { + var p = new(Sql_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_sql_statement + + return p +} + +func (s *Sql_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Sql_statementContext) Select_statement() ISelect_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelect_statementContext) +} + +func (s *Sql_statementContext) Update_statement() IUpdate_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUpdate_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IUpdate_statementContext) +} + +func (s *Sql_statementContext) Insert_statement() IInsert_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IInsert_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IInsert_statementContext) +} + +func (s *Sql_statementContext) Delete_statement() IDelete_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IDelete_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IDelete_statementContext) +} + +func (s *Sql_statementContext) WITH() antlr.TerminalNode { + return s.GetToken(KuneiformParserWITH, 0) +} + +func (s *Sql_statementContext) AllCommon_table_expression() []ICommon_table_expressionContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ICommon_table_expressionContext); ok { + len++ + } + } + + tst := make([]ICommon_table_expressionContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ICommon_table_expressionContext); ok { + tst[i] = t.(ICommon_table_expressionContext) + i++ + } + } + + return tst +} + +func (s *Sql_statementContext) Common_table_expression(i int) ICommon_table_expressionContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICommon_table_expressionContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ICommon_table_expressionContext) +} + +func (s *Sql_statementContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Sql_statementContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Sql_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Sql_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Sql_statementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSql_statement(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Sql_statement() (localctx ISql_statementContext) { + localctx = NewSql_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 54, KuneiformParserRULE_sql_statement) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(469) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWITH { + { + p.SetState(460) + p.Match(KuneiformParserWITH) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(461) + p.Common_table_expression() + } + p.SetState(466) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(462) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(463) + p.Common_table_expression() + } + + p.SetState(468) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + p.SetState(475) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserSELECT: + { + p.SetState(471) + p.Select_statement() + } + + case KuneiformParserUPDATE: + { + p.SetState(472) + p.Update_statement() + } + + case KuneiformParserINSERT: + { + p.SetState(473) + p.Insert_statement() + } + + case KuneiformParserDELETE: + { + p.SetState(474) + p.Delete_statement() + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ICommon_table_expressionContext is an interface to support dynamic dispatch. +type ICommon_table_expressionContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllIdentifier() []IIdentifierContext + Identifier(i int) IIdentifierContext + AllLPAREN() []antlr.TerminalNode + LPAREN(i int) antlr.TerminalNode + AllRPAREN() []antlr.TerminalNode + RPAREN(i int) antlr.TerminalNode + AS() antlr.TerminalNode + Select_statement() ISelect_statementContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsCommon_table_expressionContext differentiates from other interfaces. + IsCommon_table_expressionContext() +} + +type Common_table_expressionContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyCommon_table_expressionContext() *Common_table_expressionContext { + var p = new(Common_table_expressionContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_common_table_expression + return p +} + +func InitEmptyCommon_table_expressionContext(p *Common_table_expressionContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_common_table_expression +} + +func (*Common_table_expressionContext) IsCommon_table_expressionContext() {} + +func NewCommon_table_expressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Common_table_expressionContext { + var p = new(Common_table_expressionContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_common_table_expression + + return p +} + +func (s *Common_table_expressionContext) GetParser() antlr.Parser { return s.parser } + +func (s *Common_table_expressionContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Common_table_expressionContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Common_table_expressionContext) AllLPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserLPAREN) +} + +func (s *Common_table_expressionContext) LPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, i) +} + +func (s *Common_table_expressionContext) AllRPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserRPAREN) +} + +func (s *Common_table_expressionContext) RPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, i) +} + +func (s *Common_table_expressionContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Common_table_expressionContext) Select_statement() ISelect_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelect_statementContext) +} + +func (s *Common_table_expressionContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Common_table_expressionContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Common_table_expressionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Common_table_expressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Common_table_expressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitCommon_table_expression(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Common_table_expression() (localctx ICommon_table_expressionContext) { + localctx = NewCommon_table_expressionContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 56, KuneiformParserRULE_common_table_expression) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(477) + p.Identifier() + } + { + p.SetState(478) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(487) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserIDENTIFIER { + { + p.SetState(479) + p.Identifier() + } + p.SetState(484) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(480) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(481) + p.Identifier() + } + + p.SetState(486) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + { + p.SetState(489) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(490) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(491) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(492) + p.Select_statement() + } + { + p.SetState(493) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISelect_statementContext is an interface to support dynamic dispatch. +type ISelect_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetLimit returns the limit rule contexts. + GetLimit() ISql_exprContext + + // GetOffset returns the offset rule contexts. + GetOffset() ISql_exprContext + + // SetLimit sets the limit rule contexts. + SetLimit(ISql_exprContext) + + // SetOffset sets the offset rule contexts. + SetOffset(ISql_exprContext) + + // Getter signatures + AllSelect_core() []ISelect_coreContext + Select_core(i int) ISelect_coreContext + AllCompound_operator() []ICompound_operatorContext + Compound_operator(i int) ICompound_operatorContext + ORDER() antlr.TerminalNode + BY() antlr.TerminalNode + AllOrdering_term() []IOrdering_termContext + Ordering_term(i int) IOrdering_termContext + LIMIT() antlr.TerminalNode + OFFSET() antlr.TerminalNode + AllSql_expr() []ISql_exprContext + Sql_expr(i int) ISql_exprContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsSelect_statementContext differentiates from other interfaces. + IsSelect_statementContext() +} + +type Select_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + limit ISql_exprContext + offset ISql_exprContext +} + +func NewEmptySelect_statementContext() *Select_statementContext { + var p = new(Select_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_select_statement + return p +} + +func InitEmptySelect_statementContext(p *Select_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_select_statement +} + +func (*Select_statementContext) IsSelect_statementContext() {} + +func NewSelect_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Select_statementContext { + var p = new(Select_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_select_statement + + return p +} + +func (s *Select_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Select_statementContext) GetLimit() ISql_exprContext { return s.limit } + +func (s *Select_statementContext) GetOffset() ISql_exprContext { return s.offset } + +func (s *Select_statementContext) SetLimit(v ISql_exprContext) { s.limit = v } + +func (s *Select_statementContext) SetOffset(v ISql_exprContext) { s.offset = v } + +func (s *Select_statementContext) AllSelect_core() []ISelect_coreContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISelect_coreContext); ok { + len++ + } + } + + tst := make([]ISelect_coreContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISelect_coreContext); ok { + tst[i] = t.(ISelect_coreContext) + i++ + } + } + + return tst +} + +func (s *Select_statementContext) Select_core(i int) ISelect_coreContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_coreContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISelect_coreContext) +} + +func (s *Select_statementContext) AllCompound_operator() []ICompound_operatorContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ICompound_operatorContext); ok { + len++ + } + } + + tst := make([]ICompound_operatorContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ICompound_operatorContext); ok { + tst[i] = t.(ICompound_operatorContext) + i++ + } + } + + return tst +} + +func (s *Select_statementContext) Compound_operator(i int) ICompound_operatorContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICompound_operatorContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ICompound_operatorContext) +} + +func (s *Select_statementContext) ORDER() antlr.TerminalNode { + return s.GetToken(KuneiformParserORDER, 0) +} + +func (s *Select_statementContext) BY() antlr.TerminalNode { + return s.GetToken(KuneiformParserBY, 0) +} + +func (s *Select_statementContext) AllOrdering_term() []IOrdering_termContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IOrdering_termContext); ok { + len++ + } + } + + tst := make([]IOrdering_termContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IOrdering_termContext); ok { + tst[i] = t.(IOrdering_termContext) + i++ + } + } + + return tst +} + +func (s *Select_statementContext) Ordering_term(i int) IOrdering_termContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IOrdering_termContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IOrdering_termContext) +} + +func (s *Select_statementContext) LIMIT() antlr.TerminalNode { + return s.GetToken(KuneiformParserLIMIT, 0) +} + +func (s *Select_statementContext) OFFSET() antlr.TerminalNode { + return s.GetToken(KuneiformParserOFFSET, 0) +} + +func (s *Select_statementContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Select_statementContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Select_statementContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Select_statementContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Select_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Select_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Select_statementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSelect_statement(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Select_statement() (localctx ISelect_statementContext) { + localctx = NewSelect_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 58, KuneiformParserRULE_select_statement) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(495) + p.Select_core() + } + p.SetState(501) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for (int64((_la-101)) & ^0x3f) == 0 && ((int64(1)<<(_la-101))&7) != 0 { + { + p.SetState(496) + p.Compound_operator() + } + { + p.SetState(497) + p.Select_core() + } + + p.SetState(503) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(514) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserORDER { + { + p.SetState(504) + p.Match(KuneiformParserORDER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(505) + p.Match(KuneiformParserBY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(506) + p.Ordering_term() + } + p.SetState(511) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(507) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(508) + p.Ordering_term() + } + + p.SetState(513) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + p.SetState(518) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserLIMIT { + { + p.SetState(516) + p.Match(KuneiformParserLIMIT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(517) + + var _x = p.sql_expr(0) + + localctx.(*Select_statementContext).limit = _x + } + + } + p.SetState(522) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserOFFSET { + { + p.SetState(520) + p.Match(KuneiformParserOFFSET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(521) + + var _x = p.sql_expr(0) + + localctx.(*Select_statementContext).offset = _x + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ICompound_operatorContext is an interface to support dynamic dispatch. +type ICompound_operatorContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + UNION() antlr.TerminalNode + ALL() antlr.TerminalNode + INTERSECT() antlr.TerminalNode + EXCEPT() antlr.TerminalNode + + // IsCompound_operatorContext differentiates from other interfaces. + IsCompound_operatorContext() +} + +type Compound_operatorContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyCompound_operatorContext() *Compound_operatorContext { + var p = new(Compound_operatorContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_compound_operator + return p +} + +func InitEmptyCompound_operatorContext(p *Compound_operatorContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_compound_operator +} + +func (*Compound_operatorContext) IsCompound_operatorContext() {} + +func NewCompound_operatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Compound_operatorContext { + var p = new(Compound_operatorContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_compound_operator + + return p +} + +func (s *Compound_operatorContext) GetParser() antlr.Parser { return s.parser } + +func (s *Compound_operatorContext) UNION() antlr.TerminalNode { + return s.GetToken(KuneiformParserUNION, 0) +} + +func (s *Compound_operatorContext) ALL() antlr.TerminalNode { + return s.GetToken(KuneiformParserALL, 0) +} + +func (s *Compound_operatorContext) INTERSECT() antlr.TerminalNode { + return s.GetToken(KuneiformParserINTERSECT, 0) +} + +func (s *Compound_operatorContext) EXCEPT() antlr.TerminalNode { + return s.GetToken(KuneiformParserEXCEPT, 0) +} + +func (s *Compound_operatorContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Compound_operatorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Compound_operatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitCompound_operator(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Compound_operator() (localctx ICompound_operatorContext) { + localctx = NewCompound_operatorContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 60, KuneiformParserRULE_compound_operator) + var _la int + + p.SetState(530) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserUNION: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(524) + p.Match(KuneiformParserUNION) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(526) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserALL { + { + p.SetState(525) + p.Match(KuneiformParserALL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + + case KuneiformParserINTERSECT: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(528) + p.Match(KuneiformParserINTERSECT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserEXCEPT: + p.EnterOuterAlt(localctx, 3) + { + p.SetState(529) + p.Match(KuneiformParserEXCEPT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IOrdering_termContext is an interface to support dynamic dispatch. +type IOrdering_termContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Sql_expr() ISql_exprContext + NULLS() antlr.TerminalNode + ASC() antlr.TerminalNode + DESC() antlr.TerminalNode + FIRST() antlr.TerminalNode + LAST() antlr.TerminalNode + + // IsOrdering_termContext differentiates from other interfaces. + IsOrdering_termContext() +} + +type Ordering_termContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOrdering_termContext() *Ordering_termContext { + var p = new(Ordering_termContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_ordering_term + return p +} + +func InitEmptyOrdering_termContext(p *Ordering_termContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_ordering_term +} + +func (*Ordering_termContext) IsOrdering_termContext() {} + +func NewOrdering_termContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Ordering_termContext { + var p = new(Ordering_termContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_ordering_term + + return p +} + +func (s *Ordering_termContext) GetParser() antlr.Parser { return s.parser } + +func (s *Ordering_termContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Ordering_termContext) NULLS() antlr.TerminalNode { + return s.GetToken(KuneiformParserNULLS, 0) +} + +func (s *Ordering_termContext) ASC() antlr.TerminalNode { + return s.GetToken(KuneiformParserASC, 0) +} + +func (s *Ordering_termContext) DESC() antlr.TerminalNode { + return s.GetToken(KuneiformParserDESC, 0) +} + +func (s *Ordering_termContext) FIRST() antlr.TerminalNode { + return s.GetToken(KuneiformParserFIRST, 0) +} + +func (s *Ordering_termContext) LAST() antlr.TerminalNode { + return s.GetToken(KuneiformParserLAST, 0) +} + +func (s *Ordering_termContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Ordering_termContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Ordering_termContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitOrdering_term(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Ordering_term() (localctx IOrdering_termContext) { + localctx = NewOrdering_termContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 62, KuneiformParserRULE_ordering_term) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(532) + p.sql_expr(0) + } + p.SetState(534) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserASC || _la == KuneiformParserDESC { + { + p.SetState(533) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserASC || _la == KuneiformParserDESC) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + + } + p.SetState(538) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNULLS { + { + p.SetState(536) + p.Match(KuneiformParserNULLS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(537) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserFIRST || _la == KuneiformParserLAST) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISelect_coreContext is an interface to support dynamic dispatch. +type ISelect_coreContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetWhere returns the where rule contexts. + GetWhere() ISql_exprContext + + // GetGroup_by returns the group_by rule contexts. + GetGroup_by() ISql_expr_listContext + + // GetHaving returns the having rule contexts. + GetHaving() ISql_exprContext + + // SetWhere sets the where rule contexts. + SetWhere(ISql_exprContext) + + // SetGroup_by sets the group_by rule contexts. + SetGroup_by(ISql_expr_listContext) + + // SetHaving sets the having rule contexts. + SetHaving(ISql_exprContext) + + // Getter signatures + SELECT() antlr.TerminalNode + AllResult_column() []IResult_columnContext + Result_column(i int) IResult_columnContext + DISTINCT() antlr.TerminalNode + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + FROM() antlr.TerminalNode + Relation() IRelationContext + WHERE() antlr.TerminalNode + GROUP() antlr.TerminalNode + BY() antlr.TerminalNode + AllSql_expr() []ISql_exprContext + Sql_expr(i int) ISql_exprContext + Sql_expr_list() ISql_expr_listContext + AllJoin() []IJoinContext + Join(i int) IJoinContext + HAVING() antlr.TerminalNode + + // IsSelect_coreContext differentiates from other interfaces. + IsSelect_coreContext() +} + +type Select_coreContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + where ISql_exprContext + group_by ISql_expr_listContext + having ISql_exprContext +} + +func NewEmptySelect_coreContext() *Select_coreContext { + var p = new(Select_coreContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_select_core + return p +} + +func InitEmptySelect_coreContext(p *Select_coreContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_select_core +} + +func (*Select_coreContext) IsSelect_coreContext() {} + +func NewSelect_coreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Select_coreContext { + var p = new(Select_coreContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_select_core + + return p +} + +func (s *Select_coreContext) GetParser() antlr.Parser { return s.parser } + +func (s *Select_coreContext) GetWhere() ISql_exprContext { return s.where } + +func (s *Select_coreContext) GetGroup_by() ISql_expr_listContext { return s.group_by } + +func (s *Select_coreContext) GetHaving() ISql_exprContext { return s.having } + +func (s *Select_coreContext) SetWhere(v ISql_exprContext) { s.where = v } + +func (s *Select_coreContext) SetGroup_by(v ISql_expr_listContext) { s.group_by = v } + +func (s *Select_coreContext) SetHaving(v ISql_exprContext) { s.having = v } + +func (s *Select_coreContext) SELECT() antlr.TerminalNode { + return s.GetToken(KuneiformParserSELECT, 0) +} + +func (s *Select_coreContext) AllResult_column() []IResult_columnContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IResult_columnContext); ok { + len++ + } + } + + tst := make([]IResult_columnContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IResult_columnContext); ok { + tst[i] = t.(IResult_columnContext) + i++ + } + } + + return tst +} + +func (s *Select_coreContext) Result_column(i int) IResult_columnContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IResult_columnContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IResult_columnContext) +} + +func (s *Select_coreContext) DISTINCT() antlr.TerminalNode { + return s.GetToken(KuneiformParserDISTINCT, 0) +} + +func (s *Select_coreContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Select_coreContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Select_coreContext) FROM() antlr.TerminalNode { + return s.GetToken(KuneiformParserFROM, 0) +} + +func (s *Select_coreContext) Relation() IRelationContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *Select_coreContext) WHERE() antlr.TerminalNode { + return s.GetToken(KuneiformParserWHERE, 0) +} + +func (s *Select_coreContext) GROUP() antlr.TerminalNode { + return s.GetToken(KuneiformParserGROUP, 0) +} + +func (s *Select_coreContext) BY() antlr.TerminalNode { + return s.GetToken(KuneiformParserBY, 0) +} + +func (s *Select_coreContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Select_coreContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Select_coreContext) Sql_expr_list() ISql_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_expr_listContext) +} + +func (s *Select_coreContext) AllJoin() []IJoinContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IJoinContext); ok { + len++ + } + } + + tst := make([]IJoinContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IJoinContext); ok { + tst[i] = t.(IJoinContext) + i++ + } + } + + return tst +} + +func (s *Select_coreContext) Join(i int) IJoinContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IJoinContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IJoinContext) +} + +func (s *Select_coreContext) HAVING() antlr.TerminalNode { + return s.GetToken(KuneiformParserHAVING, 0) +} + +func (s *Select_coreContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Select_coreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Select_coreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSelect_core(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Select_core() (localctx ISelect_coreContext) { + localctx = NewSelect_coreContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 64, KuneiformParserRULE_select_core) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(540) + p.Match(KuneiformParserSELECT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(542) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDISTINCT { + { + p.SetState(541) + p.Match(KuneiformParserDISTINCT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(544) + p.Result_column() + } + p.SetState(549) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(545) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(546) + p.Result_column() + } + + p.SetState(551) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(560) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserFROM { + { + p.SetState(552) + p.Match(KuneiformParserFROM) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(553) + p.Relation() + } + p.SetState(557) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for (int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&134217735) != 0 { + { + p.SetState(554) + p.Join() + } + + p.SetState(559) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + p.SetState(564) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWHERE { + { + p.SetState(562) + p.Match(KuneiformParserWHERE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(563) + + var _x = p.sql_expr(0) + + localctx.(*Select_coreContext).where = _x + } + + } + p.SetState(573) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserGROUP { + { + p.SetState(566) + p.Match(KuneiformParserGROUP) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(567) + p.Match(KuneiformParserBY) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(568) + + var _x = p.Sql_expr_list() + + localctx.(*Select_coreContext).group_by = _x + } + p.SetState(571) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserHAVING { + { + p.SetState(569) + p.Match(KuneiformParserHAVING) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(570) + + var _x = p.sql_expr(0) + + localctx.(*Select_coreContext).having = _x + } + + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IRelationContext is an interface to support dynamic dispatch. +type IRelationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsRelationContext differentiates from other interfaces. + IsRelationContext() +} + +type RelationContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyRelationContext() *RelationContext { + var p = new(RelationContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_relation + return p +} + +func InitEmptyRelationContext(p *RelationContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_relation +} + +func (*RelationContext) IsRelationContext() {} + +func NewRelationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationContext { + var p = new(RelationContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_relation + + return p +} + +func (s *RelationContext) GetParser() antlr.Parser { return s.parser } + +func (s *RelationContext) CopyAll(ctx *RelationContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *RelationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *RelationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Function_relationContext struct { + RelationContext + alias IIdentifierContext +} + +func NewFunction_relationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Function_relationContext { + var p = new(Function_relationContext) + + InitEmptyRelationContext(&p.RelationContext) + p.parser = parser + p.CopyAll(ctx.(*RelationContext)) + + return p +} + +func (s *Function_relationContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Function_relationContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Function_relationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Function_relationContext) Sql_function_call() ISql_function_callContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_function_callContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_function_callContext) +} + +func (s *Function_relationContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Function_relationContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Function_relationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitFunction_relation(s) + + default: + return t.VisitChildren(s) + } +} + +type Table_relationContext struct { + RelationContext + table_name IIdentifierContext + alias IIdentifierContext +} + +func NewTable_relationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Table_relationContext { + var p = new(Table_relationContext) + + InitEmptyRelationContext(&p.RelationContext) + p.parser = parser + p.CopyAll(ctx.(*RelationContext)) + + return p +} + +func (s *Table_relationContext) GetTable_name() IIdentifierContext { return s.table_name } + +func (s *Table_relationContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Table_relationContext) SetTable_name(v IIdentifierContext) { s.table_name = v } + +func (s *Table_relationContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Table_relationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Table_relationContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Table_relationContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Table_relationContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Table_relationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitTable_relation(s) + + default: + return t.VisitChildren(s) + } +} + +type Subquery_relationContext struct { + RelationContext + alias IIdentifierContext +} + +func NewSubquery_relationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Subquery_relationContext { + var p = new(Subquery_relationContext) + + InitEmptyRelationContext(&p.RelationContext) + p.parser = parser + p.CopyAll(ctx.(*RelationContext)) + + return p +} + +func (s *Subquery_relationContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Subquery_relationContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Subquery_relationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Subquery_relationContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Subquery_relationContext) Select_statement() ISelect_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelect_statementContext) +} + +func (s *Subquery_relationContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Subquery_relationContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Subquery_relationContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Subquery_relationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSubquery_relation(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Relation() (localctx IRelationContext) { + localctx = NewRelationContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 66, KuneiformParserRULE_relation) + var _la int + + p.SetState(598) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 73, p.GetParserRuleContext()) { + case 1: + localctx = NewTable_relationContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(575) + + var _x = p.Identifier() + + localctx.(*Table_relationContext).table_name = _x + } + p.SetState(580) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserAS || _la == KuneiformParserIDENTIFIER { + p.SetState(577) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(576) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(579) + + var _x = p.Identifier() + + localctx.(*Table_relationContext).alias = _x + } + + } + + case 2: + localctx = NewSubquery_relationContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + { + p.SetState(582) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(583) + p.Select_statement() + } + { + p.SetState(584) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(589) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserAS || _la == KuneiformParserIDENTIFIER { + p.SetState(586) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(585) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(588) + + var _x = p.Identifier() + + localctx.(*Subquery_relationContext).alias = _x + } + + } + + case 3: + localctx = NewFunction_relationContext(p, localctx) + p.EnterOuterAlt(localctx, 3) + { + p.SetState(591) + p.Sql_function_call() + } + + p.SetState(593) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(592) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + p.SetState(596) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserIDENTIFIER { + { + p.SetState(595) + + var _x = p.Identifier() + + localctx.(*Function_relationContext).alias = _x + } + + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IJoinContext is an interface to support dynamic dispatch. +type IJoinContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + JOIN() antlr.TerminalNode + Relation() IRelationContext + ON() antlr.TerminalNode + Sql_expr() ISql_exprContext + INNER() antlr.TerminalNode + LEFT() antlr.TerminalNode + RIGHT() antlr.TerminalNode + FULL() antlr.TerminalNode + + // IsJoinContext differentiates from other interfaces. + IsJoinContext() +} + +type JoinContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyJoinContext() *JoinContext { + var p = new(JoinContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_join + return p +} + +func InitEmptyJoinContext(p *JoinContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_join +} + +func (*JoinContext) IsJoinContext() {} + +func NewJoinContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *JoinContext { + var p = new(JoinContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_join + + return p +} + +func (s *JoinContext) GetParser() antlr.Parser { return s.parser } + +func (s *JoinContext) JOIN() antlr.TerminalNode { + return s.GetToken(KuneiformParserJOIN, 0) +} + +func (s *JoinContext) Relation() IRelationContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *JoinContext) ON() antlr.TerminalNode { + return s.GetToken(KuneiformParserON, 0) +} + +func (s *JoinContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *JoinContext) INNER() antlr.TerminalNode { + return s.GetToken(KuneiformParserINNER, 0) +} + +func (s *JoinContext) LEFT() antlr.TerminalNode { + return s.GetToken(KuneiformParserLEFT, 0) +} + +func (s *JoinContext) RIGHT() antlr.TerminalNode { + return s.GetToken(KuneiformParserRIGHT, 0) +} + +func (s *JoinContext) FULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserFULL, 0) +} + +func (s *JoinContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *JoinContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *JoinContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitJoin(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Join() (localctx IJoinContext) { + localctx = NewJoinContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 68, KuneiformParserRULE_join) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(600) + _la = p.GetTokenStream().LA(1) + + if !((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&134217735) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(601) + p.Match(KuneiformParserJOIN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(602) + p.Relation() + } + { + p.SetState(603) + p.Match(KuneiformParserON) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(604) + p.sql_expr(0) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IResult_columnContext is an interface to support dynamic dispatch. +type IResult_columnContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsResult_columnContext differentiates from other interfaces. + IsResult_columnContext() +} + +type Result_columnContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyResult_columnContext() *Result_columnContext { + var p = new(Result_columnContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_result_column + return p +} + +func InitEmptyResult_columnContext(p *Result_columnContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_result_column +} + +func (*Result_columnContext) IsResult_columnContext() {} + +func NewResult_columnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Result_columnContext { + var p = new(Result_columnContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_result_column + + return p +} + +func (s *Result_columnContext) GetParser() antlr.Parser { return s.parser } + +func (s *Result_columnContext) CopyAll(ctx *Result_columnContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Result_columnContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Result_columnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Expression_result_columnContext struct { + Result_columnContext +} + +func NewExpression_result_columnContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expression_result_columnContext { + var p = new(Expression_result_columnContext) + + InitEmptyResult_columnContext(&p.Result_columnContext) + p.parser = parser + p.CopyAll(ctx.(*Result_columnContext)) + + return p +} + +func (s *Expression_result_columnContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Expression_result_columnContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Expression_result_columnContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Expression_result_columnContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Expression_result_columnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitExpression_result_column(s) + + default: + return t.VisitChildren(s) + } +} + +type Wildcard_result_columnContext struct { + Result_columnContext + table_name IIdentifierContext +} + +func NewWildcard_result_columnContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Wildcard_result_columnContext { + var p = new(Wildcard_result_columnContext) + + InitEmptyResult_columnContext(&p.Result_columnContext) + p.parser = parser + p.CopyAll(ctx.(*Result_columnContext)) + + return p +} + +func (s *Wildcard_result_columnContext) GetTable_name() IIdentifierContext { return s.table_name } + +func (s *Wildcard_result_columnContext) SetTable_name(v IIdentifierContext) { s.table_name = v } + +func (s *Wildcard_result_columnContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Wildcard_result_columnContext) STAR() antlr.TerminalNode { + return s.GetToken(KuneiformParserSTAR, 0) +} + +func (s *Wildcard_result_columnContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Wildcard_result_columnContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Wildcard_result_columnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitWildcard_result_column(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Result_column() (localctx IResult_columnContext) { + localctx = NewResult_columnContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 70, KuneiformParserRULE_result_column) + var _la int + + p.SetState(619) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 77, p.GetParserRuleContext()) { + case 1: + localctx = NewExpression_result_columnContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(606) + p.sql_expr(0) + } + p.SetState(611) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserAS || _la == KuneiformParserIDENTIFIER { + p.SetState(608) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(607) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(610) + p.Identifier() + } + + } + + case 2: + localctx = NewWildcard_result_columnContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + p.SetState(616) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDOUBLE_QUOTE || _la == KuneiformParserIDENTIFIER { + { + p.SetState(613) + + var _x = p.Identifier() + + localctx.(*Wildcard_result_columnContext).table_name = _x + } + { + p.SetState(614) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(618) + p.Match(KuneiformParserSTAR) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IUpdate_statementContext is an interface to support dynamic dispatch. +type IUpdate_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetTable_name returns the table_name rule contexts. + GetTable_name() IIdentifierContext + + // GetAlias returns the alias rule contexts. + GetAlias() IIdentifierContext + + // GetWhere returns the where rule contexts. + GetWhere() ISql_exprContext + + // SetTable_name sets the table_name rule contexts. + SetTable_name(IIdentifierContext) + + // SetAlias sets the alias rule contexts. + SetAlias(IIdentifierContext) + + // SetWhere sets the where rule contexts. + SetWhere(ISql_exprContext) + + // Getter signatures + UPDATE() antlr.TerminalNode + SET() antlr.TerminalNode + AllUpdate_set_clause() []IUpdate_set_clauseContext + Update_set_clause(i int) IUpdate_set_clauseContext + AllIdentifier() []IIdentifierContext + Identifier(i int) IIdentifierContext + AS() antlr.TerminalNode + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + FROM() antlr.TerminalNode + Relation() IRelationContext + WHERE() antlr.TerminalNode + Sql_expr() ISql_exprContext + AllJoin() []IJoinContext + Join(i int) IJoinContext + + // IsUpdate_statementContext differentiates from other interfaces. + IsUpdate_statementContext() +} + +type Update_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + table_name IIdentifierContext + alias IIdentifierContext + where ISql_exprContext +} + +func NewEmptyUpdate_statementContext() *Update_statementContext { + var p = new(Update_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_update_statement + return p +} + +func InitEmptyUpdate_statementContext(p *Update_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_update_statement +} + +func (*Update_statementContext) IsUpdate_statementContext() {} + +func NewUpdate_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Update_statementContext { + var p = new(Update_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_update_statement + + return p +} + +func (s *Update_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Update_statementContext) GetTable_name() IIdentifierContext { return s.table_name } + +func (s *Update_statementContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Update_statementContext) GetWhere() ISql_exprContext { return s.where } + +func (s *Update_statementContext) SetTable_name(v IIdentifierContext) { s.table_name = v } + +func (s *Update_statementContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Update_statementContext) SetWhere(v ISql_exprContext) { s.where = v } + +func (s *Update_statementContext) UPDATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUPDATE, 0) +} + +func (s *Update_statementContext) SET() antlr.TerminalNode { + return s.GetToken(KuneiformParserSET, 0) +} + +func (s *Update_statementContext) AllUpdate_set_clause() []IUpdate_set_clauseContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IUpdate_set_clauseContext); ok { + len++ + } + } + + tst := make([]IUpdate_set_clauseContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IUpdate_set_clauseContext); ok { + tst[i] = t.(IUpdate_set_clauseContext) + i++ + } + } + + return tst +} + +func (s *Update_statementContext) Update_set_clause(i int) IUpdate_set_clauseContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUpdate_set_clauseContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IUpdate_set_clauseContext) +} + +func (s *Update_statementContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Update_statementContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Update_statementContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Update_statementContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Update_statementContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Update_statementContext) FROM() antlr.TerminalNode { + return s.GetToken(KuneiformParserFROM, 0) +} + +func (s *Update_statementContext) Relation() IRelationContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *Update_statementContext) WHERE() antlr.TerminalNode { + return s.GetToken(KuneiformParserWHERE, 0) +} + +func (s *Update_statementContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Update_statementContext) AllJoin() []IJoinContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IJoinContext); ok { + len++ + } + } + + tst := make([]IJoinContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IJoinContext); ok { + tst[i] = t.(IJoinContext) + i++ + } + } + + return tst +} + +func (s *Update_statementContext) Join(i int) IJoinContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IJoinContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IJoinContext) +} + +func (s *Update_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Update_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Update_statementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUpdate_statement(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Update_statement() (localctx IUpdate_statementContext) { + localctx = NewUpdate_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 72, KuneiformParserRULE_update_statement) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(621) + p.Match(KuneiformParserUPDATE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(622) + + var _x = p.Identifier() + + localctx.(*Update_statementContext).table_name = _x + } + p.SetState(625) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(623) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(624) + + var _x = p.Identifier() + + localctx.(*Update_statementContext).alias = _x + } + + } + { + p.SetState(627) + p.Match(KuneiformParserSET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(628) + p.Update_set_clause() + } + p.SetState(633) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(629) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(630) + p.Update_set_clause() + } + + p.SetState(635) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(644) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserFROM { + { + p.SetState(636) + p.Match(KuneiformParserFROM) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(637) + p.Relation() + } + p.SetState(641) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for (int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&134217735) != 0 { + { + p.SetState(638) + p.Join() + } + + p.SetState(643) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + + } + p.SetState(648) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWHERE { + { + p.SetState(646) + p.Match(KuneiformParserWHERE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(647) + + var _x = p.sql_expr(0) + + localctx.(*Update_statementContext).where = _x + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IUpdate_set_clauseContext is an interface to support dynamic dispatch. +type IUpdate_set_clauseContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetColumn returns the column rule contexts. + GetColumn() IIdentifierContext + + // SetColumn sets the column rule contexts. + SetColumn(IIdentifierContext) + + // Getter signatures + EQUALS() antlr.TerminalNode + Sql_expr() ISql_exprContext + Identifier() IIdentifierContext + + // IsUpdate_set_clauseContext differentiates from other interfaces. + IsUpdate_set_clauseContext() +} + +type Update_set_clauseContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + column IIdentifierContext +} + +func NewEmptyUpdate_set_clauseContext() *Update_set_clauseContext { + var p = new(Update_set_clauseContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_update_set_clause + return p +} + +func InitEmptyUpdate_set_clauseContext(p *Update_set_clauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_update_set_clause +} + +func (*Update_set_clauseContext) IsUpdate_set_clauseContext() {} + +func NewUpdate_set_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Update_set_clauseContext { + var p = new(Update_set_clauseContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_update_set_clause + + return p +} + +func (s *Update_set_clauseContext) GetParser() antlr.Parser { return s.parser } + +func (s *Update_set_clauseContext) GetColumn() IIdentifierContext { return s.column } + +func (s *Update_set_clauseContext) SetColumn(v IIdentifierContext) { s.column = v } + +func (s *Update_set_clauseContext) EQUALS() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUALS, 0) +} + +func (s *Update_set_clauseContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Update_set_clauseContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Update_set_clauseContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Update_set_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Update_set_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUpdate_set_clause(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Update_set_clause() (localctx IUpdate_set_clauseContext) { + localctx = NewUpdate_set_clauseContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 74, KuneiformParserRULE_update_set_clause) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(650) + + var _x = p.Identifier() + + localctx.(*Update_set_clauseContext).column = _x + } + { + p.SetState(651) + p.Match(KuneiformParserEQUALS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(652) + p.sql_expr(0) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IInsert_statementContext is an interface to support dynamic dispatch. +type IInsert_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetTable_name returns the table_name rule contexts. + GetTable_name() IIdentifierContext + + // GetAlias returns the alias rule contexts. + GetAlias() IIdentifierContext + + // GetTarget_columns returns the target_columns rule contexts. + GetTarget_columns() IIdentifier_listContext + + // SetTable_name sets the table_name rule contexts. + SetTable_name(IIdentifierContext) + + // SetAlias sets the alias rule contexts. + SetAlias(IIdentifierContext) + + // SetTarget_columns sets the target_columns rule contexts. + SetTarget_columns(IIdentifier_listContext) + + // Getter signatures + INSERT() antlr.TerminalNode + INTO() antlr.TerminalNode + VALUES() antlr.TerminalNode + AllLPAREN() []antlr.TerminalNode + LPAREN(i int) antlr.TerminalNode + AllSql_expr_list() []ISql_expr_listContext + Sql_expr_list(i int) ISql_expr_listContext + AllRPAREN() []antlr.TerminalNode + RPAREN(i int) antlr.TerminalNode + AllIdentifier() []IIdentifierContext + Identifier(i int) IIdentifierContext + AS() antlr.TerminalNode + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + Upsert_clause() IUpsert_clauseContext + Identifier_list() IIdentifier_listContext + + // IsInsert_statementContext differentiates from other interfaces. + IsInsert_statementContext() +} + +type Insert_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + table_name IIdentifierContext + alias IIdentifierContext + target_columns IIdentifier_listContext +} + +func NewEmptyInsert_statementContext() *Insert_statementContext { + var p = new(Insert_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_insert_statement + return p +} + +func InitEmptyInsert_statementContext(p *Insert_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_insert_statement +} + +func (*Insert_statementContext) IsInsert_statementContext() {} + +func NewInsert_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Insert_statementContext { + var p = new(Insert_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_insert_statement + + return p +} + +func (s *Insert_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Insert_statementContext) GetTable_name() IIdentifierContext { return s.table_name } + +func (s *Insert_statementContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Insert_statementContext) GetTarget_columns() IIdentifier_listContext { + return s.target_columns +} + +func (s *Insert_statementContext) SetTable_name(v IIdentifierContext) { s.table_name = v } + +func (s *Insert_statementContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Insert_statementContext) SetTarget_columns(v IIdentifier_listContext) { s.target_columns = v } + +func (s *Insert_statementContext) INSERT() antlr.TerminalNode { + return s.GetToken(KuneiformParserINSERT, 0) +} + +func (s *Insert_statementContext) INTO() antlr.TerminalNode { + return s.GetToken(KuneiformParserINTO, 0) +} + +func (s *Insert_statementContext) VALUES() antlr.TerminalNode { + return s.GetToken(KuneiformParserVALUES, 0) +} + +func (s *Insert_statementContext) AllLPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserLPAREN) +} + +func (s *Insert_statementContext) LPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, i) +} + +func (s *Insert_statementContext) AllSql_expr_list() []ISql_expr_listContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_expr_listContext); ok { + len++ + } + } + + tst := make([]ISql_expr_listContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_expr_listContext); ok { + tst[i] = t.(ISql_expr_listContext) + i++ + } + } + + return tst +} + +func (s *Insert_statementContext) Sql_expr_list(i int) ISql_expr_listContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_expr_listContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_expr_listContext) +} + +func (s *Insert_statementContext) AllRPAREN() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserRPAREN) +} + +func (s *Insert_statementContext) RPAREN(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, i) +} + +func (s *Insert_statementContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Insert_statementContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Insert_statementContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Insert_statementContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Insert_statementContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Insert_statementContext) Upsert_clause() IUpsert_clauseContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUpsert_clauseContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IUpsert_clauseContext) +} + +func (s *Insert_statementContext) Identifier_list() IIdentifier_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifier_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifier_listContext) +} + +func (s *Insert_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Insert_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Insert_statementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitInsert_statement(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Insert_statement() (localctx IInsert_statementContext) { + localctx = NewInsert_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 76, KuneiformParserRULE_insert_statement) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(654) + p.Match(KuneiformParserINSERT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(655) + p.Match(KuneiformParserINTO) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(656) + + var _x = p.Identifier() + + localctx.(*Insert_statementContext).table_name = _x + } + p.SetState(659) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(657) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(658) + + var _x = p.Identifier() + + localctx.(*Insert_statementContext).alias = _x + } + + } + p.SetState(665) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserLPAREN { + { + p.SetState(661) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(662) + + var _x = p.Identifier_list() + + localctx.(*Insert_statementContext).target_columns = _x + } + { + p.SetState(663) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(667) + p.Match(KuneiformParserVALUES) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(668) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(669) + p.Sql_expr_list() + } + { + p.SetState(670) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(678) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(671) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(672) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(673) + p.Sql_expr_list() + } + { + p.SetState(674) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + p.SetState(680) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(682) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserON { + { + p.SetState(681) + p.Upsert_clause() + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IUpsert_clauseContext is an interface to support dynamic dispatch. +type IUpsert_clauseContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetConflict_columns returns the conflict_columns rule contexts. + GetConflict_columns() IIdentifier_listContext + + // GetConflict_where returns the conflict_where rule contexts. + GetConflict_where() ISql_exprContext + + // GetUpdate_where returns the update_where rule contexts. + GetUpdate_where() ISql_exprContext + + // SetConflict_columns sets the conflict_columns rule contexts. + SetConflict_columns(IIdentifier_listContext) + + // SetConflict_where sets the conflict_where rule contexts. + SetConflict_where(ISql_exprContext) + + // SetUpdate_where sets the update_where rule contexts. + SetUpdate_where(ISql_exprContext) + + // Getter signatures + ON() antlr.TerminalNode + CONFLICT() antlr.TerminalNode + DO() antlr.TerminalNode + NOTHING() antlr.TerminalNode + UPDATE() antlr.TerminalNode + SET() antlr.TerminalNode + AllUpdate_set_clause() []IUpdate_set_clauseContext + Update_set_clause(i int) IUpdate_set_clauseContext + LPAREN() antlr.TerminalNode + RPAREN() antlr.TerminalNode + Identifier_list() IIdentifier_listContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + AllWHERE() []antlr.TerminalNode + WHERE(i int) antlr.TerminalNode + AllSql_expr() []ISql_exprContext + Sql_expr(i int) ISql_exprContext + + // IsUpsert_clauseContext differentiates from other interfaces. + IsUpsert_clauseContext() +} + +type Upsert_clauseContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + conflict_columns IIdentifier_listContext + conflict_where ISql_exprContext + update_where ISql_exprContext +} + +func NewEmptyUpsert_clauseContext() *Upsert_clauseContext { + var p = new(Upsert_clauseContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_upsert_clause + return p +} + +func InitEmptyUpsert_clauseContext(p *Upsert_clauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_upsert_clause +} + +func (*Upsert_clauseContext) IsUpsert_clauseContext() {} + +func NewUpsert_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Upsert_clauseContext { + var p = new(Upsert_clauseContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_upsert_clause + + return p +} + +func (s *Upsert_clauseContext) GetParser() antlr.Parser { return s.parser } + +func (s *Upsert_clauseContext) GetConflict_columns() IIdentifier_listContext { + return s.conflict_columns +} + +func (s *Upsert_clauseContext) GetConflict_where() ISql_exprContext { return s.conflict_where } + +func (s *Upsert_clauseContext) GetUpdate_where() ISql_exprContext { return s.update_where } + +func (s *Upsert_clauseContext) SetConflict_columns(v IIdentifier_listContext) { s.conflict_columns = v } + +func (s *Upsert_clauseContext) SetConflict_where(v ISql_exprContext) { s.conflict_where = v } + +func (s *Upsert_clauseContext) SetUpdate_where(v ISql_exprContext) { s.update_where = v } + +func (s *Upsert_clauseContext) ON() antlr.TerminalNode { + return s.GetToken(KuneiformParserON, 0) +} + +func (s *Upsert_clauseContext) CONFLICT() antlr.TerminalNode { + return s.GetToken(KuneiformParserCONFLICT, 0) +} + +func (s *Upsert_clauseContext) DO() antlr.TerminalNode { + return s.GetToken(KuneiformParserDO, 0) +} + +func (s *Upsert_clauseContext) NOTHING() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOTHING, 0) +} + +func (s *Upsert_clauseContext) UPDATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUPDATE, 0) +} + +func (s *Upsert_clauseContext) SET() antlr.TerminalNode { + return s.GetToken(KuneiformParserSET, 0) +} + +func (s *Upsert_clauseContext) AllUpdate_set_clause() []IUpdate_set_clauseContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IUpdate_set_clauseContext); ok { + len++ + } + } + + tst := make([]IUpdate_set_clauseContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IUpdate_set_clauseContext); ok { + tst[i] = t.(IUpdate_set_clauseContext) + i++ + } + } + + return tst +} + +func (s *Upsert_clauseContext) Update_set_clause(i int) IUpdate_set_clauseContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUpdate_set_clauseContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IUpdate_set_clauseContext) +} + +func (s *Upsert_clauseContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Upsert_clauseContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Upsert_clauseContext) Identifier_list() IIdentifier_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifier_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifier_listContext) +} + +func (s *Upsert_clauseContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Upsert_clauseContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Upsert_clauseContext) AllWHERE() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserWHERE) +} + +func (s *Upsert_clauseContext) WHERE(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserWHERE, i) +} + +func (s *Upsert_clauseContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Upsert_clauseContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Upsert_clauseContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Upsert_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Upsert_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUpsert_clause(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Upsert_clause() (localctx IUpsert_clauseContext) { + localctx = NewUpsert_clauseContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 78, KuneiformParserRULE_upsert_clause) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(684) + p.Match(KuneiformParserON) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(685) + p.Match(KuneiformParserCONFLICT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(693) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserLPAREN { + { + p.SetState(686) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(687) + + var _x = p.Identifier_list() + + localctx.(*Upsert_clauseContext).conflict_columns = _x + } + { + p.SetState(688) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(691) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWHERE { + { + p.SetState(689) + p.Match(KuneiformParserWHERE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(690) + + var _x = p.sql_expr(0) + + localctx.(*Upsert_clauseContext).conflict_where = _x + } + + } + + } + { + p.SetState(695) + p.Match(KuneiformParserDO) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(711) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserNOTHING: + { + p.SetState(696) + p.Match(KuneiformParserNOTHING) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserUPDATE: + { + p.SetState(697) + p.Match(KuneiformParserUPDATE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(698) + p.Match(KuneiformParserSET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(699) + p.Update_set_clause() + } + p.SetState(704) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(700) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(701) + p.Update_set_clause() + } + + p.SetState(706) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(709) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWHERE { + { + p.SetState(707) + p.Match(KuneiformParserWHERE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(708) + + var _x = p.sql_expr(0) + + localctx.(*Upsert_clauseContext).update_where = _x + } + + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IDelete_statementContext is an interface to support dynamic dispatch. +type IDelete_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetTable_name returns the table_name rule contexts. + GetTable_name() IIdentifierContext + + // GetAlias returns the alias rule contexts. + GetAlias() IIdentifierContext + + // GetWhere returns the where rule contexts. + GetWhere() ISql_exprContext + + // SetTable_name sets the table_name rule contexts. + SetTable_name(IIdentifierContext) + + // SetAlias sets the alias rule contexts. + SetAlias(IIdentifierContext) + + // SetWhere sets the where rule contexts. + SetWhere(ISql_exprContext) + + // Getter signatures + DELETE() antlr.TerminalNode + FROM() antlr.TerminalNode + AllIdentifier() []IIdentifierContext + Identifier(i int) IIdentifierContext + AS() antlr.TerminalNode + WHERE() antlr.TerminalNode + Sql_expr() ISql_exprContext + + // IsDelete_statementContext differentiates from other interfaces. + IsDelete_statementContext() +} + +type Delete_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + table_name IIdentifierContext + alias IIdentifierContext + where ISql_exprContext +} + +func NewEmptyDelete_statementContext() *Delete_statementContext { + var p = new(Delete_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_delete_statement + return p +} + +func InitEmptyDelete_statementContext(p *Delete_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_delete_statement +} + +func (*Delete_statementContext) IsDelete_statementContext() {} + +func NewDelete_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Delete_statementContext { + var p = new(Delete_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_delete_statement + + return p +} + +func (s *Delete_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Delete_statementContext) GetTable_name() IIdentifierContext { return s.table_name } + +func (s *Delete_statementContext) GetAlias() IIdentifierContext { return s.alias } + +func (s *Delete_statementContext) GetWhere() ISql_exprContext { return s.where } + +func (s *Delete_statementContext) SetTable_name(v IIdentifierContext) { s.table_name = v } + +func (s *Delete_statementContext) SetAlias(v IIdentifierContext) { s.alias = v } + +func (s *Delete_statementContext) SetWhere(v ISql_exprContext) { s.where = v } + +func (s *Delete_statementContext) DELETE() antlr.TerminalNode { + return s.GetToken(KuneiformParserDELETE, 0) +} + +func (s *Delete_statementContext) FROM() antlr.TerminalNode { + return s.GetToken(KuneiformParserFROM, 0) +} + +func (s *Delete_statementContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Delete_statementContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Delete_statementContext) AS() antlr.TerminalNode { + return s.GetToken(KuneiformParserAS, 0) +} + +func (s *Delete_statementContext) WHERE() antlr.TerminalNode { + return s.GetToken(KuneiformParserWHERE, 0) +} + +func (s *Delete_statementContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Delete_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Delete_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Delete_statementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitDelete_statement(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Delete_statement() (localctx IDelete_statementContext) { + localctx = NewDelete_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 80, KuneiformParserRULE_delete_statement) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(713) + p.Match(KuneiformParserDELETE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(714) + p.Match(KuneiformParserFROM) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(715) + + var _x = p.Identifier() + + localctx.(*Delete_statementContext).table_name = _x + } + p.SetState(718) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserAS { + { + p.SetState(716) + p.Match(KuneiformParserAS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(717) + + var _x = p.Identifier() + + localctx.(*Delete_statementContext).alias = _x + } + + } + p.SetState(722) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserWHERE { + { + p.SetState(720) + p.Match(KuneiformParserWHERE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(721) + + var _x = p.sql_expr(0) + + localctx.(*Delete_statementContext).where = _x + } + + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISql_exprContext is an interface to support dynamic dispatch. +type ISql_exprContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsSql_exprContext differentiates from other interfaces. + IsSql_exprContext() +} + +type Sql_exprContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySql_exprContext() *Sql_exprContext { + var p = new(Sql_exprContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_expr + return p +} + +func InitEmptySql_exprContext(p *Sql_exprContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_expr +} + +func (*Sql_exprContext) IsSql_exprContext() {} + +func NewSql_exprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_exprContext { + var p = new(Sql_exprContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_sql_expr + + return p +} + +func (s *Sql_exprContext) GetParser() antlr.Parser { return s.parser } + +func (s *Sql_exprContext) CopyAll(ctx *Sql_exprContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Sql_exprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Column_sql_exprContext struct { + Sql_exprContext + table IIdentifierContext + column IIdentifierContext +} + +func NewColumn_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Column_sql_exprContext { + var p = new(Column_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Column_sql_exprContext) GetTable() IIdentifierContext { return s.table } + +func (s *Column_sql_exprContext) GetColumn() IIdentifierContext { return s.column } + +func (s *Column_sql_exprContext) SetTable(v IIdentifierContext) { s.table = v } + +func (s *Column_sql_exprContext) SetColumn(v IIdentifierContext) { s.column = v } + +func (s *Column_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Column_sql_exprContext) AllIdentifier() []IIdentifierContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIdentifierContext); ok { + len++ + } + } + + tst := make([]IIdentifierContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIdentifierContext); ok { + tst[i] = t.(IIdentifierContext) + i++ + } + } + + return tst +} + +func (s *Column_sql_exprContext) Identifier(i int) IIdentifierContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Column_sql_exprContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Column_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Column_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitColumn_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Logical_sql_exprContext struct { + Sql_exprContext + left ISql_exprContext + right ISql_exprContext +} + +func NewLogical_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Logical_sql_exprContext { + var p = new(Logical_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Logical_sql_exprContext) GetLeft() ISql_exprContext { return s.left } + +func (s *Logical_sql_exprContext) GetRight() ISql_exprContext { return s.right } + +func (s *Logical_sql_exprContext) SetLeft(v ISql_exprContext) { s.left = v } + +func (s *Logical_sql_exprContext) SetRight(v ISql_exprContext) { s.right = v } + +func (s *Logical_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Logical_sql_exprContext) AND() antlr.TerminalNode { + return s.GetToken(KuneiformParserAND, 0) +} + +func (s *Logical_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Logical_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Logical_sql_exprContext) OR() antlr.TerminalNode { + return s.GetToken(KuneiformParserOR, 0) +} + +func (s *Logical_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitLogical_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Array_access_sql_exprContext struct { + Sql_exprContext +} + +func NewArray_access_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Array_access_sql_exprContext { + var p = new(Array_access_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Array_access_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Array_access_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Array_access_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Array_access_sql_exprContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *Array_access_sql_exprContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *Array_access_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Array_access_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitArray_access_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Field_access_sql_exprContext struct { + Sql_exprContext +} + +func NewField_access_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Field_access_sql_exprContext { + var p = new(Field_access_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Field_access_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Field_access_sql_exprContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Field_access_sql_exprContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Field_access_sql_exprContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Field_access_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Field_access_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitField_access_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Comparison_sql_exprContext struct { + Sql_exprContext + left ISql_exprContext + right ISql_exprContext +} + +func NewComparison_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Comparison_sql_exprContext { + var p = new(Comparison_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Comparison_sql_exprContext) GetLeft() ISql_exprContext { return s.left } + +func (s *Comparison_sql_exprContext) GetRight() ISql_exprContext { return s.right } + +func (s *Comparison_sql_exprContext) SetLeft(v ISql_exprContext) { s.left = v } + +func (s *Comparison_sql_exprContext) SetRight(v ISql_exprContext) { s.right = v } + +func (s *Comparison_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Comparison_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Comparison_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Comparison_sql_exprContext) EQUALS() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUALS, 0) +} + +func (s *Comparison_sql_exprContext) EQUATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUATE, 0) +} + +func (s *Comparison_sql_exprContext) NEQ() antlr.TerminalNode { + return s.GetToken(KuneiformParserNEQ, 0) +} + +func (s *Comparison_sql_exprContext) LT() antlr.TerminalNode { + return s.GetToken(KuneiformParserLT, 0) +} + +func (s *Comparison_sql_exprContext) LTE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLTE, 0) +} + +func (s *Comparison_sql_exprContext) GT() antlr.TerminalNode { + return s.GetToken(KuneiformParserGT, 0) +} + +func (s *Comparison_sql_exprContext) GTE() antlr.TerminalNode { + return s.GetToken(KuneiformParserGTE, 0) +} + +func (s *Comparison_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitComparison_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Literal_sql_exprContext struct { + Sql_exprContext +} + +func NewLiteral_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Literal_sql_exprContext { + var p = new(Literal_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Literal_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Literal_sql_exprContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Literal_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Literal_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitLiteral_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Between_sql_exprContext struct { + Sql_exprContext + element ISql_exprContext + lower ISql_exprContext + upper ISql_exprContext +} + +func NewBetween_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Between_sql_exprContext { + var p = new(Between_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Between_sql_exprContext) GetElement() ISql_exprContext { return s.element } + +func (s *Between_sql_exprContext) GetLower() ISql_exprContext { return s.lower } + +func (s *Between_sql_exprContext) GetUpper() ISql_exprContext { return s.upper } + +func (s *Between_sql_exprContext) SetElement(v ISql_exprContext) { s.element = v } + +func (s *Between_sql_exprContext) SetLower(v ISql_exprContext) { s.lower = v } + +func (s *Between_sql_exprContext) SetUpper(v ISql_exprContext) { s.upper = v } + +func (s *Between_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Between_sql_exprContext) BETWEEN() antlr.TerminalNode { + return s.GetToken(KuneiformParserBETWEEN, 0) +} + +func (s *Between_sql_exprContext) AND() antlr.TerminalNode { + return s.GetToken(KuneiformParserAND, 0) +} + +func (s *Between_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Between_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Between_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Between_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitBetween_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Function_call_sql_exprContext struct { + Sql_exprContext +} + +func NewFunction_call_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Function_call_sql_exprContext { + var p = new(Function_call_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Function_call_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Function_call_sql_exprContext) Sql_function_call() ISql_function_callContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_function_callContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_function_callContext) +} + +func (s *Function_call_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Function_call_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitFunction_call_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Paren_sql_exprContext struct { + Sql_exprContext +} + +func NewParen_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Paren_sql_exprContext { + var p = new(Paren_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Paren_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Paren_sql_exprContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Paren_sql_exprContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Paren_sql_exprContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Paren_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Paren_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitParen_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Collate_sql_exprContext struct { + Sql_exprContext +} + +func NewCollate_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Collate_sql_exprContext { + var p = new(Collate_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Collate_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Collate_sql_exprContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Collate_sql_exprContext) COLLATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserCOLLATE, 0) +} + +func (s *Collate_sql_exprContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Collate_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitCollate_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Variable_sql_exprContext struct { + Sql_exprContext +} + +func NewVariable_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Variable_sql_exprContext { + var p = new(Variable_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Variable_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Variable_sql_exprContext) Variable() IVariableContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariableContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVariableContext) +} + +func (s *Variable_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Variable_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitVariable_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Is_sql_exprContext struct { + Sql_exprContext + left ISql_exprContext + right ISql_exprContext +} + +func NewIs_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Is_sql_exprContext { + var p = new(Is_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Is_sql_exprContext) GetLeft() ISql_exprContext { return s.left } + +func (s *Is_sql_exprContext) GetRight() ISql_exprContext { return s.right } + +func (s *Is_sql_exprContext) SetLeft(v ISql_exprContext) { s.left = v } + +func (s *Is_sql_exprContext) SetRight(v ISql_exprContext) { s.right = v } + +func (s *Is_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Is_sql_exprContext) IS() antlr.TerminalNode { + return s.GetToken(KuneiformParserIS, 0) +} + +func (s *Is_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Is_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Is_sql_exprContext) NULL() antlr.TerminalNode { + return s.GetToken(KuneiformParserNULL, 0) +} + +func (s *Is_sql_exprContext) TRUE() antlr.TerminalNode { + return s.GetToken(KuneiformParserTRUE, 0) +} + +func (s *Is_sql_exprContext) FALSE() antlr.TerminalNode { + return s.GetToken(KuneiformParserFALSE, 0) +} + +func (s *Is_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Is_sql_exprContext) DISTINCT() antlr.TerminalNode { + return s.GetToken(KuneiformParserDISTINCT, 0) +} + +func (s *Is_sql_exprContext) FROM() antlr.TerminalNode { + return s.GetToken(KuneiformParserFROM, 0) +} + +func (s *Is_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIs_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Like_sql_exprContext struct { + Sql_exprContext + left ISql_exprContext + right ISql_exprContext +} + +func NewLike_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Like_sql_exprContext { + var p = new(Like_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Like_sql_exprContext) GetLeft() ISql_exprContext { return s.left } + +func (s *Like_sql_exprContext) GetRight() ISql_exprContext { return s.right } + +func (s *Like_sql_exprContext) SetLeft(v ISql_exprContext) { s.left = v } + +func (s *Like_sql_exprContext) SetRight(v ISql_exprContext) { s.right = v } + +func (s *Like_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Like_sql_exprContext) LIKE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLIKE, 0) +} + +func (s *Like_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Like_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Like_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Like_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitLike_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Arithmetic_sql_exprContext struct { + Sql_exprContext + left ISql_exprContext + right ISql_exprContext +} + +func NewArithmetic_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Arithmetic_sql_exprContext { + var p = new(Arithmetic_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Arithmetic_sql_exprContext) GetLeft() ISql_exprContext { return s.left } + +func (s *Arithmetic_sql_exprContext) GetRight() ISql_exprContext { return s.right } + +func (s *Arithmetic_sql_exprContext) SetLeft(v ISql_exprContext) { s.left = v } + +func (s *Arithmetic_sql_exprContext) SetRight(v ISql_exprContext) { s.right = v } + +func (s *Arithmetic_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Arithmetic_sql_exprContext) CONCAT() antlr.TerminalNode { + return s.GetToken(KuneiformParserCONCAT, 0) +} + +func (s *Arithmetic_sql_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Arithmetic_sql_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Arithmetic_sql_exprContext) STAR() antlr.TerminalNode { + return s.GetToken(KuneiformParserSTAR, 0) +} + +func (s *Arithmetic_sql_exprContext) DIV() antlr.TerminalNode { + return s.GetToken(KuneiformParserDIV, 0) +} + +func (s *Arithmetic_sql_exprContext) MOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserMOD, 0) +} + +func (s *Arithmetic_sql_exprContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Arithmetic_sql_exprContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Arithmetic_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitArithmetic_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Subquery_sql_exprContext struct { + Sql_exprContext +} + +func NewSubquery_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Subquery_sql_exprContext { + var p = new(Subquery_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Subquery_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Subquery_sql_exprContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Subquery_sql_exprContext) Select_statement() ISelect_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelect_statementContext) +} + +func (s *Subquery_sql_exprContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Subquery_sql_exprContext) EXISTS() antlr.TerminalNode { + return s.GetToken(KuneiformParserEXISTS, 0) +} + +func (s *Subquery_sql_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Subquery_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Subquery_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSubquery_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Unary_sql_exprContext struct { + Sql_exprContext +} + +func NewUnary_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Unary_sql_exprContext { + var p = new(Unary_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Unary_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Unary_sql_exprContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Unary_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *Unary_sql_exprContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Unary_sql_exprContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Unary_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUnary_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Case_exprContext struct { + Sql_exprContext + case_clause ISql_exprContext + else_clause ISql_exprContext +} + +func NewCase_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Case_exprContext { + var p = new(Case_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *Case_exprContext) GetCase_clause() ISql_exprContext { return s.case_clause } + +func (s *Case_exprContext) GetElse_clause() ISql_exprContext { return s.else_clause } + +func (s *Case_exprContext) SetCase_clause(v ISql_exprContext) { s.case_clause = v } + +func (s *Case_exprContext) SetElse_clause(v ISql_exprContext) { s.else_clause = v } + +func (s *Case_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Case_exprContext) CASE() antlr.TerminalNode { + return s.GetToken(KuneiformParserCASE, 0) +} + +func (s *Case_exprContext) END() antlr.TerminalNode { + return s.GetToken(KuneiformParserEND, 0) +} + +func (s *Case_exprContext) AllWhen_then_clause() []IWhen_then_clauseContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IWhen_then_clauseContext); ok { + len++ + } + } + + tst := make([]IWhen_then_clauseContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IWhen_then_clauseContext); ok { + tst[i] = t.(IWhen_then_clauseContext) + i++ + } + } + + return tst +} + +func (s *Case_exprContext) When_then_clause(i int) IWhen_then_clauseContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IWhen_then_clauseContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IWhen_then_clauseContext) +} + +func (s *Case_exprContext) ELSE() antlr.TerminalNode { + return s.GetToken(KuneiformParserELSE, 0) +} + +func (s *Case_exprContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Case_exprContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Case_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitCase_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type In_sql_exprContext struct { + Sql_exprContext +} + +func NewIn_sql_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *In_sql_exprContext { + var p = new(In_sql_exprContext) + + InitEmptySql_exprContext(&p.Sql_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_exprContext)) + + return p +} + +func (s *In_sql_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *In_sql_exprContext) Sql_expr() ISql_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *In_sql_exprContext) IN() antlr.TerminalNode { + return s.GetToken(KuneiformParserIN, 0) +} + +func (s *In_sql_exprContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *In_sql_exprContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *In_sql_exprContext) Sql_expr_list() ISql_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_expr_listContext) +} + +func (s *In_sql_exprContext) Select_statement() ISelect_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISelect_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISelect_statementContext) +} + +func (s *In_sql_exprContext) NOT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNOT, 0) +} + +func (s *In_sql_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIn_sql_expr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Sql_expr() (localctx ISql_exprContext) { + return p.sql_expr(0) +} + +func (p *KuneiformParser) sql_expr(_p int) (localctx ISql_exprContext) { + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + + _parentState := p.GetState() + localctx = NewSql_exprContext(p, p.GetParserRuleContext(), _parentState) + var _prevctx ISql_exprContext = localctx + var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. + _startState := 82 + p.EnterRecursionRule(localctx, 82, KuneiformParserRULE_sql_expr, _p) + var _la int + + var _alt int + + p.EnterOuterAlt(localctx, 1) + p.SetState(781) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 106, p.GetParserRuleContext()) { + case 1: + localctx = NewLiteral_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + + { + p.SetState(725) + p.Literal() + } + p.SetState(727) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 94, p.GetParserRuleContext()) == 1 { + { + p.SetState(726) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 2: + localctx = NewFunction_call_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(729) + p.Sql_function_call() + } + p.SetState(731) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 95, p.GetParserRuleContext()) == 1 { + { + p.SetState(730) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 3: + localctx = NewVariable_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(733) + p.Variable() + } + p.SetState(735) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 96, p.GetParserRuleContext()) == 1 { + { + p.SetState(734) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 4: + localctx = NewColumn_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + p.SetState(740) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 97, p.GetParserRuleContext()) == 1 { + { + p.SetState(737) + + var _x = p.Identifier() + + localctx.(*Column_sql_exprContext).table = _x + } + { + p.SetState(738) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } else if p.HasError() { // JIM + goto errorExit + } + { + p.SetState(742) + + var _x = p.Identifier() + + localctx.(*Column_sql_exprContext).column = _x + } + p.SetState(744) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 98, p.GetParserRuleContext()) == 1 { + { + p.SetState(743) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 5: + localctx = NewParen_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(746) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(747) + p.sql_expr(0) + } + { + p.SetState(748) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(750) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 99, p.GetParserRuleContext()) == 1 { + { + p.SetState(749) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 6: + localctx = NewUnary_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(752) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2305843009216839680) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(753) + p.sql_expr(10) + } + + case 7: + localctx = NewCase_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(754) + p.Match(KuneiformParserCASE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(756) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2377900607549735040) != 0) || ((int64((_la-69)) & ^0x3f) == 0 && ((int64(1)<<(_la-69))&-2288391560656584703) != 0) { + { + p.SetState(755) + + var _x = p.sql_expr(0) + + localctx.(*Case_exprContext).case_clause = _x + } + + } + p.SetState(759) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ok := true; ok; ok = _la == KuneiformParserWHEN { + { + p.SetState(758) + p.When_then_clause() + } + + p.SetState(761) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(765) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserELSE { + { + p.SetState(763) + p.Match(KuneiformParserELSE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(764) + + var _x = p.sql_expr(0) + + localctx.(*Case_exprContext).else_clause = _x + } + + } + { + p.SetState(767) + p.Match(KuneiformParserEND) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 8: + localctx = NewSubquery_sql_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + p.SetState(773) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT || _la == KuneiformParserEXISTS { + p.SetState(770) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT { + { + p.SetState(769) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(772) + p.Match(KuneiformParserEXISTS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(775) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(776) + p.Select_statement() + } + { + p.SetState(777) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(779) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 105, p.GetParserRuleContext()) == 1 { + { + p.SetState(778) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(859) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 116, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + if p.GetParseListeners() != nil { + p.TriggerExitRuleEvent() + } + _prevctx = localctx + p.SetState(857) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 115, p.GetParserRuleContext()) { + case 1: + localctx = NewComparison_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Comparison_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(783) + + if !(p.Precpred(p.GetParserRuleContext(), 13)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 13)", "")) + goto errorExit + } + { + p.SetState(784) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&260145152) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(785) + + var _x = p.sql_expr(14) + + localctx.(*Comparison_sql_exprContext).right = _x + } + + case 2: + localctx = NewLike_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Like_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(786) + + if !(p.Precpred(p.GetParserRuleContext(), 11)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 11)", "")) + goto errorExit + } + p.SetState(788) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT { + { + p.SetState(787) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(790) + p.Match(KuneiformParserLIKE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(791) + + var _x = p.sql_expr(12) + + localctx.(*Like_sql_exprContext).right = _x + } + + case 3: + localctx = NewBetween_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Between_sql_exprContext).element = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(792) + + if !(p.Precpred(p.GetParserRuleContext(), 9)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) + goto errorExit + } + p.SetState(794) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT { + { + p.SetState(793) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(796) + p.Match(KuneiformParserBETWEEN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(797) + + var _x = p.sql_expr(0) + + localctx.(*Between_sql_exprContext).lower = _x + } + { + p.SetState(798) + p.Match(KuneiformParserAND) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(799) + + var _x = p.sql_expr(10) + + localctx.(*Between_sql_exprContext).upper = _x + } + + case 4: + localctx = NewArithmetic_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Arithmetic_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(801) + + if !(p.Precpred(p.GetParserRuleContext(), 5)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) + goto errorExit + } + { + p.SetState(802) + p.Match(KuneiformParserCONCAT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(803) + + var _x = p.sql_expr(6) + + localctx.(*Arithmetic_sql_exprContext).right = _x + } + + case 5: + localctx = NewArithmetic_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Arithmetic_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(804) + + if !(p.Precpred(p.GetParserRuleContext(), 4)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) + goto errorExit + } + { + p.SetState(805) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4734976) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(806) + + var _x = p.sql_expr(5) + + localctx.(*Arithmetic_sql_exprContext).right = _x + } + + case 6: + localctx = NewArithmetic_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Arithmetic_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(807) + + if !(p.Precpred(p.GetParserRuleContext(), 3)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + goto errorExit + } + { + p.SetState(808) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserPLUS || _la == KuneiformParserMINUS) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(809) + + var _x = p.sql_expr(4) + + localctx.(*Arithmetic_sql_exprContext).right = _x + } + + case 7: + localctx = NewLogical_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Logical_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(810) + + if !(p.Precpred(p.GetParserRuleContext(), 2)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + goto errorExit + } + { + p.SetState(811) + p.Match(KuneiformParserAND) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(812) + + var _x = p.sql_expr(3) + + localctx.(*Logical_sql_exprContext).right = _x + } + + case 8: + localctx = NewLogical_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Logical_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(813) + + if !(p.Precpred(p.GetParserRuleContext(), 1)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) + goto errorExit + } + { + p.SetState(814) + p.Match(KuneiformParserOR) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(815) + + var _x = p.sql_expr(2) + + localctx.(*Logical_sql_exprContext).right = _x + } + + case 9: + localctx = NewCollate_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(816) + + if !(p.Precpred(p.GetParserRuleContext(), 20)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 20)", "")) + goto errorExit + } + { + p.SetState(817) + p.Match(KuneiformParserCOLLATE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(818) + p.Identifier() + } + + case 10: + localctx = NewArray_access_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(819) + + if !(p.Precpred(p.GetParserRuleContext(), 16)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 16)", "")) + goto errorExit + } + { + p.SetState(820) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(821) + p.sql_expr(0) + } + { + p.SetState(822) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(824) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 109, p.GetParserRuleContext()) == 1 { + { + p.SetState(823) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 11: + localctx = NewField_access_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(826) + + if !(p.Precpred(p.GetParserRuleContext(), 15)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 15)", "")) + goto errorExit + } + { + p.SetState(827) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(828) + p.Identifier() + } + p.SetState(830) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 110, p.GetParserRuleContext()) == 1 { + { + p.SetState(829) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 12: + localctx = NewIn_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(832) + + if !(p.Precpred(p.GetParserRuleContext(), 12)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 12)", "")) + goto errorExit + } + p.SetState(834) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT { + { + p.SetState(833) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(836) + p.Match(KuneiformParserIN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(837) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(840) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserLPAREN, KuneiformParserPLUS, KuneiformParserMINUS, KuneiformParserDOUBLE_QUOTE, KuneiformParserNULL, KuneiformParserNOT, KuneiformParserEXISTS, KuneiformParserCASE, KuneiformParserSTRING_, KuneiformParserTRUE, KuneiformParserFALSE, KuneiformParserDIGITS_, KuneiformParserBINARY_, KuneiformParserIDENTIFIER, KuneiformParserVARIABLE, KuneiformParserCONTEXTUAL_VARIABLE: + { + p.SetState(838) + p.Sql_expr_list() + } + + case KuneiformParserSELECT: + { + p.SetState(839) + p.Select_statement() + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + { + p.SetState(842) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 13: + localctx = NewIs_sql_exprContext(p, NewSql_exprContext(p, _parentctx, _parentState)) + localctx.(*Is_sql_exprContext).left = _prevctx + + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_sql_expr) + p.SetState(844) + + if !(p.Precpred(p.GetParserRuleContext(), 8)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) + goto errorExit + } + { + p.SetState(845) + p.Match(KuneiformParserIS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(847) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserNOT { + { + p.SetState(846) + p.Match(KuneiformParserNOT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + p.SetState(855) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserDISTINCT: + { + p.SetState(849) + p.Match(KuneiformParserDISTINCT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(850) + p.Match(KuneiformParserFROM) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(851) + + var _x = p.sql_expr(0) + + localctx.(*Is_sql_exprContext).right = _x + } + + case KuneiformParserNULL: + { + p.SetState(852) + p.Match(KuneiformParserNULL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserTRUE: + { + p.SetState(853) + p.Match(KuneiformParserTRUE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserFALSE: + { + p.SetState(854) + p.Match(KuneiformParserFALSE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + + } + p.SetState(861) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 116, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.UnrollRecursionContexts(_parentctx) + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IWhen_then_clauseContext is an interface to support dynamic dispatch. +type IWhen_then_clauseContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetWhen_condition returns the when_condition rule contexts. + GetWhen_condition() ISql_exprContext + + // GetThen returns the then rule contexts. + GetThen() ISql_exprContext + + // SetWhen_condition sets the when_condition rule contexts. + SetWhen_condition(ISql_exprContext) + + // SetThen sets the then rule contexts. + SetThen(ISql_exprContext) + + // Getter signatures + WHEN() antlr.TerminalNode + THEN() antlr.TerminalNode + AllSql_expr() []ISql_exprContext + Sql_expr(i int) ISql_exprContext + + // IsWhen_then_clauseContext differentiates from other interfaces. + IsWhen_then_clauseContext() +} + +type When_then_clauseContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser + when_condition ISql_exprContext + then ISql_exprContext +} + +func NewEmptyWhen_then_clauseContext() *When_then_clauseContext { + var p = new(When_then_clauseContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_when_then_clause + return p +} + +func InitEmptyWhen_then_clauseContext(p *When_then_clauseContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_when_then_clause +} + +func (*When_then_clauseContext) IsWhen_then_clauseContext() {} + +func NewWhen_then_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *When_then_clauseContext { + var p = new(When_then_clauseContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_when_then_clause + + return p +} + +func (s *When_then_clauseContext) GetParser() antlr.Parser { return s.parser } + +func (s *When_then_clauseContext) GetWhen_condition() ISql_exprContext { return s.when_condition } + +func (s *When_then_clauseContext) GetThen() ISql_exprContext { return s.then } + +func (s *When_then_clauseContext) SetWhen_condition(v ISql_exprContext) { s.when_condition = v } + +func (s *When_then_clauseContext) SetThen(v ISql_exprContext) { s.then = v } + +func (s *When_then_clauseContext) WHEN() antlr.TerminalNode { + return s.GetToken(KuneiformParserWHEN, 0) +} + +func (s *When_then_clauseContext) THEN() antlr.TerminalNode { + return s.GetToken(KuneiformParserTHEN, 0) +} + +func (s *When_then_clauseContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *When_then_clauseContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *When_then_clauseContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *When_then_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *When_then_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitWhen_then_clause(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) When_then_clause() (localctx IWhen_then_clauseContext) { + localctx = NewWhen_then_clauseContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 84, KuneiformParserRULE_when_then_clause) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(862) + p.Match(KuneiformParserWHEN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(863) + + var _x = p.sql_expr(0) + + localctx.(*When_then_clauseContext).when_condition = _x + } + { + p.SetState(864) + p.Match(KuneiformParserTHEN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(865) + + var _x = p.sql_expr(0) + + localctx.(*When_then_clauseContext).then = _x + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISql_expr_listContext is an interface to support dynamic dispatch. +type ISql_expr_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllSql_expr() []ISql_exprContext + Sql_expr(i int) ISql_exprContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsSql_expr_listContext differentiates from other interfaces. + IsSql_expr_listContext() +} + +type Sql_expr_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySql_expr_listContext() *Sql_expr_listContext { + var p = new(Sql_expr_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_expr_list + return p +} + +func InitEmptySql_expr_listContext(p *Sql_expr_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_expr_list +} + +func (*Sql_expr_listContext) IsSql_expr_listContext() {} + +func NewSql_expr_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_expr_listContext { + var p = new(Sql_expr_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_sql_expr_list + + return p +} + +func (s *Sql_expr_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Sql_expr_listContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Sql_expr_listContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Sql_expr_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Sql_expr_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Sql_expr_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Sql_expr_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Sql_expr_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSql_expr_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Sql_expr_list() (localctx ISql_expr_listContext) { + localctx = NewSql_expr_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 86, KuneiformParserRULE_sql_expr_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(867) + p.sql_expr(0) + } + p.SetState(872) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(868) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(869) + p.sql_expr(0) + } + + p.SetState(874) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// ISql_function_callContext is an interface to support dynamic dispatch. +type ISql_function_callContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsSql_function_callContext differentiates from other interfaces. + IsSql_function_callContext() +} + +type Sql_function_callContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptySql_function_callContext() *Sql_function_callContext { + var p = new(Sql_function_callContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_function_call + return p +} + +func InitEmptySql_function_callContext(p *Sql_function_callContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_sql_function_call +} + +func (*Sql_function_callContext) IsSql_function_callContext() {} + +func NewSql_function_callContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_function_callContext { + var p = new(Sql_function_callContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_sql_function_call + + return p +} + +func (s *Sql_function_callContext) GetParser() antlr.Parser { return s.parser } + +func (s *Sql_function_callContext) CopyAll(ctx *Sql_function_callContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Sql_function_callContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Sql_function_callContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Normal_call_sqlContext struct { + Sql_function_callContext +} + +func NewNormal_call_sqlContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Normal_call_sqlContext { + var p = new(Normal_call_sqlContext) + + InitEmptySql_function_callContext(&p.Sql_function_callContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_function_callContext)) + + return p +} + +func (s *Normal_call_sqlContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Normal_call_sqlContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Normal_call_sqlContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Normal_call_sqlContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Normal_call_sqlContext) Sql_expr_list() ISql_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_expr_listContext) +} + +func (s *Normal_call_sqlContext) STAR() antlr.TerminalNode { + return s.GetToken(KuneiformParserSTAR, 0) +} + +func (s *Normal_call_sqlContext) DISTINCT() antlr.TerminalNode { + return s.GetToken(KuneiformParserDISTINCT, 0) +} + +func (s *Normal_call_sqlContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitNormal_call_sql(s) + + default: + return t.VisitChildren(s) + } +} + +type Foreign_call_sqlContext struct { + Sql_function_callContext + dbid ISql_exprContext + procedure ISql_exprContext +} + +func NewForeign_call_sqlContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Foreign_call_sqlContext { + var p = new(Foreign_call_sqlContext) + + InitEmptySql_function_callContext(&p.Sql_function_callContext) + p.parser = parser + p.CopyAll(ctx.(*Sql_function_callContext)) + + return p +} + +func (s *Foreign_call_sqlContext) GetDbid() ISql_exprContext { return s.dbid } + +func (s *Foreign_call_sqlContext) GetProcedure() ISql_exprContext { return s.procedure } + +func (s *Foreign_call_sqlContext) SetDbid(v ISql_exprContext) { s.dbid = v } + +func (s *Foreign_call_sqlContext) SetProcedure(v ISql_exprContext) { s.procedure = v } + +func (s *Foreign_call_sqlContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Foreign_call_sqlContext) Identifier() IIdentifierContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIdentifierContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IIdentifierContext) +} + +func (s *Foreign_call_sqlContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *Foreign_call_sqlContext) COMMA() antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, 0) +} + +func (s *Foreign_call_sqlContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *Foreign_call_sqlContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Foreign_call_sqlContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Foreign_call_sqlContext) AllSql_expr() []ISql_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ISql_exprContext); ok { + len++ + } + } + + tst := make([]ISql_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ISql_exprContext); ok { + tst[i] = t.(ISql_exprContext) + i++ + } + } + + return tst +} + +func (s *Foreign_call_sqlContext) Sql_expr(i int) ISql_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ISql_exprContext) +} + +func (s *Foreign_call_sqlContext) Sql_expr_list() ISql_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_expr_listContext) +} + +func (s *Foreign_call_sqlContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitForeign_call_sql(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Sql_function_call() (localctx ISql_function_callContext) { + localctx = NewSql_function_callContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 88, KuneiformParserRULE_sql_function_call) + var _la int + + p.SetState(898) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 121, p.GetParserRuleContext()) { + case 1: + localctx = NewNormal_call_sqlContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(875) + p.Identifier() + } + { + p.SetState(876) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(882) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + switch p.GetTokenStream().LA(1) { + case KuneiformParserLPAREN, KuneiformParserPLUS, KuneiformParserMINUS, KuneiformParserDOUBLE_QUOTE, KuneiformParserNULL, KuneiformParserNOT, KuneiformParserEXISTS, KuneiformParserCASE, KuneiformParserDISTINCT, KuneiformParserSTRING_, KuneiformParserTRUE, KuneiformParserFALSE, KuneiformParserDIGITS_, KuneiformParserBINARY_, KuneiformParserIDENTIFIER, KuneiformParserVARIABLE, KuneiformParserCONTEXTUAL_VARIABLE: + p.SetState(878) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserDISTINCT { + { + p.SetState(877) + p.Match(KuneiformParserDISTINCT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(880) + p.Sql_expr_list() + } + + case KuneiformParserSTAR: + { + p.SetState(881) + p.Match(KuneiformParserSTAR) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case KuneiformParserRPAREN: + + default: + } + { + p.SetState(884) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 2: + localctx = NewForeign_call_sqlContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + { + p.SetState(886) + p.Identifier() + } + { + p.SetState(887) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(888) + + var _x = p.sql_expr(0) + + localctx.(*Foreign_call_sqlContext).dbid = _x + } + { + p.SetState(889) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(890) + + var _x = p.sql_expr(0) + + localctx.(*Foreign_call_sqlContext).procedure = _x + } + { + p.SetState(891) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(892) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(894) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2377900607549735040) != 0) || ((int64((_la-69)) & ^0x3f) == 0 && ((int64(1)<<(_la-69))&-2288391560656584703) != 0) { + { + p.SetState(893) + p.Sql_expr_list() + } + + } + { + p.SetState(896) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IAction_blockContext is an interface to support dynamic dispatch. +type IAction_blockContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllAction_statement() []IAction_statementContext + Action_statement(i int) IAction_statementContext + AllSCOL() []antlr.TerminalNode + SCOL(i int) antlr.TerminalNode + + // IsAction_blockContext differentiates from other interfaces. + IsAction_blockContext() +} + +type Action_blockContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyAction_blockContext() *Action_blockContext { + var p = new(Action_blockContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_block + return p +} + +func InitEmptyAction_blockContext(p *Action_blockContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_block +} + +func (*Action_blockContext) IsAction_blockContext() {} + +func NewAction_blockContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Action_blockContext { + var p = new(Action_blockContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_action_block + + return p +} + +func (s *Action_blockContext) GetParser() antlr.Parser { return s.parser } + +func (s *Action_blockContext) AllAction_statement() []IAction_statementContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IAction_statementContext); ok { + len++ + } + } + + tst := make([]IAction_statementContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IAction_statementContext); ok { + tst[i] = t.(IAction_statementContext) + i++ + } + } + + return tst +} + +func (s *Action_blockContext) Action_statement(i int) IAction_statementContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IAction_statementContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IAction_statementContext) +} + +func (s *Action_blockContext) AllSCOL() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserSCOL) +} + +func (s *Action_blockContext) SCOL(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, i) +} + +func (s *Action_blockContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Action_blockContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Action_blockContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitAction_block(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Action_block() (localctx IAction_blockContext) { + localctx = NewAction_blockContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 90, KuneiformParserRULE_action_block) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(905) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserDELETE || _la == KuneiformParserUPDATE || ((int64((_la-88)) & ^0x3f) == 0 && ((int64(1)<<(_la-88))&30786325579265) != 0) { + { + p.SetState(900) + p.Action_statement() + } + { + p.SetState(901) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + p.SetState(907) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IAction_statementContext is an interface to support dynamic dispatch. +type IAction_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsAction_statementContext differentiates from other interfaces. + IsAction_statementContext() +} + +type Action_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyAction_statementContext() *Action_statementContext { + var p = new(Action_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_statement + return p +} + +func InitEmptyAction_statementContext(p *Action_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_action_statement +} + +func (*Action_statementContext) IsAction_statementContext() {} + +func NewAction_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Action_statementContext { + var p = new(Action_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_action_statement + + return p +} + +func (s *Action_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Action_statementContext) CopyAll(ctx *Action_statementContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Action_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Action_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Extension_actionContext struct { + Action_statementContext +} + +func NewExtension_actionContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Extension_actionContext { + var p = new(Extension_actionContext) + + InitEmptyAction_statementContext(&p.Action_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Action_statementContext)) + + return p +} + +func (s *Extension_actionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Extension_actionContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserIDENTIFIER) +} + +func (s *Extension_actionContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, i) +} + +func (s *Extension_actionContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Extension_actionContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Extension_actionContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Extension_actionContext) Variable_list() IVariable_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariable_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVariable_listContext) +} + +func (s *Extension_actionContext) EQUALS() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUALS, 0) +} + +func (s *Extension_actionContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Extension_actionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitExtension_action(s) + + default: + return t.VisitChildren(s) + } +} + +type Local_actionContext struct { + Action_statementContext +} + +func NewLocal_actionContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Local_actionContext { + var p = new(Local_actionContext) + + InitEmptyAction_statementContext(&p.Action_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Action_statementContext)) + + return p +} + +func (s *Local_actionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Local_actionContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Local_actionContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Local_actionContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Local_actionContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Local_actionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitLocal_action(s) + + default: + return t.VisitChildren(s) + } +} + +type Sql_actionContext struct { + Action_statementContext +} + +func NewSql_actionContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Sql_actionContext { + var p = new(Sql_actionContext) + + InitEmptyAction_statementContext(&p.Action_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Action_statementContext)) + + return p +} + +func (s *Sql_actionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Sql_actionContext) Sql_statement() ISql_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_statementContext) +} + +func (s *Sql_actionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitSql_action(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Action_statement() (localctx IAction_statementContext) { + localctx = NewAction_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 92, KuneiformParserRULE_action_statement) + var _la int + + p.SetState(928) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 126, p.GetParserRuleContext()) { + case 1: + localctx = NewSql_actionContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(908) + p.Sql_statement() + } + + case 2: + localctx = NewLocal_actionContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + { + p.SetState(909) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(910) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(912) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&72057594041075848) != 0) || ((int64((_la-118)) & ^0x3f) == 0 && ((int64(1)<<(_la-118))&28703) != 0) { + { + p.SetState(911) + p.Procedure_expr_list() + } + + } + { + p.SetState(914) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 3: + localctx = NewExtension_actionContext(p, localctx) + p.EnterOuterAlt(localctx, 3) + p.SetState(918) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserVARIABLE || _la == KuneiformParserCONTEXTUAL_VARIABLE { + { + p.SetState(915) + p.Variable_list() + } + { + p.SetState(916) + p.Match(KuneiformParserEQUALS) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(920) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(921) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(922) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(923) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(925) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&72057594041075848) != 0) || ((int64((_la-118)) & ^0x3f) == 0 && ((int64(1)<<(_la-118))&28703) != 0) { + { + p.SetState(924) + p.Procedure_expr_list() + } + + } + { + p.SetState(927) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_blockContext is an interface to support dynamic dispatch. +type IProcedure_blockContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllProc_statement() []IProc_statementContext + Proc_statement(i int) IProc_statementContext + + // IsProcedure_blockContext differentiates from other interfaces. + IsProcedure_blockContext() +} + +type Procedure_blockContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProcedure_blockContext() *Procedure_blockContext { + var p = new(Procedure_blockContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_block + return p +} + +func InitEmptyProcedure_blockContext(p *Procedure_blockContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_block +} + +func (*Procedure_blockContext) IsProcedure_blockContext() {} + +func NewProcedure_blockContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_blockContext { + var p = new(Procedure_blockContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_block + + return p +} + +func (s *Procedure_blockContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_blockContext) AllProc_statement() []IProc_statementContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProc_statementContext); ok { + len++ + } + } + + tst := make([]IProc_statementContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProc_statementContext); ok { + tst[i] = t.(IProc_statementContext) + i++ + } + } + + return tst +} + +func (s *Procedure_blockContext) Proc_statement(i int) IProc_statementContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProc_statementContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProc_statementContext) +} + +func (s *Procedure_blockContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_blockContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Procedure_blockContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitProcedure_block(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_block() (localctx IProcedure_blockContext) { + localctx = NewProcedure_blockContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 94, KuneiformParserRULE_procedure_block) + var _la int + + p.EnterOuterAlt(localctx, 1) + p.SetState(933) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&432345564764438528) != 0) || ((int64((_la-88)) & ^0x3f) == 0 && ((int64(1)<<(_la-88))&13194567353857) != 0) { + { + p.SetState(930) + p.Proc_statement() + } + + p.SetState(935) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_exprContext is an interface to support dynamic dispatch. +type IProcedure_exprContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsProcedure_exprContext differentiates from other interfaces. + IsProcedure_exprContext() +} + +type Procedure_exprContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProcedure_exprContext() *Procedure_exprContext { + var p = new(Procedure_exprContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_expr + return p +} + +func InitEmptyProcedure_exprContext(p *Procedure_exprContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_expr +} + +func (*Procedure_exprContext) IsProcedure_exprContext() {} + +func NewProcedure_exprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_exprContext { + var p = new(Procedure_exprContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_expr + + return p +} + +func (s *Procedure_exprContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_exprContext) CopyAll(ctx *Procedure_exprContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_exprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Field_access_procedure_exprContext struct { + Procedure_exprContext +} + +func NewField_access_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Field_access_procedure_exprContext { + var p = new(Field_access_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Field_access_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Field_access_procedure_exprContext) Procedure_expr() IProcedure_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Field_access_procedure_exprContext) PERIOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserPERIOD, 0) +} + +func (s *Field_access_procedure_exprContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Field_access_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Field_access_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitField_access_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Literal_procedure_exprContext struct { + Procedure_exprContext +} + +func NewLiteral_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Literal_procedure_exprContext { + var p = new(Literal_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Literal_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Literal_procedure_exprContext) Literal() ILiteralContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILiteralContext) +} + +func (s *Literal_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Literal_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitLiteral_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Paren_procedure_exprContext struct { + Procedure_exprContext +} + +func NewParen_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Paren_procedure_exprContext { + var p = new(Paren_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Paren_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Paren_procedure_exprContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Paren_procedure_exprContext) Procedure_expr() IProcedure_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Paren_procedure_exprContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Paren_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Paren_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitParen_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Variable_procedure_exprContext struct { + Procedure_exprContext +} + +func NewVariable_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Variable_procedure_exprContext { + var p = new(Variable_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Variable_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Variable_procedure_exprContext) Variable() IVariableContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariableContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVariableContext) +} + +func (s *Variable_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Variable_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitVariable_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Make_array_procedure_exprContext struct { + Procedure_exprContext +} + +func NewMake_array_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Make_array_procedure_exprContext { + var p = new(Make_array_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Make_array_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Make_array_procedure_exprContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *Make_array_procedure_exprContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *Make_array_procedure_exprContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Make_array_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Make_array_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitMake_array_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Procedure_expr_arithmeticContext struct { + Procedure_exprContext +} + +func NewProcedure_expr_arithmeticContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Procedure_expr_arithmeticContext { + var p = new(Procedure_expr_arithmeticContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Procedure_expr_arithmeticContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_expr_arithmeticContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *Procedure_expr_arithmeticContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Procedure_expr_arithmeticContext) CONCAT() antlr.TerminalNode { + return s.GetToken(KuneiformParserCONCAT, 0) +} + +func (s *Procedure_expr_arithmeticContext) STAR() antlr.TerminalNode { + return s.GetToken(KuneiformParserSTAR, 0) +} + +func (s *Procedure_expr_arithmeticContext) DIV() antlr.TerminalNode { + return s.GetToken(KuneiformParserDIV, 0) +} + +func (s *Procedure_expr_arithmeticContext) MOD() antlr.TerminalNode { + return s.GetToken(KuneiformParserMOD, 0) +} + +func (s *Procedure_expr_arithmeticContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Procedure_expr_arithmeticContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Procedure_expr_arithmeticContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitProcedure_expr_arithmetic(s) + + default: + return t.VisitChildren(s) + } +} + +type Unary_procedure_exprContext struct { + Procedure_exprContext +} + +func NewUnary_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Unary_procedure_exprContext { + var p = new(Unary_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Unary_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Unary_procedure_exprContext) Procedure_expr() IProcedure_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Unary_procedure_exprContext) MINUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserMINUS, 0) +} + +func (s *Unary_procedure_exprContext) PLUS() antlr.TerminalNode { + return s.GetToken(KuneiformParserPLUS, 0) +} + +func (s *Unary_procedure_exprContext) EXCL() antlr.TerminalNode { + return s.GetToken(KuneiformParserEXCL, 0) +} + +func (s *Unary_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitUnary_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Comparison_procedure_exprContext struct { + Procedure_exprContext +} + +func NewComparison_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Comparison_procedure_exprContext { + var p = new(Comparison_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Comparison_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Comparison_procedure_exprContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *Comparison_procedure_exprContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Comparison_procedure_exprContext) EQUALS() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUALS, 0) +} + +func (s *Comparison_procedure_exprContext) EQUATE() antlr.TerminalNode { + return s.GetToken(KuneiformParserEQUATE, 0) +} + +func (s *Comparison_procedure_exprContext) NEQ() antlr.TerminalNode { + return s.GetToken(KuneiformParserNEQ, 0) +} + +func (s *Comparison_procedure_exprContext) LT() antlr.TerminalNode { + return s.GetToken(KuneiformParserLT, 0) +} + +func (s *Comparison_procedure_exprContext) LTE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLTE, 0) +} + +func (s *Comparison_procedure_exprContext) GT() antlr.TerminalNode { + return s.GetToken(KuneiformParserGT, 0) +} + +func (s *Comparison_procedure_exprContext) GTE() antlr.TerminalNode { + return s.GetToken(KuneiformParserGTE, 0) +} + +func (s *Comparison_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitComparison_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Function_call_procedure_exprContext struct { + Procedure_exprContext +} + +func NewFunction_call_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Function_call_procedure_exprContext { + var p = new(Function_call_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Function_call_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Function_call_procedure_exprContext) Procedure_function_call() IProcedure_function_callContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_function_callContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_function_callContext) +} + +func (s *Function_call_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Function_call_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitFunction_call_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +type Array_access_procedure_exprContext struct { + Procedure_exprContext +} + +func NewArray_access_procedure_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Array_access_procedure_exprContext { + var p = new(Array_access_procedure_exprContext) + + InitEmptyProcedure_exprContext(&p.Procedure_exprContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_exprContext)) + + return p +} + +func (s *Array_access_procedure_exprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Array_access_procedure_exprContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *Array_access_procedure_exprContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Array_access_procedure_exprContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *Array_access_procedure_exprContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *Array_access_procedure_exprContext) Type_cast() IType_castContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IType_castContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IType_castContext) +} + +func (s *Array_access_procedure_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitArray_access_procedure_expr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_expr() (localctx IProcedure_exprContext) { + return p.procedure_expr(0) +} + +func (p *KuneiformParser) procedure_expr(_p int) (localctx IProcedure_exprContext) { + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + + _parentState := p.GetState() + localctx = NewProcedure_exprContext(p, p.GetParserRuleContext(), _parentState) + var _prevctx IProcedure_exprContext = localctx + var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. + _startState := 96 + p.EnterRecursionRule(localctx, 96, KuneiformParserRULE_procedure_expr, _p) + var _la int + + var _alt int + + p.EnterOuterAlt(localctx, 1) + p.SetState(965) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 134, p.GetParserRuleContext()) { + case 1: + localctx = NewLiteral_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + + { + p.SetState(937) + p.Literal() + } + p.SetState(939) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 128, p.GetParserRuleContext()) == 1 { + { + p.SetState(938) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 2: + localctx = NewFunction_call_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(941) + p.Procedure_function_call() + } + p.SetState(943) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 129, p.GetParserRuleContext()) == 1 { + { + p.SetState(942) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 3: + localctx = NewVariable_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(945) + p.Variable() + } + p.SetState(947) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 130, p.GetParserRuleContext()) == 1 { + { + p.SetState(946) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 4: + localctx = NewMake_array_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(949) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(951) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&72057594041075848) != 0) || ((int64((_la-118)) & ^0x3f) == 0 && ((int64(1)<<(_la-118))&28703) != 0) { + { + p.SetState(950) + p.Procedure_expr_list() + } + + } + { + p.SetState(953) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(955) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 132, p.GetParserRuleContext()) == 1 { + { + p.SetState(954) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 5: + localctx = NewParen_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(957) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(958) + p.procedure_expr(0) + } + { + p.SetState(959) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(961) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 133, p.GetParserRuleContext()) == 1 { + { + p.SetState(960) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 6: + localctx = NewUnary_procedure_exprContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(963) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&3147776) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(964) + p.procedure_expr(4) + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(994) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 138, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + if p.GetParseListeners() != nil { + p.TriggerExitRuleEvent() + } + _prevctx = localctx + p.SetState(992) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 137, p.GetParserRuleContext()) { + case 1: + localctx = NewComparison_procedure_exprContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(967) + + if !(p.Precpred(p.GetParserRuleContext(), 5)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) + goto errorExit + } + { + p.SetState(968) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&260145152) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(969) + p.procedure_expr(6) + } + + case 2: + localctx = NewProcedure_expr_arithmeticContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(970) + + if !(p.Precpred(p.GetParserRuleContext(), 3)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) + goto errorExit + } + { + p.SetState(971) + p.Match(KuneiformParserCONCAT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(972) + p.procedure_expr(4) + } + + case 3: + localctx = NewProcedure_expr_arithmeticContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(973) + + if !(p.Precpred(p.GetParserRuleContext(), 2)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + goto errorExit + } + { + p.SetState(974) + _la = p.GetTokenStream().LA(1) + + if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4734976) != 0) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(975) + p.procedure_expr(3) + } + + case 4: + localctx = NewProcedure_expr_arithmeticContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(976) + + if !(p.Precpred(p.GetParserRuleContext(), 1)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) + goto errorExit + } + { + p.SetState(977) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserPLUS || _la == KuneiformParserMINUS) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(978) + p.procedure_expr(2) + } + + case 5: + localctx = NewArray_access_procedure_exprContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(979) + + if !(p.Precpred(p.GetParserRuleContext(), 8)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) + goto errorExit + } + { + p.SetState(980) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(981) + p.procedure_expr(0) + } + { + p.SetState(982) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(984) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 135, p.GetParserRuleContext()) == 1 { + { + p.SetState(983) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case 6: + localctx = NewField_access_procedure_exprContext(p, NewProcedure_exprContext(p, _parentctx, _parentState)) + p.PushNewRecursionContext(localctx, _startState, KuneiformParserRULE_procedure_expr) + p.SetState(986) + + if !(p.Precpred(p.GetParserRuleContext(), 6)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) + goto errorExit + } + { + p.SetState(987) + p.Match(KuneiformParserPERIOD) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(988) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(990) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 136, p.GetParserRuleContext()) == 1 { + { + p.SetState(989) + p.Type_cast() + } + + } else if p.HasError() { // JIM + goto errorExit + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + + } + p.SetState(996) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 138, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.UnrollRecursionContexts(_parentctx) + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_expr_listContext is an interface to support dynamic dispatch. +type IProcedure_expr_listContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllProcedure_expr() []IProcedure_exprContext + Procedure_expr(i int) IProcedure_exprContext + AllCOMMA() []antlr.TerminalNode + COMMA(i int) antlr.TerminalNode + + // IsProcedure_expr_listContext differentiates from other interfaces. + IsProcedure_expr_listContext() +} + +type Procedure_expr_listContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProcedure_expr_listContext() *Procedure_expr_listContext { + var p = new(Procedure_expr_listContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_expr_list + return p +} + +func InitEmptyProcedure_expr_listContext(p *Procedure_expr_listContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_expr_list +} + +func (*Procedure_expr_listContext) IsProcedure_expr_listContext() {} + +func NewProcedure_expr_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_expr_listContext { + var p = new(Procedure_expr_listContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_expr_list + + return p +} + +func (s *Procedure_expr_listContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_expr_listContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *Procedure_expr_listContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Procedure_expr_listContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Procedure_expr_listContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Procedure_expr_listContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_expr_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Procedure_expr_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitProcedure_expr_list(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_expr_list() (localctx IProcedure_expr_listContext) { + localctx = NewProcedure_expr_listContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 98, KuneiformParserRULE_procedure_expr_list) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(997) + p.procedure_expr(0) + } + p.SetState(1002) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(998) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(999) + p.procedure_expr(0) + } + + p.SetState(1004) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProc_statementContext is an interface to support dynamic dispatch. +type IProc_statementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsProc_statementContext differentiates from other interfaces. + IsProc_statementContext() +} + +type Proc_statementContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProc_statementContext() *Proc_statementContext { + var p = new(Proc_statementContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_proc_statement + return p +} + +func InitEmptyProc_statementContext(p *Proc_statementContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_proc_statement +} + +func (*Proc_statementContext) IsProc_statementContext() {} + +func NewProc_statementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Proc_statementContext { + var p = new(Proc_statementContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_proc_statement + + return p +} + +func (s *Proc_statementContext) GetParser() antlr.Parser { return s.parser } + +func (s *Proc_statementContext) CopyAll(ctx *Proc_statementContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Proc_statementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Proc_statementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Stmt_ifContext struct { + Proc_statementContext +} + +func NewStmt_ifContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_ifContext { + var p = new(Stmt_ifContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_ifContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_ifContext) IF() antlr.TerminalNode { + return s.GetToken(KuneiformParserIF, 0) +} + +func (s *Stmt_ifContext) AllIf_then_block() []IIf_then_blockContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IIf_then_blockContext); ok { + len++ + } + } + + tst := make([]IIf_then_blockContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IIf_then_blockContext); ok { + tst[i] = t.(IIf_then_blockContext) + i++ + } + } + + return tst +} + +func (s *Stmt_ifContext) If_then_block(i int) IIf_then_blockContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IIf_then_blockContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IIf_then_blockContext) +} + +func (s *Stmt_ifContext) AllELSEIF() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserELSEIF) +} + +func (s *Stmt_ifContext) ELSEIF(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserELSEIF, i) +} + +func (s *Stmt_ifContext) ELSE() antlr.TerminalNode { + return s.GetToken(KuneiformParserELSE, 0) +} + +func (s *Stmt_ifContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Stmt_ifContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Stmt_ifContext) AllProc_statement() []IProc_statementContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProc_statementContext); ok { + len++ + } + } + + tst := make([]IProc_statementContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProc_statementContext); ok { + tst[i] = t.(IProc_statementContext) + i++ + } + } + + return tst +} + +func (s *Stmt_ifContext) Proc_statement(i int) IProc_statementContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProc_statementContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProc_statementContext) +} + +func (s *Stmt_ifContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_if(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_breakContext struct { + Proc_statementContext +} + +func NewStmt_breakContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_breakContext { + var p = new(Stmt_breakContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_breakContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_breakContext) BREAK() antlr.TerminalNode { + return s.GetToken(KuneiformParserBREAK, 0) +} + +func (s *Stmt_breakContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_breakContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_break(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_variable_declarationContext struct { + Proc_statementContext +} + +func NewStmt_variable_declarationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_variable_declarationContext { + var p = new(Stmt_variable_declarationContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_variable_declarationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_variable_declarationContext) VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserVARIABLE, 0) +} + +func (s *Stmt_variable_declarationContext) Type_() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Stmt_variable_declarationContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_variable_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_variable_declaration(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_return_nextContext struct { + Proc_statementContext +} + +func NewStmt_return_nextContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_return_nextContext { + var p = new(Stmt_return_nextContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_return_nextContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_return_nextContext) RETURN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRETURN, 0) +} + +func (s *Stmt_return_nextContext) NEXT() antlr.TerminalNode { + return s.GetToken(KuneiformParserNEXT, 0) +} + +func (s *Stmt_return_nextContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Stmt_return_nextContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_return_nextContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_return_next(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_for_loopContext struct { + Proc_statementContext + receiver antlr.Token + target_variable IVariableContext +} + +func NewStmt_for_loopContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_for_loopContext { + var p = new(Stmt_for_loopContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_for_loopContext) GetReceiver() antlr.Token { return s.receiver } + +func (s *Stmt_for_loopContext) SetReceiver(v antlr.Token) { s.receiver = v } + +func (s *Stmt_for_loopContext) GetTarget_variable() IVariableContext { return s.target_variable } + +func (s *Stmt_for_loopContext) SetTarget_variable(v IVariableContext) { s.target_variable = v } + +func (s *Stmt_for_loopContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_for_loopContext) FOR() antlr.TerminalNode { + return s.GetToken(KuneiformParserFOR, 0) +} + +func (s *Stmt_for_loopContext) IN() antlr.TerminalNode { + return s.GetToken(KuneiformParserIN, 0) +} + +func (s *Stmt_for_loopContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *Stmt_for_loopContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *Stmt_for_loopContext) VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserVARIABLE, 0) +} + +func (s *Stmt_for_loopContext) Range_() IRangeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRangeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IRangeContext) +} + +func (s *Stmt_for_loopContext) Sql_statement() ISql_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_statementContext) +} + +func (s *Stmt_for_loopContext) Variable() IVariableContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariableContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVariableContext) +} + +func (s *Stmt_for_loopContext) AllProc_statement() []IProc_statementContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProc_statementContext); ok { + len++ + } + } + + tst := make([]IProc_statementContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProc_statementContext); ok { + tst[i] = t.(IProc_statementContext) + i++ + } + } + + return tst +} + +func (s *Stmt_for_loopContext) Proc_statement(i int) IProc_statementContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProc_statementContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProc_statementContext) +} + +func (s *Stmt_for_loopContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_for_loop(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_returnContext struct { + Proc_statementContext +} + +func NewStmt_returnContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_returnContext { + var p = new(Stmt_returnContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_returnContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_returnContext) RETURN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRETURN, 0) +} + +func (s *Stmt_returnContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_returnContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Stmt_returnContext) Sql_statement() ISql_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_statementContext) +} + +func (s *Stmt_returnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_return(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_procedure_callContext struct { + Proc_statementContext +} + +func NewStmt_procedure_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_procedure_callContext { + var p = new(Stmt_procedure_callContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_procedure_callContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_procedure_callContext) Procedure_function_call() IProcedure_function_callContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_function_callContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_function_callContext) +} + +func (s *Stmt_procedure_callContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_procedure_callContext) ASSIGN() antlr.TerminalNode { + return s.GetToken(KuneiformParserASSIGN, 0) +} + +func (s *Stmt_procedure_callContext) AllVariable_or_underscore() []IVariable_or_underscoreContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IVariable_or_underscoreContext); ok { + len++ + } + } + + tst := make([]IVariable_or_underscoreContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IVariable_or_underscoreContext); ok { + tst[i] = t.(IVariable_or_underscoreContext) + i++ + } + } + + return tst +} + +func (s *Stmt_procedure_callContext) Variable_or_underscore(i int) IVariable_or_underscoreContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVariable_or_underscoreContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IVariable_or_underscoreContext) +} + +func (s *Stmt_procedure_callContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(KuneiformParserCOMMA) +} + +func (s *Stmt_procedure_callContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, i) +} + +func (s *Stmt_procedure_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_procedure_call(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_variable_assignmentContext struct { + Proc_statementContext +} + +func NewStmt_variable_assignmentContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_variable_assignmentContext { + var p = new(Stmt_variable_assignmentContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_variable_assignmentContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_variable_assignmentContext) VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserVARIABLE, 0) +} + +func (s *Stmt_variable_assignmentContext) ASSIGN() antlr.TerminalNode { + return s.GetToken(KuneiformParserASSIGN, 0) +} + +func (s *Stmt_variable_assignmentContext) Procedure_expr() IProcedure_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Stmt_variable_assignmentContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_variable_assignmentContext) Type_() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *Stmt_variable_assignmentContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_variable_assignment(s) + + default: + return t.VisitChildren(s) + } +} + +type Stmt_sqlContext struct { + Proc_statementContext +} + +func NewStmt_sqlContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_sqlContext { + var p = new(Stmt_sqlContext) + + InitEmptyProc_statementContext(&p.Proc_statementContext) + p.parser = parser + p.CopyAll(ctx.(*Proc_statementContext)) + + return p +} + +func (s *Stmt_sqlContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Stmt_sqlContext) Sql_statement() ISql_statementContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISql_statementContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISql_statementContext) +} + +func (s *Stmt_sqlContext) SCOL() antlr.TerminalNode { + return s.GetToken(KuneiformParserSCOL, 0) +} + +func (s *Stmt_sqlContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitStmt_sql(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Proc_statement() (localctx IProc_statementContext) { + localctx = NewProc_statementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 100, KuneiformParserRULE_proc_statement) + var _la int + + p.SetState(1086) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 149, p.GetParserRuleContext()) { + case 1: + localctx = NewStmt_variable_declarationContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(1005) + p.Match(KuneiformParserVARIABLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1006) + p.Type_() + } + { + p.SetState(1007) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 2: + localctx = NewStmt_procedure_callContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + p.SetState(1019) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserUNDERSCORE || _la == KuneiformParserVARIABLE { + { + p.SetState(1009) + p.Variable_or_underscore() + } + + p.SetState(1014) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserCOMMA { + { + p.SetState(1010) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + { + p.SetState(1011) + p.Variable_or_underscore() + } + + p.SetState(1016) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(1017) + p.Match(KuneiformParserASSIGN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + { + p.SetState(1021) + p.Procedure_function_call() + } + { + p.SetState(1022) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 3: + localctx = NewStmt_variable_assignmentContext(p, localctx) + p.EnterOuterAlt(localctx, 3) + { + p.SetState(1024) + p.Match(KuneiformParserVARIABLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1026) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserIDENTIFIER { + { + p.SetState(1025) + p.Type_() + } + + } + { + p.SetState(1028) + p.Match(KuneiformParserASSIGN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1029) + p.procedure_expr(0) + } + { + p.SetState(1030) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 4: + localctx = NewStmt_for_loopContext(p, localctx) + p.EnterOuterAlt(localctx, 4) + { + p.SetState(1032) + p.Match(KuneiformParserFOR) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1033) + + var _m = p.Match(KuneiformParserVARIABLE) + + localctx.(*Stmt_for_loopContext).receiver = _m + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1034) + p.Match(KuneiformParserIN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1038) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 143, p.GetParserRuleContext()) { + case 1: + { + p.SetState(1035) + p.Range_() + } + + case 2: + { + p.SetState(1036) + + var _x = p.Variable() + + localctx.(*Stmt_for_loopContext).target_variable = _x + } + + case 3: + { + p.SetState(1037) + p.Sql_statement() + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + { + p.SetState(1040) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1044) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&432345564764438528) != 0) || ((int64((_la-88)) & ^0x3f) == 0 && ((int64(1)<<(_la-88))&13194567353857) != 0) { + { + p.SetState(1041) + p.Proc_statement() + } + + p.SetState(1046) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(1047) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 5: + localctx = NewStmt_ifContext(p, localctx) + p.EnterOuterAlt(localctx, 5) + { + p.SetState(1049) + p.Match(KuneiformParserIF) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1050) + p.If_then_block() + } + p.SetState(1055) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for _la == KuneiformParserELSEIF { + { + p.SetState(1051) + p.Match(KuneiformParserELSEIF) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1052) + p.If_then_block() + } + + p.SetState(1057) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + p.SetState(1067) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == KuneiformParserELSE { + { + p.SetState(1058) + p.Match(KuneiformParserELSE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1059) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1063) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&432345564764438528) != 0) || ((int64((_la-88)) & ^0x3f) == 0 && ((int64(1)<<(_la-88))&13194567353857) != 0) { + { + p.SetState(1060) + p.Proc_statement() + } + + p.SetState(1065) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(1066) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + } + + case 6: + localctx = NewStmt_sqlContext(p, localctx) + p.EnterOuterAlt(localctx, 6) + { + p.SetState(1069) + p.Sql_statement() + } + { + p.SetState(1070) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 7: + localctx = NewStmt_breakContext(p, localctx) + p.EnterOuterAlt(localctx, 7) + { + p.SetState(1072) + p.Match(KuneiformParserBREAK) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1073) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 8: + localctx = NewStmt_returnContext(p, localctx) + p.EnterOuterAlt(localctx, 8) + { + p.SetState(1074) + p.Match(KuneiformParserRETURN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1077) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetTokenStream().LA(1) { + case KuneiformParserLBRACKET, KuneiformParserLPAREN, KuneiformParserEXCL, KuneiformParserPLUS, KuneiformParserMINUS, KuneiformParserNULL, KuneiformParserSTRING_, KuneiformParserTRUE, KuneiformParserFALSE, KuneiformParserDIGITS_, KuneiformParserBINARY_, KuneiformParserIDENTIFIER, KuneiformParserVARIABLE, KuneiformParserCONTEXTUAL_VARIABLE: + { + p.SetState(1075) + p.Procedure_expr_list() + } + + case KuneiformParserDELETE, KuneiformParserUPDATE, KuneiformParserWITH, KuneiformParserSELECT, KuneiformParserINSERT: + { + p.SetState(1076) + p.Sql_statement() + } + + default: + p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + goto errorExit + } + { + p.SetState(1079) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 9: + localctx = NewStmt_return_nextContext(p, localctx) + p.EnterOuterAlt(localctx, 9) + { + p.SetState(1081) + p.Match(KuneiformParserRETURN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1082) + p.Match(KuneiformParserNEXT) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1083) + p.Procedure_expr_list() + } + { + p.SetState(1084) + p.Match(KuneiformParserSCOL) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IVariable_or_underscoreContext is an interface to support dynamic dispatch. +type IVariable_or_underscoreContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + VARIABLE() antlr.TerminalNode + UNDERSCORE() antlr.TerminalNode + + // IsVariable_or_underscoreContext differentiates from other interfaces. + IsVariable_or_underscoreContext() +} + +type Variable_or_underscoreContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyVariable_or_underscoreContext() *Variable_or_underscoreContext { + var p = new(Variable_or_underscoreContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable_or_underscore + return p +} + +func InitEmptyVariable_or_underscoreContext(p *Variable_or_underscoreContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_variable_or_underscore +} + +func (*Variable_or_underscoreContext) IsVariable_or_underscoreContext() {} + +func NewVariable_or_underscoreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Variable_or_underscoreContext { + var p = new(Variable_or_underscoreContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_variable_or_underscore + + return p +} + +func (s *Variable_or_underscoreContext) GetParser() antlr.Parser { return s.parser } + +func (s *Variable_or_underscoreContext) VARIABLE() antlr.TerminalNode { + return s.GetToken(KuneiformParserVARIABLE, 0) +} + +func (s *Variable_or_underscoreContext) UNDERSCORE() antlr.TerminalNode { + return s.GetToken(KuneiformParserUNDERSCORE, 0) +} + +func (s *Variable_or_underscoreContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Variable_or_underscoreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *Variable_or_underscoreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitVariable_or_underscore(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Variable_or_underscore() (localctx IVariable_or_underscoreContext) { + localctx = NewVariable_or_underscoreContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 102, KuneiformParserRULE_variable_or_underscore) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(1088) + _la = p.GetTokenStream().LA(1) + + if !(_la == KuneiformParserUNDERSCORE || _la == KuneiformParserVARIABLE) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IProcedure_function_callContext is an interface to support dynamic dispatch. +type IProcedure_function_callContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + // IsProcedure_function_callContext differentiates from other interfaces. + IsProcedure_function_callContext() +} + +type Procedure_function_callContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyProcedure_function_callContext() *Procedure_function_callContext { + var p = new(Procedure_function_callContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_function_call + return p +} + +func InitEmptyProcedure_function_callContext(p *Procedure_function_callContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_procedure_function_call +} + +func (*Procedure_function_callContext) IsProcedure_function_callContext() {} + +func NewProcedure_function_callContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_function_callContext { + var p = new(Procedure_function_callContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_procedure_function_call + + return p +} + +func (s *Procedure_function_callContext) GetParser() antlr.Parser { return s.parser } + +func (s *Procedure_function_callContext) CopyAll(ctx *Procedure_function_callContext) { + s.CopyFrom(&ctx.BaseParserRuleContext) +} + +func (s *Procedure_function_callContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Procedure_function_callContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +type Foreign_call_procedureContext struct { + Procedure_function_callContext + dbid IProcedure_exprContext + procedure IProcedure_exprContext +} + +func NewForeign_call_procedureContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Foreign_call_procedureContext { + var p = new(Foreign_call_procedureContext) + + InitEmptyProcedure_function_callContext(&p.Procedure_function_callContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_function_callContext)) + + return p +} + +func (s *Foreign_call_procedureContext) GetDbid() IProcedure_exprContext { return s.dbid } + +func (s *Foreign_call_procedureContext) GetProcedure() IProcedure_exprContext { return s.procedure } + +func (s *Foreign_call_procedureContext) SetDbid(v IProcedure_exprContext) { s.dbid = v } + +func (s *Foreign_call_procedureContext) SetProcedure(v IProcedure_exprContext) { s.procedure = v } + +func (s *Foreign_call_procedureContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Foreign_call_procedureContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Foreign_call_procedureContext) LBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACKET, 0) +} + +func (s *Foreign_call_procedureContext) COMMA() antlr.TerminalNode { + return s.GetToken(KuneiformParserCOMMA, 0) +} + +func (s *Foreign_call_procedureContext) RBRACKET() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACKET, 0) +} + +func (s *Foreign_call_procedureContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Foreign_call_procedureContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Foreign_call_procedureContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *Foreign_call_procedureContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *Foreign_call_procedureContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Foreign_call_procedureContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitForeign_call_procedure(s) + + default: + return t.VisitChildren(s) + } +} + +type Normal_call_procedureContext struct { + Procedure_function_callContext +} + +func NewNormal_call_procedureContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Normal_call_procedureContext { + var p = new(Normal_call_procedureContext) + + InitEmptyProcedure_function_callContext(&p.Procedure_function_callContext) + p.parser = parser + p.CopyAll(ctx.(*Procedure_function_callContext)) + + return p +} + +func (s *Normal_call_procedureContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *Normal_call_procedureContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(KuneiformParserIDENTIFIER, 0) +} + +func (s *Normal_call_procedureContext) LPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserLPAREN, 0) +} + +func (s *Normal_call_procedureContext) RPAREN() antlr.TerminalNode { + return s.GetToken(KuneiformParserRPAREN, 0) +} + +func (s *Normal_call_procedureContext) Procedure_expr_list() IProcedure_expr_listContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_expr_listContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_expr_listContext) +} + +func (s *Normal_call_procedureContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitNormal_call_procedure(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Procedure_function_call() (localctx IProcedure_function_callContext) { + localctx = NewProcedure_function_callContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 104, KuneiformParserRULE_procedure_function_call) + var _la int + + p.SetState(1108) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + + switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 152, p.GetParserRuleContext()) { + case 1: + localctx = NewNormal_call_procedureContext(p, localctx) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(1090) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1091) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1093) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&72057594041075848) != 0) || ((int64((_la-118)) & ^0x3f) == 0 && ((int64(1)<<(_la-118))&28703) != 0) { + { + p.SetState(1092) + p.Procedure_expr_list() + } + + } + { + p.SetState(1095) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 2: + localctx = NewForeign_call_procedureContext(p, localctx) + p.EnterOuterAlt(localctx, 2) + { + p.SetState(1096) + p.Match(KuneiformParserIDENTIFIER) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1097) + p.Match(KuneiformParserLBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1098) + + var _x = p.procedure_expr(0) + + localctx.(*Foreign_call_procedureContext).dbid = _x + } + { + p.SetState(1099) + p.Match(KuneiformParserCOMMA) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1100) + + var _x = p.procedure_expr(0) + + localctx.(*Foreign_call_procedureContext).procedure = _x + } + { + p.SetState(1101) + p.Match(KuneiformParserRBRACKET) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1102) + p.Match(KuneiformParserLPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1104) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&72057594041075848) != 0) || ((int64((_la-118)) & ^0x3f) == 0 && ((int64(1)<<(_la-118))&28703) != 0) { + { + p.SetState(1103) + p.Procedure_expr_list() + } + + } + { + p.SetState(1106) + p.Match(KuneiformParserRPAREN) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case antlr.ATNInvalidAltNumber: + goto errorExit + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IIf_then_blockContext is an interface to support dynamic dispatch. +type IIf_then_blockContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Procedure_expr() IProcedure_exprContext + LBRACE() antlr.TerminalNode + RBRACE() antlr.TerminalNode + AllProc_statement() []IProc_statementContext + Proc_statement(i int) IProc_statementContext + + // IsIf_then_blockContext differentiates from other interfaces. + IsIf_then_blockContext() +} + +type If_then_blockContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyIf_then_blockContext() *If_then_blockContext { + var p = new(If_then_blockContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_if_then_block + return p +} + +func InitEmptyIf_then_blockContext(p *If_then_blockContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_if_then_block +} + +func (*If_then_blockContext) IsIf_then_blockContext() {} + +func NewIf_then_blockContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *If_then_blockContext { + var p = new(If_then_blockContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_if_then_block + + return p +} + +func (s *If_then_blockContext) GetParser() antlr.Parser { return s.parser } + +func (s *If_then_blockContext) Procedure_expr() IProcedure_exprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *If_then_blockContext) LBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserLBRACE, 0) +} + +func (s *If_then_blockContext) RBRACE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRBRACE, 0) +} + +func (s *If_then_blockContext) AllProc_statement() []IProc_statementContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProc_statementContext); ok { + len++ + } + } + + tst := make([]IProc_statementContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProc_statementContext); ok { + tst[i] = t.(IProc_statementContext) + i++ + } + } + + return tst +} + +func (s *If_then_blockContext) Proc_statement(i int) IProc_statementContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProc_statementContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProc_statementContext) +} + +func (s *If_then_blockContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *If_then_blockContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *If_then_blockContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitIf_then_block(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) If_then_block() (localctx IIf_then_blockContext) { + localctx = NewIf_then_blockContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 106, KuneiformParserRULE_if_then_block) + var _la int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(1110) + p.procedure_expr(0) + } + { + p.SetState(1111) + p.Match(KuneiformParserLBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(1115) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&432345564764438528) != 0) || ((int64((_la-88)) & ^0x3f) == 0 && ((int64(1)<<(_la-88))&13194567353857) != 0) { + { + p.SetState(1112) + p.Proc_statement() + } + + p.SetState(1117) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(1118) + p.Match(KuneiformParserRBRACE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +// IRangeContext is an interface to support dynamic dispatch. +type IRangeContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + AllProcedure_expr() []IProcedure_exprContext + Procedure_expr(i int) IProcedure_exprContext + RANGE() antlr.TerminalNode + + // IsRangeContext differentiates from other interfaces. + IsRangeContext() +} + +type RangeContext struct { + antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyRangeContext() *RangeContext { + var p = new(RangeContext) + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_range + return p +} + +func InitEmptyRangeContext(p *RangeContext) { + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) + p.RuleIndex = KuneiformParserRULE_range +} + +func (*RangeContext) IsRangeContext() {} + +func NewRangeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RangeContext { + var p = new(RangeContext) + + antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) + + p.parser = parser + p.RuleIndex = KuneiformParserRULE_range + + return p +} + +func (s *RangeContext) GetParser() antlr.Parser { return s.parser } + +func (s *RangeContext) AllProcedure_expr() []IProcedure_exprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IProcedure_exprContext); ok { + len++ + } + } + + tst := make([]IProcedure_exprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IProcedure_exprContext); ok { + tst[i] = t.(IProcedure_exprContext) + i++ + } + } + + return tst +} + +func (s *RangeContext) Procedure_expr(i int) IProcedure_exprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IProcedure_exprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IProcedure_exprContext) +} + +func (s *RangeContext) RANGE() antlr.TerminalNode { + return s.GetToken(KuneiformParserRANGE, 0) +} + +func (s *RangeContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *RangeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *RangeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case KuneiformParserVisitor: + return t.VisitRange(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *KuneiformParser) Range_() (localctx IRangeContext) { + localctx = NewRangeContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 108, KuneiformParserRULE_range) + p.EnterOuterAlt(localctx, 1) + { + p.SetState(1120) + p.procedure_expr(0) + } + { + p.SetState(1121) + p.Match(KuneiformParserRANGE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(1122) + p.procedure_expr(0) + } + +errorExit: + if p.HasError() { + v := p.GetError() + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + p.SetError(nil) + } + p.ExitRule() + return localctx + goto errorExit // Trick to prevent compiler error if the label is not used +} + +func (p *KuneiformParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { + switch ruleIndex { + case 41: + var t *Sql_exprContext = nil + if localctx != nil { + t = localctx.(*Sql_exprContext) + } + return p.Sql_expr_Sempred(t, predIndex) + + case 48: + var t *Procedure_exprContext = nil + if localctx != nil { + t = localctx.(*Procedure_exprContext) + } + return p.Procedure_expr_Sempred(t, predIndex) + + default: + panic("No predicate with index: " + fmt.Sprint(ruleIndex)) + } +} + +func (p *KuneiformParser) Sql_expr_Sempred(localctx antlr.RuleContext, predIndex int) bool { + switch predIndex { + case 0: + return p.Precpred(p.GetParserRuleContext(), 13) + + case 1: + return p.Precpred(p.GetParserRuleContext(), 11) + + case 2: + return p.Precpred(p.GetParserRuleContext(), 9) + + case 3: + return p.Precpred(p.GetParserRuleContext(), 5) + + case 4: + return p.Precpred(p.GetParserRuleContext(), 4) + + case 5: + return p.Precpred(p.GetParserRuleContext(), 3) + + case 6: + return p.Precpred(p.GetParserRuleContext(), 2) + + case 7: + return p.Precpred(p.GetParserRuleContext(), 1) + + case 8: + return p.Precpred(p.GetParserRuleContext(), 20) + + case 9: + return p.Precpred(p.GetParserRuleContext(), 16) + + case 10: + return p.Precpred(p.GetParserRuleContext(), 15) + + case 11: + return p.Precpred(p.GetParserRuleContext(), 12) + + case 12: + return p.Precpred(p.GetParserRuleContext(), 8) + + default: + panic("No predicate with index: " + fmt.Sprint(predIndex)) + } +} + +func (p *KuneiformParser) Procedure_expr_Sempred(localctx antlr.RuleContext, predIndex int) bool { + switch predIndex { + case 13: + return p.Precpred(p.GetParserRuleContext(), 5) + + case 14: + return p.Precpred(p.GetParserRuleContext(), 3) + + case 15: + return p.Precpred(p.GetParserRuleContext(), 2) + + case 16: + return p.Precpred(p.GetParserRuleContext(), 1) + + case 17: + return p.Precpred(p.GetParserRuleContext(), 8) + + case 18: + return p.Precpred(p.GetParserRuleContext(), 6) + + default: + panic("No predicate with index: " + fmt.Sprint(predIndex)) + } +} diff --git a/parse/gen/kuneiformparser_base_visitor.go b/parse/gen/kuneiformparser_base_visitor.go new file mode 100644 index 000000000..af422e19f --- /dev/null +++ b/parse/gen/kuneiformparser_base_visitor.go @@ -0,0 +1,440 @@ +// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. + +package gen // KuneiformParser +import "github.com/antlr4-go/antlr/v4" + +type BaseKuneiformParserVisitor struct { + *antlr.BaseParseTreeVisitor +} + +func (v *BaseKuneiformParserVisitor) VisitEntry(ctx *EntryContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitString_literal(ctx *String_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitInteger_literal(ctx *Integer_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitDecimal_literal(ctx *Decimal_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitBoolean_literal(ctx *Boolean_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitNull_literal(ctx *Null_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitBinary_literal(ctx *Binary_literalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIdentifier_list(ctx *Identifier_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitType(ctx *TypeContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitType_cast(ctx *Type_castContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitVariable(ctx *VariableContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitVariable_list(ctx *Variable_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSchema(ctx *SchemaContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitAnnotation(ctx *AnnotationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitDatabase_declaration(ctx *Database_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUse_declaration(ctx *Use_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitTable_declaration(ctx *Table_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitColumn_def(ctx *Column_defContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIndex_def(ctx *Index_defContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitForeign_key_def(ctx *Foreign_key_defContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitForeign_key_action(ctx *Foreign_key_actionContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitType_list(ctx *Type_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitNamed_type_list(ctx *Named_type_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitTyped_variable_list(ctx *Typed_variable_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitMin_constraint(ctx *Min_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitMax_constraint(ctx *Max_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitMin_len_constraint(ctx *Min_len_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitMax_len_constraint(ctx *Max_len_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitNot_null_constraint(ctx *Not_null_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitPrimary_key_constraint(ctx *Primary_key_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitDefault_constraint(ctx *Default_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUnique_constraint(ctx *Unique_constraintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitAccess_modifier(ctx *Access_modifierContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitAction_declaration(ctx *Action_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitProcedure_declaration(ctx *Procedure_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitForeign_procedure_declaration(ctx *Foreign_procedure_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitProcedure_return(ctx *Procedure_returnContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSql(ctx *SqlContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSql_statement(ctx *Sql_statementContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitCommon_table_expression(ctx *Common_table_expressionContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSelect_statement(ctx *Select_statementContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitCompound_operator(ctx *Compound_operatorContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitOrdering_term(ctx *Ordering_termContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSelect_core(ctx *Select_coreContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitTable_relation(ctx *Table_relationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSubquery_relation(ctx *Subquery_relationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitFunction_relation(ctx *Function_relationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitJoin(ctx *JoinContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitExpression_result_column(ctx *Expression_result_columnContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitWildcard_result_column(ctx *Wildcard_result_columnContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUpdate_statement(ctx *Update_statementContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUpdate_set_clause(ctx *Update_set_clauseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitInsert_statement(ctx *Insert_statementContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUpsert_clause(ctx *Upsert_clauseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitDelete_statement(ctx *Delete_statementContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitColumn_sql_expr(ctx *Column_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitLogical_sql_expr(ctx *Logical_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitArray_access_sql_expr(ctx *Array_access_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitField_access_sql_expr(ctx *Field_access_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitComparison_sql_expr(ctx *Comparison_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitLiteral_sql_expr(ctx *Literal_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitBetween_sql_expr(ctx *Between_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitFunction_call_sql_expr(ctx *Function_call_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitParen_sql_expr(ctx *Paren_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitCollate_sql_expr(ctx *Collate_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitVariable_sql_expr(ctx *Variable_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIs_sql_expr(ctx *Is_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitLike_sql_expr(ctx *Like_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitArithmetic_sql_expr(ctx *Arithmetic_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSubquery_sql_expr(ctx *Subquery_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUnary_sql_expr(ctx *Unary_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitCase_expr(ctx *Case_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIn_sql_expr(ctx *In_sql_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitWhen_then_clause(ctx *When_then_clauseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSql_expr_list(ctx *Sql_expr_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitNormal_call_sql(ctx *Normal_call_sqlContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitForeign_call_sql(ctx *Foreign_call_sqlContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitAction_block(ctx *Action_blockContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitSql_action(ctx *Sql_actionContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitLocal_action(ctx *Local_actionContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitExtension_action(ctx *Extension_actionContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitProcedure_block(ctx *Procedure_blockContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitField_access_procedure_expr(ctx *Field_access_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitLiteral_procedure_expr(ctx *Literal_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitParen_procedure_expr(ctx *Paren_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitVariable_procedure_expr(ctx *Variable_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitMake_array_procedure_expr(ctx *Make_array_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitProcedure_expr_arithmetic(ctx *Procedure_expr_arithmeticContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitUnary_procedure_expr(ctx *Unary_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitComparison_procedure_expr(ctx *Comparison_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitFunction_call_procedure_expr(ctx *Function_call_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitArray_access_procedure_expr(ctx *Array_access_procedure_exprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitProcedure_expr_list(ctx *Procedure_expr_listContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_variable_declaration(ctx *Stmt_variable_declarationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_procedure_call(ctx *Stmt_procedure_callContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_variable_assignment(ctx *Stmt_variable_assignmentContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_for_loop(ctx *Stmt_for_loopContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_if(ctx *Stmt_ifContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_sql(ctx *Stmt_sqlContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_break(ctx *Stmt_breakContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_return(ctx *Stmt_returnContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitStmt_return_next(ctx *Stmt_return_nextContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitVariable_or_underscore(ctx *Variable_or_underscoreContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitNormal_call_procedure(ctx *Normal_call_procedureContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitForeign_call_procedure(ctx *Foreign_call_procedureContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitIf_then_block(ctx *If_then_blockContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseKuneiformParserVisitor) VisitRange(ctx *RangeContext) interface{} { + return v.VisitChildren(ctx) +} diff --git a/parse/gen/kuneiformparser_visitor.go b/parse/gen/kuneiformparser_visitor.go new file mode 100644 index 000000000..517194838 --- /dev/null +++ b/parse/gen/kuneiformparser_visitor.go @@ -0,0 +1,333 @@ +// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. + +package gen // KuneiformParser +import "github.com/antlr4-go/antlr/v4" + +// A complete Visitor for a parse tree produced by KuneiformParser. +type KuneiformParserVisitor interface { + antlr.ParseTreeVisitor + + // Visit a parse tree produced by KuneiformParser#entry. + VisitEntry(ctx *EntryContext) interface{} + + // Visit a parse tree produced by KuneiformParser#string_literal. + VisitString_literal(ctx *String_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#integer_literal. + VisitInteger_literal(ctx *Integer_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#decimal_literal. + VisitDecimal_literal(ctx *Decimal_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#boolean_literal. + VisitBoolean_literal(ctx *Boolean_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#null_literal. + VisitNull_literal(ctx *Null_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#binary_literal. + VisitBinary_literal(ctx *Binary_literalContext) interface{} + + // Visit a parse tree produced by KuneiformParser#identifier. + VisitIdentifier(ctx *IdentifierContext) interface{} + + // Visit a parse tree produced by KuneiformParser#identifier_list. + VisitIdentifier_list(ctx *Identifier_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#type. + VisitType(ctx *TypeContext) interface{} + + // Visit a parse tree produced by KuneiformParser#type_cast. + VisitType_cast(ctx *Type_castContext) interface{} + + // Visit a parse tree produced by KuneiformParser#variable. + VisitVariable(ctx *VariableContext) interface{} + + // Visit a parse tree produced by KuneiformParser#variable_list. + VisitVariable_list(ctx *Variable_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#schema. + VisitSchema(ctx *SchemaContext) interface{} + + // Visit a parse tree produced by KuneiformParser#annotation. + VisitAnnotation(ctx *AnnotationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#database_declaration. + VisitDatabase_declaration(ctx *Database_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#use_declaration. + VisitUse_declaration(ctx *Use_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#table_declaration. + VisitTable_declaration(ctx *Table_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#column_def. + VisitColumn_def(ctx *Column_defContext) interface{} + + // Visit a parse tree produced by KuneiformParser#index_def. + VisitIndex_def(ctx *Index_defContext) interface{} + + // Visit a parse tree produced by KuneiformParser#foreign_key_def. + VisitForeign_key_def(ctx *Foreign_key_defContext) interface{} + + // Visit a parse tree produced by KuneiformParser#foreign_key_action. + VisitForeign_key_action(ctx *Foreign_key_actionContext) interface{} + + // Visit a parse tree produced by KuneiformParser#type_list. + VisitType_list(ctx *Type_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#named_type_list. + VisitNamed_type_list(ctx *Named_type_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#typed_variable_list. + VisitTyped_variable_list(ctx *Typed_variable_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#min_constraint. + VisitMin_constraint(ctx *Min_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#max_constraint. + VisitMax_constraint(ctx *Max_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#min_len_constraint. + VisitMin_len_constraint(ctx *Min_len_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#max_len_constraint. + VisitMax_len_constraint(ctx *Max_len_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#not_null_constraint. + VisitNot_null_constraint(ctx *Not_null_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#primary_key_constraint. + VisitPrimary_key_constraint(ctx *Primary_key_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#default_constraint. + VisitDefault_constraint(ctx *Default_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#unique_constraint. + VisitUnique_constraint(ctx *Unique_constraintContext) interface{} + + // Visit a parse tree produced by KuneiformParser#access_modifier. + VisitAccess_modifier(ctx *Access_modifierContext) interface{} + + // Visit a parse tree produced by KuneiformParser#action_declaration. + VisitAction_declaration(ctx *Action_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#procedure_declaration. + VisitProcedure_declaration(ctx *Procedure_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#foreign_procedure_declaration. + VisitForeign_procedure_declaration(ctx *Foreign_procedure_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#procedure_return. + VisitProcedure_return(ctx *Procedure_returnContext) interface{} + + // Visit a parse tree produced by KuneiformParser#sql. + VisitSql(ctx *SqlContext) interface{} + + // Visit a parse tree produced by KuneiformParser#sql_statement. + VisitSql_statement(ctx *Sql_statementContext) interface{} + + // Visit a parse tree produced by KuneiformParser#common_table_expression. + VisitCommon_table_expression(ctx *Common_table_expressionContext) interface{} + + // Visit a parse tree produced by KuneiformParser#select_statement. + VisitSelect_statement(ctx *Select_statementContext) interface{} + + // Visit a parse tree produced by KuneiformParser#compound_operator. + VisitCompound_operator(ctx *Compound_operatorContext) interface{} + + // Visit a parse tree produced by KuneiformParser#ordering_term. + VisitOrdering_term(ctx *Ordering_termContext) interface{} + + // Visit a parse tree produced by KuneiformParser#select_core. + VisitSelect_core(ctx *Select_coreContext) interface{} + + // Visit a parse tree produced by KuneiformParser#table_relation. + VisitTable_relation(ctx *Table_relationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#subquery_relation. + VisitSubquery_relation(ctx *Subquery_relationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#function_relation. + VisitFunction_relation(ctx *Function_relationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#join. + VisitJoin(ctx *JoinContext) interface{} + + // Visit a parse tree produced by KuneiformParser#expression_result_column. + VisitExpression_result_column(ctx *Expression_result_columnContext) interface{} + + // Visit a parse tree produced by KuneiformParser#wildcard_result_column. + VisitWildcard_result_column(ctx *Wildcard_result_columnContext) interface{} + + // Visit a parse tree produced by KuneiformParser#update_statement. + VisitUpdate_statement(ctx *Update_statementContext) interface{} + + // Visit a parse tree produced by KuneiformParser#update_set_clause. + VisitUpdate_set_clause(ctx *Update_set_clauseContext) interface{} + + // Visit a parse tree produced by KuneiformParser#insert_statement. + VisitInsert_statement(ctx *Insert_statementContext) interface{} + + // Visit a parse tree produced by KuneiformParser#upsert_clause. + VisitUpsert_clause(ctx *Upsert_clauseContext) interface{} + + // Visit a parse tree produced by KuneiformParser#delete_statement. + VisitDelete_statement(ctx *Delete_statementContext) interface{} + + // Visit a parse tree produced by KuneiformParser#column_sql_expr. + VisitColumn_sql_expr(ctx *Column_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#logical_sql_expr. + VisitLogical_sql_expr(ctx *Logical_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#array_access_sql_expr. + VisitArray_access_sql_expr(ctx *Array_access_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#field_access_sql_expr. + VisitField_access_sql_expr(ctx *Field_access_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#comparison_sql_expr. + VisitComparison_sql_expr(ctx *Comparison_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#literal_sql_expr. + VisitLiteral_sql_expr(ctx *Literal_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#between_sql_expr. + VisitBetween_sql_expr(ctx *Between_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#function_call_sql_expr. + VisitFunction_call_sql_expr(ctx *Function_call_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#paren_sql_expr. + VisitParen_sql_expr(ctx *Paren_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#collate_sql_expr. + VisitCollate_sql_expr(ctx *Collate_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#variable_sql_expr. + VisitVariable_sql_expr(ctx *Variable_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#is_sql_expr. + VisitIs_sql_expr(ctx *Is_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#like_sql_expr. + VisitLike_sql_expr(ctx *Like_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#arithmetic_sql_expr. + VisitArithmetic_sql_expr(ctx *Arithmetic_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#subquery_sql_expr. + VisitSubquery_sql_expr(ctx *Subquery_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#unary_sql_expr. + VisitUnary_sql_expr(ctx *Unary_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#case_expr. + VisitCase_expr(ctx *Case_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#in_sql_expr. + VisitIn_sql_expr(ctx *In_sql_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#when_then_clause. + VisitWhen_then_clause(ctx *When_then_clauseContext) interface{} + + // Visit a parse tree produced by KuneiformParser#sql_expr_list. + VisitSql_expr_list(ctx *Sql_expr_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#normal_call_sql. + VisitNormal_call_sql(ctx *Normal_call_sqlContext) interface{} + + // Visit a parse tree produced by KuneiformParser#foreign_call_sql. + VisitForeign_call_sql(ctx *Foreign_call_sqlContext) interface{} + + // Visit a parse tree produced by KuneiformParser#action_block. + VisitAction_block(ctx *Action_blockContext) interface{} + + // Visit a parse tree produced by KuneiformParser#sql_action. + VisitSql_action(ctx *Sql_actionContext) interface{} + + // Visit a parse tree produced by KuneiformParser#local_action. + VisitLocal_action(ctx *Local_actionContext) interface{} + + // Visit a parse tree produced by KuneiformParser#extension_action. + VisitExtension_action(ctx *Extension_actionContext) interface{} + + // Visit a parse tree produced by KuneiformParser#procedure_block. + VisitProcedure_block(ctx *Procedure_blockContext) interface{} + + // Visit a parse tree produced by KuneiformParser#field_access_procedure_expr. + VisitField_access_procedure_expr(ctx *Field_access_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#literal_procedure_expr. + VisitLiteral_procedure_expr(ctx *Literal_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#paren_procedure_expr. + VisitParen_procedure_expr(ctx *Paren_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#variable_procedure_expr. + VisitVariable_procedure_expr(ctx *Variable_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#make_array_procedure_expr. + VisitMake_array_procedure_expr(ctx *Make_array_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#procedure_expr_arithmetic. + VisitProcedure_expr_arithmetic(ctx *Procedure_expr_arithmeticContext) interface{} + + // Visit a parse tree produced by KuneiformParser#unary_procedure_expr. + VisitUnary_procedure_expr(ctx *Unary_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#comparison_procedure_expr. + VisitComparison_procedure_expr(ctx *Comparison_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#function_call_procedure_expr. + VisitFunction_call_procedure_expr(ctx *Function_call_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#array_access_procedure_expr. + VisitArray_access_procedure_expr(ctx *Array_access_procedure_exprContext) interface{} + + // Visit a parse tree produced by KuneiformParser#procedure_expr_list. + VisitProcedure_expr_list(ctx *Procedure_expr_listContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_variable_declaration. + VisitStmt_variable_declaration(ctx *Stmt_variable_declarationContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_procedure_call. + VisitStmt_procedure_call(ctx *Stmt_procedure_callContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_variable_assignment. + VisitStmt_variable_assignment(ctx *Stmt_variable_assignmentContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_for_loop. + VisitStmt_for_loop(ctx *Stmt_for_loopContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_if. + VisitStmt_if(ctx *Stmt_ifContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_sql. + VisitStmt_sql(ctx *Stmt_sqlContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_break. + VisitStmt_break(ctx *Stmt_breakContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_return. + VisitStmt_return(ctx *Stmt_returnContext) interface{} + + // Visit a parse tree produced by KuneiformParser#stmt_return_next. + VisitStmt_return_next(ctx *Stmt_return_nextContext) interface{} + + // Visit a parse tree produced by KuneiformParser#variable_or_underscore. + VisitVariable_or_underscore(ctx *Variable_or_underscoreContext) interface{} + + // Visit a parse tree produced by KuneiformParser#normal_call_procedure. + VisitNormal_call_procedure(ctx *Normal_call_procedureContext) interface{} + + // Visit a parse tree produced by KuneiformParser#foreign_call_procedure. + VisitForeign_call_procedure(ctx *Foreign_call_procedureContext) interface{} + + // Visit a parse tree produced by KuneiformParser#if_then_block. + VisitIf_then_block(ctx *If_then_blockContext) interface{} + + // Visit a parse tree produced by KuneiformParser#range. + VisitRange(ctx *RangeContext) interface{} +} diff --git a/parse/go.mod b/parse/go.mod index 8c3ef250e..d7d054249 100644 --- a/parse/go.mod +++ b/parse/go.mod @@ -7,12 +7,14 @@ replace github.com/kwilteam/kwil-db/core => ../core require ( github.com/antlr4-go/antlr/v4 v4.13.0 github.com/google/go-cmp v0.6.0 + github.com/holiman/uint256 v1.2.4 github.com/kwilteam/kwil-db/core v0.2.0-beta github.com/pganalyze/pg_query_go/v5 v5.1.0 github.com/stretchr/testify v1.9.0 ) require ( + github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/google/uuid v1.6.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/parse/go.sum b/parse/go.sum index 5dcbd63b2..085a50f5b 100644 --- a/parse/go.sum +++ b/parse/go.sum @@ -1,5 +1,7 @@ github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -8,8 +10,14 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pganalyze/pg_query_go/v5 v5.1.0 h1:MlxQqHZnvA3cbRQYyIrjxEjzo560P6MyTgtlaf3pmXg= github.com/pganalyze/pg_query_go/v5 v5.1.0/go.mod h1:FsglvxidZsVN+Ltw3Ai6nTgPVcK2BPukH3jCDEqc1Ug= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -25,3 +33,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/parse/grammar/KuneiformLexer.g4 b/parse/grammar/KuneiformLexer.g4 new file mode 100644 index 000000000..5be48ee73 --- /dev/null +++ b/parse/grammar/KuneiformLexer.g4 @@ -0,0 +1,179 @@ +/* + * A ANTLR4 grammar for Kuneiform. + * Developed by the Kwil team. +*/ + +lexer grammar KuneiformLexer; + +options { caseInsensitive = true; } + +// symbols +LBRACE: '{'; +RBRACE: '}'; +LBRACKET: '['; +RBRACKET: ']'; +COL: ':'; +SCOL: ';'; +LPAREN: '('; +RPAREN: ')'; +COMMA: ','; +AT: '@'; +EXCL: '!'; +PERIOD: '.'; +CONCAT: '||'; +STAR: '*'; +EQUALS: '='; +EQUATE: '=='; +HASH: '#'; +DOLLAR: '$'; +MOD: '%'; +PLUS: '+'; +MINUS: '-'; +DIV: '/'; +NEQ: '!='|'<>'; +LT: '<'; +LTE: '<='; +GT: '>'; +GTE: '>='; +TYPE_CAST: '::'; +UNDERSCORE: '_'; +ASSIGN: ':='; +RANGE: '..'; +DOUBLE_QUOTE: '"'; + + +// top-level blocks +DATABASE: 'database'; +USE: 'use'; +TABLE: 'table'; +ACTION: 'action'; +PROCEDURE: 'procedure'; + +PUBLIC: 'public'; +PRIVATE: 'private'; +VIEW: 'view'; +OWNER: 'owner'; + +// column attributes +MIN: 'min'; +MAX: 'max'; +MINLEN: 'minlen'; +MAXLEN: 'maxlen'; +UNIQUE: 'unique'; + +// keywords +FOREIGN: 'foreign'; +PRIMARY: 'primary'; +KEY: 'key'; +ON: 'on'; +DO: 'do'; +CASCADE: 'cascade'; +RESTRICT: 'restrict'; +SET: 'set'; +DEFAULT: 'default'; +NULL: 'null'; +DELETE: 'delete'; +UPDATE: 'update'; +REFERENCES: 'references'; +REF: 'ref'; +NOT: 'not'; +INDEX: 'index'; +AND: 'and'; +OR: 'or'; +LIKE: 'like'; +IN: 'in'; +BETWEEN: 'between'; +IS: 'is'; +EXISTS: 'exists'; +ALL: 'all'; +ANY: 'any'; +JOIN: 'join'; // we only support inner, left, and right joins +LEFT: 'left'; +RIGHT: 'right'; +INNER: 'inner'; +AS: 'as'; +ASC: 'asc'; +DESC: 'desc'; +LIMIT: 'limit'; +OFFSET: 'offset'; +ORDER: 'order'; +BY: 'by'; +GROUP: 'group'; +HAVING: 'having'; +RETURNS: 'returns'; +NO: 'no'; +NOTNULL: 'notnull'; +WITH: 'with'; +CASE: 'case'; +WHEN: 'when'; +THEN: 'then'; +END: 'end'; +DISTINCT: 'distinct'; +FROM: 'from'; +WHERE: 'where'; +COLLATE: 'collate'; +SELECT: 'select'; +INSERT: 'insert'; +VALUES: 'values'; +FULL: 'full'; +UNION: 'union'; +INTERSECT: 'intersect'; +EXCEPT: 'except'; +NULLS: 'nulls'; +FIRST: 'first'; +LAST: 'last'; +RETURNING: 'returning'; +INTO: 'into'; +CONFLICT: 'conflict'; +NOTHING: 'nothing'; +FOR: 'for'; +IF: 'if'; +ELSEIF: 'elseif'; +ELSE: 'else'; +BREAK: 'break'; +RETURN: 'return'; +NEXT: 'next'; + + +// Literals +STRING_: '\'' ( ~['\\] | '\\' . )* '\''; +TRUE: 'true'; +FALSE: 'false'; + +DIGITS_: + [0-9]+ +; + +BINARY_: + '0x' [0-9a-f]+ +; + +// for backwards compatibility, constraints that support underscores +// are kept here +LEGACY_PRIMARY_KEY: 'primary_key' | 'pk'; +LEGACY_FOREIGN_KEY: 'foreign_key' | 'fk'; +LEGACY_ON_UPDATE: 'on_update'; +LEGACY_ON_DELETE: 'on_delete'; +LEGACY_SET_DEFAULT: 'set_default'; +LEGACY_SET_NULL: 'set_null'; +LEGACY_NO_ACTION: 'no_action'; + +IDENTIFIER: + [a-z] [a-z_0-9]* +; + +VARIABLE: + DOLLAR IDENTIFIER +; + +CONTEXTUAL_VARIABLE: + AT IDENTIFIER +; + +HASH_IDENTIFIER: + HASH IDENTIFIER +; + +WS: [ \u000B\t\r\n] -> channel(HIDDEN); +BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); +LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); \ No newline at end of file diff --git a/parse/grammar/KuneiformParser.g4 b/parse/grammar/KuneiformParser.g4 new file mode 100644 index 000000000..ae34757db --- /dev/null +++ b/parse/grammar/KuneiformParser.g4 @@ -0,0 +1,388 @@ +/* + * A ANTLR4 grammar for Kuneiform. + * Developed by the Kwil team. +*/ +parser grammar KuneiformParser; + +options { + tokenVocab = KuneiformLexer; +} + +// entry is the entrypoint for the parser. +// The parser is capable of parsing full Kuneiform schemas, +// sql statements, and action and procedure bodies. +entry: + (schema | sql | action_block | procedure_block) + EOF +; + +/* + The following section includes the parser rules that are commonly + used among all sections of the grammar. These include literals, +*/ + +literal: + STRING_ # string_literal + | (PLUS | MINUS)? DIGITS_ # integer_literal + | (PLUS | MINUS)? DIGITS_ PERIOD DIGITS_ # decimal_literal + | (TRUE | FALSE) # boolean_literal + | NULL # null_literal + | BINARY_ # binary_literal +; + +// identifier is used for table / column names +identifier: + (DOUBLE_QUOTE IDENTIFIER DOUBLE_QUOTE) | IDENTIFIER +; + +identifier_list: + identifier (COMMA identifier)* +; + +type: + IDENTIFIER (LPAREN DIGITS_ COMMA DIGITS_ RPAREN)? (LBRACKET RBRACKET)? // Handles arrays of any type, including nested arrays +; + +type_cast: + TYPE_CAST type +; + +variable: + VARIABLE | CONTEXTUAL_VARIABLE +; + +variable_list: + variable (COMMA variable)* +; + +/* + The following section includes parser rules for top-level Kuneiform. + These are the rules that parse the schema / DDL, and are used pre-consensus. +*/ + +// schema is the parser entrypoint for an entire +// Kuneiform schema. +schema: + database_declaration + (use_declaration | table_declaration + | action_declaration | procedure_declaration + | foreign_procedure_declaration + )* +; + +annotation: + // sort've a hack; annotations don't technically use contextual variables, but they have + // the same syntax of @identifier + CONTEXTUAL_VARIABLE LPAREN (IDENTIFIER EQUALS literal (COMMA IDENTIFIER EQUALS literal)*)? RPAREN +; + +database_declaration: + DATABASE IDENTIFIER SCOL +; + +use_declaration: + USE IDENTIFIER + (LBRACE IDENTIFIER COL literal (COMMA IDENTIFIER COL literal)* RBRACE)? + AS IDENTIFIER SCOL +; + +table_declaration: + TABLE IDENTIFIER LBRACE + column_def (COMMA (column_def | index_def | foreign_key_def))* + RBRACE + ; + +column_def: + name=IDENTIFIER type constraint* +; + +index_def: + HASH_IDENTIFIER + (UNIQUE | INDEX | PRIMARY) + LPAREN columns=identifier_list RPAREN +; + +foreign_key_def: + (FOREIGN KEY|LEGACY_FOREIGN_KEY) // for backwards compatibility + LPAREN child_keys=identifier_list RPAREN + (REFERENCES|REF) parent_table=IDENTIFIER LPAREN parent_keys=identifier_list RPAREN + foreign_key_action* +; + +// variability here is to support legacy syntax +foreign_key_action: + ((ON UPDATE|LEGACY_ON_UPDATE)|(ON DELETE|LEGACY_ON_DELETE)) DO? ((NO ACTION|LEGACY_NO_ACTION)|CASCADE|(SET NULL|LEGACY_SET_NULL)|(SET DEFAULT|LEGACY_SET_DEFAULT)|RESTRICT) +; + +type_list: + type (COMMA type)* +; + +named_type_list: + IDENTIFIER type (COMMA IDENTIFIER type)* +; + +typed_variable_list: + variable type (COMMA variable type)* +; + +constraint: + MIN LPAREN literal RPAREN # min_constraint + | MAX LPAREN literal RPAREN # max_constraint + | MINLEN LPAREN literal RPAREN # min_len_constraint + | MAXLEN LPAREN literal RPAREN # max_len_constraint + | (NOTNULL|NOT NULL) # not_null_constraint + | (LEGACY_PRIMARY_KEY|PRIMARY KEY?) # primary_key_constraint + | DEFAULT LPAREN literal RPAREN # default_constraint + | UNIQUE # unique_constraint +; + +access_modifier: + PUBLIC | PRIVATE | VIEW | OWNER +; + +action_declaration: + annotation* + ACTION IDENTIFIER + LPAREN variable_list? RPAREN + (access_modifier)+ + LBRACE action_block RBRACE +; + +procedure_declaration: + annotation* + PROCEDURE IDENTIFIER + LPAREN (typed_variable_list)? RPAREN + (access_modifier)+ + (procedure_return)? + LBRACE procedure_block RBRACE +; + + +foreign_procedure_declaration: + FOREIGN PROCEDURE IDENTIFIER + LPAREN (unnamed_params=type_list|named_params=typed_variable_list)? RPAREN + (procedure_return)? +; + +procedure_return: + RETURNS (TABLE? LPAREN return_columns=named_type_list RPAREN + | LPAREN unnamed_return_types=type_list RPAREN) +; + +/* + The following section includes parser rules for SQL. +*/ + +// sql is a top-level SQL statement. +sql: + sql_statement SCOL +; + +sql_statement: + (WITH common_table_expression (COMMA common_table_expression)*)? + (select_statement | update_statement | insert_statement | delete_statement) +; + +common_table_expression: + identifier LPAREN (identifier (COMMA identifier)*)? RPAREN AS LPAREN select_statement RPAREN +; + +select_statement: + select_core + (compound_operator select_core)* + (ORDER BY ordering_term (COMMA ordering_term)*)? + (LIMIT limit=sql_expr)? + (OFFSET offset=sql_expr)? +; + +compound_operator: + UNION ALL? | INTERSECT | EXCEPT +; + +ordering_term: + sql_expr (ASC | DESC)? (NULLS (FIRST | LAST))? +; + +select_core: + SELECT DISTINCT? + result_column (COMMA result_column)* + (FROM relation join*)? + (WHERE where=sql_expr)? + ( + GROUP BY group_by=sql_expr_list + (HAVING having=sql_expr)? + )? +; + +relation: + table_name=identifier (AS? alias=identifier)? # table_relation + // aliases are technically required in Kuneiform for subquery and function calls, + // but we allow it to pass here since it is standard SQL to not require it, and + // we can throw a better error message after parsing. + | LPAREN select_statement RPAREN (AS? alias=identifier)? # subquery_relation + | sql_function_call (AS? alias=identifier?) # function_relation +; + +join: + (INNER| LEFT | RIGHT | FULL) JOIN + relation ON sql_expr +; + +result_column: + sql_expr (AS? identifier)? # expression_result_column + | (table_name=identifier PERIOD)? STAR # wildcard_result_column +; + +update_statement: + UPDATE table_name=identifier (AS alias=identifier)? + SET update_set_clause (COMMA update_set_clause)* + (FROM relation join*)? + (WHERE where=sql_expr)? +; + +update_set_clause: + column=identifier EQUALS sql_expr +; + +insert_statement: + INSERT INTO table_name=identifier (AS alias=identifier)? + (LPAREN target_columns=identifier_list RPAREN)? + VALUES LPAREN sql_expr_list RPAREN (COMMA LPAREN sql_expr_list RPAREN)* + upsert_clause? +; + +upsert_clause: + ON CONFLICT + (LPAREN conflict_columns=identifier_list RPAREN (WHERE conflict_where=sql_expr)?)? + DO ( + NOTHING + | UPDATE SET update_set_clause (COMMA update_set_clause)* + (WHERE update_where=sql_expr)? + ) +; + +delete_statement: + DELETE FROM table_name=identifier (AS alias=identifier)? + // (USING relation join*)? + (WHERE where=sql_expr)? +; + +sql_expr: + literal type_cast? # literal_sql_expr + | sql_expr COLLATE identifier # collate_sql_expr + | sql_function_call type_cast? # function_call_sql_expr + | variable type_cast? # variable_sql_expr + | (table=identifier PERIOD)? column=identifier type_cast? # column_sql_expr + | sql_expr LBRACKET sql_expr RBRACKET type_cast? # array_access_sql_expr + | sql_expr PERIOD identifier type_cast? # field_access_sql_expr + | LPAREN sql_expr RPAREN type_cast? # paren_sql_expr + | left=sql_expr (EQUALS | EQUATE | NEQ | LT | LTE | GT | GTE) right=sql_expr # comparison_sql_expr + | sql_expr NOT? IN LPAREN (sql_expr_list|select_statement) RPAREN # in_sql_expr + | left=sql_expr NOT? LIKE right=sql_expr # like_sql_expr + | (NOT|PLUS|MINUS) sql_expr # unary_sql_expr + | element=sql_expr (NOT)? BETWEEN lower=sql_expr AND upper=sql_expr # between_sql_expr + | left=sql_expr IS NOT? ((DISTINCT FROM right=sql_expr) | NULL | TRUE | FALSE) # is_sql_expr + | CASE case_clause=sql_expr? + (when_then_clause)+ + (ELSE else_clause=sql_expr)? END # case_expr + | (NOT? EXISTS)? LPAREN select_statement RPAREN type_cast? # subquery_sql_expr + // setting precedence for arithmetic operations: + | left=sql_expr CONCAT right=sql_expr # arithmetic_sql_expr + | left=sql_expr (STAR | DIV | MOD) right=sql_expr # arithmetic_sql_expr + | left=sql_expr (PLUS | MINUS) right=sql_expr # arithmetic_sql_expr + // setting precedence for logical operations: + | left=sql_expr AND right=sql_expr # logical_sql_expr + | left=sql_expr OR right=sql_expr # logical_sql_expr +; + +when_then_clause: + WHEN when_condition=sql_expr THEN then=sql_expr +; + +sql_expr_list: + sql_expr (COMMA sql_expr)* +; + +sql_function_call: + identifier LPAREN (DISTINCT? sql_expr_list|STAR)? RPAREN #normal_call_sql + | identifier LBRACKET dbid=sql_expr COMMA procedure=sql_expr RBRACKET LPAREN (sql_expr_list)? RPAREN #foreign_call_sql +; + +/* + The following section includes parser rules for action blocks. +*/ +// action_block is the top-level rule for an action block. +action_block: + (action_statement SCOL)* +; + +// action statements can only be 3 things: +// 1. a sql statement +// 2. a local action/procedure call. +// 3. an extension call +action_statement: + sql_statement # sql_action + | IDENTIFIER LPAREN (procedure_expr_list)? RPAREN # local_action + | (variable_list EQUALS)? IDENTIFIER PERIOD IDENTIFIER LPAREN (procedure_expr_list)? RPAREN # extension_action +; + +/* + This section includes parser rules for procedures +*/ + +// procedure_block is the top-level rule for a procedure. +procedure_block: + proc_statement* +; + +procedure_expr: + literal type_cast? # literal_procedure_expr + | procedure_function_call type_cast? # function_call_procedure_expr + | variable type_cast? # variable_procedure_expr + | LBRACKET (procedure_expr_list)? RBRACKET type_cast? # make_array_procedure_expr + | procedure_expr LBRACKET procedure_expr RBRACKET type_cast? # array_access_procedure_expr + | LPAREN procedure_expr RPAREN type_cast? # paren_procedure_expr + | procedure_expr PERIOD IDENTIFIER type_cast? # field_access_procedure_expr + | procedure_expr (EQUALS | EQUATE | NEQ | LT | LTE | GT | GTE) procedure_expr # comparison_procedure_expr + | (MINUS|PLUS|EXCL) procedure_expr # unary_procedure_expr + // setting precedence for arithmetic operations: + | procedure_expr CONCAT procedure_expr # procedure_expr_arithmetic + | procedure_expr (STAR | DIV | MOD) procedure_expr # procedure_expr_arithmetic + | procedure_expr (PLUS | MINUS) procedure_expr # procedure_expr_arithmetic +; + +procedure_expr_list: + procedure_expr (COMMA procedure_expr)* +; + +proc_statement: + VARIABLE type SCOL # stmt_variable_declaration + // stmt_procedure_call must go above stmt_variable_assignment due to lexer ambiguity + | ((variable_or_underscore) (COMMA (variable_or_underscore))* ASSIGN)? procedure_function_call SCOL # stmt_procedure_call + | VARIABLE type? ASSIGN procedure_expr SCOL # stmt_variable_assignment + | FOR receiver=VARIABLE IN (range|target_variable=variable|sql_statement) LBRACE proc_statement* RBRACE # stmt_for_loop + | IF if_then_block (ELSEIF if_then_block)* (ELSE LBRACE proc_statement* RBRACE)? # stmt_if + | sql_statement SCOL # stmt_sql + | BREAK SCOL # stmt_break + | RETURN (procedure_expr_list|sql_statement) SCOL # stmt_return + | RETURN NEXT procedure_expr_list SCOL # stmt_return_next +; + +variable_or_underscore: + VARIABLE | UNDERSCORE +; + +procedure_function_call: + IDENTIFIER LPAREN (procedure_expr_list)? RPAREN #normal_call_procedure + | IDENTIFIER LBRACKET dbid=procedure_expr COMMA procedure=procedure_expr RBRACKET LPAREN (procedure_expr_list)? RPAREN #foreign_call_procedure +; + +if_then_block: + procedure_expr LBRACE proc_statement* RBRACE +; + +// range used for for loops +range: + procedure_expr RANGE procedure_expr +; \ No newline at end of file diff --git a/parse/kuneiform/grammar/generate.sh b/parse/grammar/generate.sh similarity index 100% rename from parse/kuneiform/grammar/generate.sh rename to parse/grammar/generate.sh diff --git a/parse/kuneiform/.gitignore b/parse/kuneiform/.gitignore deleted file mode 100644 index 0729010ac..000000000 --- a/parse/kuneiform/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.java -*.tokens -*.interp -antlr-4.13.1-complete.jar -.antlr -!gen \ No newline at end of file diff --git a/parse/kuneiform/gen/kuneiform_lexer.go b/parse/kuneiform/gen/kuneiform_lexer.go deleted file mode 100644 index 6b0e197e1..000000000 --- a/parse/kuneiform/gen/kuneiform_lexer.go +++ /dev/null @@ -1,492 +0,0 @@ -// Code generated from KuneiformLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen - -import ( - "fmt" - "github.com/antlr4-go/antlr/v4" - "sync" - "unicode" -) - -// Suppress unused import error -var _ = fmt.Printf -var _ = sync.Once{} -var _ = unicode.IsLetter - -type KuneiformLexer struct { - *antlr.BaseLexer - channelNames []string - modeNames []string - // TODO: EOF string -} - -var KuneiformLexerLexerStaticData struct { - once sync.Once - serializedATN []int32 - ChannelNames []string - ModeNames []string - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func kuneiformlexerLexerInit() { - staticData := &KuneiformLexerLexerStaticData - staticData.ChannelNames = []string{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN", - } - staticData.ModeNames = []string{ - "DEFAULT_MODE", "STMT_MODE", - } - staticData.LiteralNames = []string{ - "", "'{'", "'}'", "'['", "']'", "':'", "';'", "'('", "')'", "','", "'@'", - "'.'", "'='", "'database'", "'use'", "'import'", "'as'", "'min'", "'max'", - "'minlen'", "'maxlen'", "", "", "'default'", "'unique'", "'index'", - "'table'", "'type'", "'returns'", "", "", "", "", "", "", "'cascade'", - "", "", "'restrict'", "'do'", "'action'", "'procedure'", - } - staticData.SymbolicNames = []string{ - "", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", - "RPAREN", "COMMA", "AT", "PERIOD", "EQUALS", "DATABASE", "USE", "IMPORT", - "AS", "MIN", "MAX", "MIN_LEN", "MAX_LEN", "NOT_NULL", "PRIMARY", "DEFAULT", - "UNIQUE", "INDEX", "TABLE", "TYPE", "RETURNS", "FOREIGN_KEY", "FOREIGN_PROCEDURE", - "REFERENCES", "ON_UPDATE", "ON_DELETE", "DO_NO_ACTION", "DO_CASCADE", - "DO_SET_NULL", "DO_SET_DEFAULT", "DO_RESTRICT", "DO", "START_ACTION", - "START_PROCEDURE", "NUMERIC_LITERAL", "TEXT_LITERAL", "BOOLEAN_LITERAL", - "BLOB_LITERAL", "VAR", "INDEX_NAME", "IDENTIFIER", "ANNOTATION", "WS", - "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", "COMMENT", "STMT_BODY", - "TEXT", "STMT_LPAREN", "STMT_RPAREN", "STMT_COMMA", "STMT_PERIOD", "STMT_RETURNS", - "STMT_TABLE", "STMT_ARRAY", "STMT_VAR", "STMT_ACCESS", "STMT_IDENTIFIER", - "STMT_WS", "STMT_TERMINATOR", - } - staticData.RuleNames = []string{ - "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", - "RPAREN", "COMMA", "AT", "PERIOD", "EQUALS", "DATABASE", "USE", "IMPORT", - "AS", "MIN", "MAX", "MIN_LEN", "MAX_LEN", "NOT_NULL", "PRIMARY", "DEFAULT", - "UNIQUE", "INDEX", "TABLE", "TYPE", "RETURNS", "FOREIGN_KEY", "FOREIGN_PROCEDURE", - "REFERENCES", "ON_UPDATE", "ON_DELETE", "DO_NO_ACTION", "DO_CASCADE", - "DO_SET_NULL", "DO_SET_DEFAULT", "DO_RESTRICT", "DO", "START_ACTION", - "START_PROCEDURE", "NUMERIC_LITERAL", "TEXT_LITERAL", "BOOLEAN_LITERAL", - "BLOB_LITERAL", "VAR", "INDEX_NAME", "IDENTIFIER", "ANNOTATION", "WS", - "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", "WSNL", "DIGIT", "COMMENT", - "STMT_BODY", "TEXT", "STMT_LPAREN", "STMT_RPAREN", "STMT_COMMA", "STMT_PERIOD", - "STMT_RETURNS", "STMT_TABLE", "STMT_ARRAY", "STMT_VAR", "STMT_ACCESS", - "STMT_IDENTIFIER", "STMT_WS", "STMT_TERMINATOR", "ANY", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 0, 68, 657, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, - 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, - 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, - 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, - 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, - 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, - 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, - 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, - 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, - 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, - 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, - 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, - 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, - 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 1, 0, 1, 0, 1, 1, - 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, - 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, - 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, - 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, - 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, - 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, - 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 219, 8, 20, 1, 20, 1, - 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, - 1, 21, 1, 21, 1, 21, 3, 21, 236, 8, 21, 1, 21, 1, 21, 1, 21, 3, 21, 241, - 8, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, - 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, - 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, - 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, - 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 293, - 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 300, 8, 28, 1, 29, 1, - 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, - 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, - 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, - 334, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 341, 8, 31, 1, 31, - 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, - 32, 3, 32, 355, 8, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, - 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 369, 8, 33, 1, 33, 1, 33, 1, - 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, - 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 392, 8, - 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, - 1, 36, 3, 36, 405, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, - 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, - 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, - 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, - 1, 40, 1, 40, 1, 40, 1, 41, 3, 41, 449, 8, 41, 1, 41, 4, 41, 452, 8, 41, - 11, 41, 12, 41, 453, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 460, 8, 42, 10, - 42, 12, 42, 463, 9, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, - 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 476, 8, 43, 1, 44, 1, 44, 1, 44, 1, - 44, 4, 44, 482, 8, 44, 11, 44, 12, 44, 483, 1, 45, 1, 45, 1, 45, 1, 46, - 1, 46, 1, 46, 1, 47, 1, 47, 5, 47, 494, 8, 47, 10, 47, 12, 47, 497, 9, - 47, 1, 48, 1, 48, 4, 48, 501, 8, 48, 11, 48, 12, 48, 502, 1, 49, 1, 49, - 1, 49, 1, 49, 1, 50, 4, 50, 510, 8, 50, 11, 50, 12, 50, 511, 1, 50, 1, - 50, 1, 51, 1, 51, 1, 51, 1, 51, 5, 51, 520, 8, 51, 10, 51, 12, 51, 523, - 9, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 5, - 52, 534, 8, 52, 10, 52, 12, 52, 537, 9, 52, 1, 52, 1, 52, 1, 53, 4, 53, - 542, 8, 53, 11, 53, 12, 53, 543, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, - 55, 5, 55, 552, 8, 55, 10, 55, 12, 55, 555, 9, 55, 1, 55, 3, 55, 558, 8, - 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 5, 55, 565, 8, 55, 10, 55, 12, 55, - 568, 9, 55, 1, 55, 1, 55, 3, 55, 572, 8, 55, 1, 55, 1, 55, 1, 56, 1, 56, - 1, 56, 1, 56, 1, 56, 5, 56, 581, 8, 56, 10, 56, 12, 56, 584, 9, 56, 1, - 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 5, 57, 594, 8, 57, - 10, 57, 12, 57, 597, 9, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, - 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, - 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, - 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, - 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 641, 8, 66, 1, 67, 1, 67, 1, 68, 1, - 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 4, 70, 654, 8, 70, - 11, 70, 12, 70, 655, 2, 521, 566, 0, 71, 2, 1, 4, 2, 6, 3, 8, 4, 10, 5, - 12, 6, 14, 7, 16, 8, 18, 9, 20, 10, 22, 11, 24, 12, 26, 13, 28, 14, 30, - 15, 32, 16, 34, 17, 36, 18, 38, 19, 40, 20, 42, 21, 44, 22, 46, 23, 48, - 24, 50, 25, 52, 26, 54, 27, 56, 28, 58, 29, 60, 30, 62, 31, 64, 32, 66, - 33, 68, 34, 70, 35, 72, 36, 74, 37, 76, 38, 78, 39, 80, 40, 82, 41, 84, - 42, 86, 43, 88, 44, 90, 45, 92, 46, 94, 47, 96, 48, 98, 49, 100, 50, 102, - 51, 104, 52, 106, 53, 108, 0, 110, 0, 112, 54, 114, 55, 116, 56, 118, 57, - 120, 58, 122, 59, 124, 60, 126, 61, 128, 62, 130, 63, 132, 64, 134, 65, - 136, 66, 138, 67, 140, 68, 142, 0, 2, 0, 1, 34, 2, 0, 68, 68, 100, 100, - 2, 0, 65, 65, 97, 97, 2, 0, 84, 84, 116, 116, 2, 0, 66, 66, 98, 98, 2, - 0, 83, 83, 115, 115, 2, 0, 69, 69, 101, 101, 2, 0, 85, 85, 117, 117, 2, - 0, 73, 73, 105, 105, 2, 0, 77, 77, 109, 109, 2, 0, 80, 80, 112, 112, 2, - 0, 79, 79, 111, 111, 2, 0, 82, 82, 114, 114, 2, 0, 78, 78, 110, 110, 2, - 0, 88, 88, 120, 120, 2, 0, 76, 76, 108, 108, 2, 0, 89, 89, 121, 121, 2, - 0, 75, 75, 107, 107, 2, 0, 70, 70, 102, 102, 2, 0, 81, 81, 113, 113, 2, - 0, 71, 71, 103, 103, 2, 0, 67, 67, 99, 99, 2, 0, 43, 43, 45, 45, 1, 0, - 48, 57, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 3, 0, 48, 57, 65, 70, 97, - 102, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 1, 0, - 10, 10, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 10, 10, 13, 13, 2, 0, 39, 39, - 92, 92, 2, 0, 86, 86, 118, 118, 2, 0, 87, 87, 119, 119, 4, 0, 39, 39, 47, - 47, 123, 123, 125, 125, 690, 0, 2, 1, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 6, - 1, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, - 14, 1, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, - 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, - 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, - 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, - 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, - 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, - 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 66, 1, 0, 0, 0, - 0, 68, 1, 0, 0, 0, 0, 70, 1, 0, 0, 0, 0, 72, 1, 0, 0, 0, 0, 74, 1, 0, 0, - 0, 0, 76, 1, 0, 0, 0, 0, 78, 1, 0, 0, 0, 0, 80, 1, 0, 0, 0, 0, 82, 1, 0, - 0, 0, 0, 84, 1, 0, 0, 0, 0, 86, 1, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 90, 1, - 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 94, 1, 0, 0, 0, 0, 96, 1, 0, 0, 0, 0, 98, - 1, 0, 0, 0, 0, 100, 1, 0, 0, 0, 0, 102, 1, 0, 0, 0, 0, 104, 1, 0, 0, 0, - 0, 106, 1, 0, 0, 0, 1, 112, 1, 0, 0, 0, 1, 114, 1, 0, 0, 0, 1, 116, 1, - 0, 0, 0, 1, 118, 1, 0, 0, 0, 1, 120, 1, 0, 0, 0, 1, 122, 1, 0, 0, 0, 1, - 124, 1, 0, 0, 0, 1, 126, 1, 0, 0, 0, 1, 128, 1, 0, 0, 0, 1, 130, 1, 0, - 0, 0, 1, 132, 1, 0, 0, 0, 1, 134, 1, 0, 0, 0, 1, 136, 1, 0, 0, 0, 1, 138, - 1, 0, 0, 0, 1, 140, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 4, 146, 1, 0, 0, 0, - 6, 148, 1, 0, 0, 0, 8, 150, 1, 0, 0, 0, 10, 152, 1, 0, 0, 0, 12, 154, 1, - 0, 0, 0, 14, 156, 1, 0, 0, 0, 16, 158, 1, 0, 0, 0, 18, 160, 1, 0, 0, 0, - 20, 162, 1, 0, 0, 0, 22, 164, 1, 0, 0, 0, 24, 166, 1, 0, 0, 0, 26, 168, - 1, 0, 0, 0, 28, 177, 1, 0, 0, 0, 30, 181, 1, 0, 0, 0, 32, 188, 1, 0, 0, - 0, 34, 191, 1, 0, 0, 0, 36, 195, 1, 0, 0, 0, 38, 199, 1, 0, 0, 0, 40, 206, - 1, 0, 0, 0, 42, 213, 1, 0, 0, 0, 44, 225, 1, 0, 0, 0, 46, 242, 1, 0, 0, - 0, 48, 250, 1, 0, 0, 0, 50, 257, 1, 0, 0, 0, 52, 263, 1, 0, 0, 0, 54, 269, - 1, 0, 0, 0, 56, 274, 1, 0, 0, 0, 58, 299, 1, 0, 0, 0, 60, 301, 1, 0, 0, - 0, 62, 333, 1, 0, 0, 0, 64, 335, 1, 0, 0, 0, 66, 349, 1, 0, 0, 0, 68, 363, - 1, 0, 0, 0, 70, 377, 1, 0, 0, 0, 72, 385, 1, 0, 0, 0, 74, 398, 1, 0, 0, - 0, 76, 414, 1, 0, 0, 0, 78, 423, 1, 0, 0, 0, 80, 426, 1, 0, 0, 0, 82, 435, - 1, 0, 0, 0, 84, 448, 1, 0, 0, 0, 86, 455, 1, 0, 0, 0, 88, 475, 1, 0, 0, - 0, 90, 477, 1, 0, 0, 0, 92, 485, 1, 0, 0, 0, 94, 488, 1, 0, 0, 0, 96, 491, - 1, 0, 0, 0, 98, 498, 1, 0, 0, 0, 100, 504, 1, 0, 0, 0, 102, 509, 1, 0, - 0, 0, 104, 515, 1, 0, 0, 0, 106, 529, 1, 0, 0, 0, 108, 541, 1, 0, 0, 0, - 110, 545, 1, 0, 0, 0, 112, 571, 1, 0, 0, 0, 114, 575, 1, 0, 0, 0, 116, - 589, 1, 0, 0, 0, 118, 600, 1, 0, 0, 0, 120, 602, 1, 0, 0, 0, 122, 604, - 1, 0, 0, 0, 124, 606, 1, 0, 0, 0, 126, 608, 1, 0, 0, 0, 128, 610, 1, 0, - 0, 0, 130, 612, 1, 0, 0, 0, 132, 615, 1, 0, 0, 0, 134, 640, 1, 0, 0, 0, - 136, 642, 1, 0, 0, 0, 138, 644, 1, 0, 0, 0, 140, 648, 1, 0, 0, 0, 142, - 653, 1, 0, 0, 0, 144, 145, 5, 123, 0, 0, 145, 3, 1, 0, 0, 0, 146, 147, - 5, 125, 0, 0, 147, 5, 1, 0, 0, 0, 148, 149, 5, 91, 0, 0, 149, 7, 1, 0, - 0, 0, 150, 151, 5, 93, 0, 0, 151, 9, 1, 0, 0, 0, 152, 153, 5, 58, 0, 0, - 153, 11, 1, 0, 0, 0, 154, 155, 5, 59, 0, 0, 155, 13, 1, 0, 0, 0, 156, 157, - 5, 40, 0, 0, 157, 15, 1, 0, 0, 0, 158, 159, 5, 41, 0, 0, 159, 17, 1, 0, - 0, 0, 160, 161, 5, 44, 0, 0, 161, 19, 1, 0, 0, 0, 162, 163, 5, 64, 0, 0, - 163, 21, 1, 0, 0, 0, 164, 165, 5, 46, 0, 0, 165, 23, 1, 0, 0, 0, 166, 167, - 5, 61, 0, 0, 167, 25, 1, 0, 0, 0, 168, 169, 7, 0, 0, 0, 169, 170, 7, 1, - 0, 0, 170, 171, 7, 2, 0, 0, 171, 172, 7, 1, 0, 0, 172, 173, 7, 3, 0, 0, - 173, 174, 7, 1, 0, 0, 174, 175, 7, 4, 0, 0, 175, 176, 7, 5, 0, 0, 176, - 27, 1, 0, 0, 0, 177, 178, 7, 6, 0, 0, 178, 179, 7, 4, 0, 0, 179, 180, 7, - 5, 0, 0, 180, 29, 1, 0, 0, 0, 181, 182, 7, 7, 0, 0, 182, 183, 7, 8, 0, - 0, 183, 184, 7, 9, 0, 0, 184, 185, 7, 10, 0, 0, 185, 186, 7, 11, 0, 0, - 186, 187, 7, 2, 0, 0, 187, 31, 1, 0, 0, 0, 188, 189, 7, 1, 0, 0, 189, 190, - 7, 4, 0, 0, 190, 33, 1, 0, 0, 0, 191, 192, 7, 8, 0, 0, 192, 193, 7, 7, - 0, 0, 193, 194, 7, 12, 0, 0, 194, 35, 1, 0, 0, 0, 195, 196, 7, 8, 0, 0, - 196, 197, 7, 1, 0, 0, 197, 198, 7, 13, 0, 0, 198, 37, 1, 0, 0, 0, 199, - 200, 7, 8, 0, 0, 200, 201, 7, 7, 0, 0, 201, 202, 7, 12, 0, 0, 202, 203, - 7, 14, 0, 0, 203, 204, 7, 5, 0, 0, 204, 205, 7, 12, 0, 0, 205, 39, 1, 0, - 0, 0, 206, 207, 7, 8, 0, 0, 207, 208, 7, 1, 0, 0, 208, 209, 7, 13, 0, 0, - 209, 210, 7, 14, 0, 0, 210, 211, 7, 5, 0, 0, 211, 212, 7, 12, 0, 0, 212, - 41, 1, 0, 0, 0, 213, 214, 7, 12, 0, 0, 214, 215, 7, 10, 0, 0, 215, 216, - 7, 2, 0, 0, 216, 218, 1, 0, 0, 0, 217, 219, 3, 108, 53, 0, 218, 217, 1, - 0, 0, 0, 218, 219, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 221, 7, 12, 0, - 0, 221, 222, 7, 6, 0, 0, 222, 223, 7, 14, 0, 0, 223, 224, 7, 14, 0, 0, - 224, 43, 1, 0, 0, 0, 225, 226, 7, 9, 0, 0, 226, 227, 7, 11, 0, 0, 227, - 228, 7, 7, 0, 0, 228, 229, 7, 8, 0, 0, 229, 230, 7, 1, 0, 0, 230, 231, - 7, 11, 0, 0, 231, 232, 7, 15, 0, 0, 232, 235, 1, 0, 0, 0, 233, 236, 5, - 95, 0, 0, 234, 236, 3, 108, 53, 0, 235, 233, 1, 0, 0, 0, 235, 234, 1, 0, - 0, 0, 235, 236, 1, 0, 0, 0, 236, 240, 1, 0, 0, 0, 237, 238, 7, 16, 0, 0, - 238, 239, 7, 5, 0, 0, 239, 241, 7, 15, 0, 0, 240, 237, 1, 0, 0, 0, 240, - 241, 1, 0, 0, 0, 241, 45, 1, 0, 0, 0, 242, 243, 7, 0, 0, 0, 243, 244, 7, - 5, 0, 0, 244, 245, 7, 17, 0, 0, 245, 246, 7, 1, 0, 0, 246, 247, 7, 6, 0, - 0, 247, 248, 7, 14, 0, 0, 248, 249, 7, 2, 0, 0, 249, 47, 1, 0, 0, 0, 250, - 251, 7, 6, 0, 0, 251, 252, 7, 12, 0, 0, 252, 253, 7, 7, 0, 0, 253, 254, - 7, 18, 0, 0, 254, 255, 7, 6, 0, 0, 255, 256, 7, 5, 0, 0, 256, 49, 1, 0, - 0, 0, 257, 258, 7, 7, 0, 0, 258, 259, 7, 12, 0, 0, 259, 260, 7, 0, 0, 0, - 260, 261, 7, 5, 0, 0, 261, 262, 7, 13, 0, 0, 262, 51, 1, 0, 0, 0, 263, - 264, 7, 2, 0, 0, 264, 265, 7, 1, 0, 0, 265, 266, 7, 3, 0, 0, 266, 267, - 7, 14, 0, 0, 267, 268, 7, 5, 0, 0, 268, 53, 1, 0, 0, 0, 269, 270, 7, 2, - 0, 0, 270, 271, 7, 15, 0, 0, 271, 272, 7, 9, 0, 0, 272, 273, 7, 5, 0, 0, - 273, 55, 1, 0, 0, 0, 274, 275, 7, 11, 0, 0, 275, 276, 7, 5, 0, 0, 276, - 277, 7, 2, 0, 0, 277, 278, 7, 6, 0, 0, 278, 279, 7, 11, 0, 0, 279, 280, - 7, 12, 0, 0, 280, 281, 7, 4, 0, 0, 281, 57, 1, 0, 0, 0, 282, 283, 7, 17, - 0, 0, 283, 284, 7, 10, 0, 0, 284, 285, 7, 11, 0, 0, 285, 286, 7, 5, 0, - 0, 286, 287, 7, 7, 0, 0, 287, 288, 7, 19, 0, 0, 288, 289, 7, 12, 0, 0, - 289, 292, 1, 0, 0, 0, 290, 293, 5, 95, 0, 0, 291, 293, 3, 108, 53, 0, 292, - 290, 1, 0, 0, 0, 292, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, - 7, 16, 0, 0, 295, 296, 7, 5, 0, 0, 296, 300, 7, 15, 0, 0, 297, 298, 7, - 17, 0, 0, 298, 300, 7, 16, 0, 0, 299, 282, 1, 0, 0, 0, 299, 297, 1, 0, - 0, 0, 300, 59, 1, 0, 0, 0, 301, 302, 7, 17, 0, 0, 302, 303, 7, 10, 0, 0, - 303, 304, 7, 11, 0, 0, 304, 305, 7, 5, 0, 0, 305, 306, 7, 7, 0, 0, 306, - 307, 7, 19, 0, 0, 307, 308, 7, 12, 0, 0, 308, 309, 1, 0, 0, 0, 309, 310, - 3, 108, 53, 0, 310, 311, 7, 9, 0, 0, 311, 312, 7, 11, 0, 0, 312, 313, 7, - 10, 0, 0, 313, 314, 7, 20, 0, 0, 314, 315, 7, 5, 0, 0, 315, 316, 7, 0, - 0, 0, 316, 317, 7, 6, 0, 0, 317, 318, 7, 11, 0, 0, 318, 319, 7, 5, 0, 0, - 319, 61, 1, 0, 0, 0, 320, 321, 7, 11, 0, 0, 321, 322, 7, 5, 0, 0, 322, - 323, 7, 17, 0, 0, 323, 324, 7, 5, 0, 0, 324, 325, 7, 11, 0, 0, 325, 326, - 7, 5, 0, 0, 326, 327, 7, 12, 0, 0, 327, 328, 7, 20, 0, 0, 328, 329, 7, - 5, 0, 0, 329, 334, 7, 4, 0, 0, 330, 331, 7, 11, 0, 0, 331, 332, 7, 5, 0, - 0, 332, 334, 7, 17, 0, 0, 333, 320, 1, 0, 0, 0, 333, 330, 1, 0, 0, 0, 334, - 63, 1, 0, 0, 0, 335, 336, 7, 10, 0, 0, 336, 337, 7, 12, 0, 0, 337, 340, - 1, 0, 0, 0, 338, 341, 5, 95, 0, 0, 339, 341, 3, 108, 53, 0, 340, 338, 1, - 0, 0, 0, 340, 339, 1, 0, 0, 0, 341, 342, 1, 0, 0, 0, 342, 343, 7, 6, 0, - 0, 343, 344, 7, 9, 0, 0, 344, 345, 7, 0, 0, 0, 345, 346, 7, 1, 0, 0, 346, - 347, 7, 2, 0, 0, 347, 348, 7, 5, 0, 0, 348, 65, 1, 0, 0, 0, 349, 350, 7, - 10, 0, 0, 350, 351, 7, 12, 0, 0, 351, 354, 1, 0, 0, 0, 352, 355, 5, 95, - 0, 0, 353, 355, 3, 108, 53, 0, 354, 352, 1, 0, 0, 0, 354, 353, 1, 0, 0, - 0, 355, 356, 1, 0, 0, 0, 356, 357, 7, 0, 0, 0, 357, 358, 7, 5, 0, 0, 358, - 359, 7, 14, 0, 0, 359, 360, 7, 5, 0, 0, 360, 361, 7, 2, 0, 0, 361, 362, - 7, 5, 0, 0, 362, 67, 1, 0, 0, 0, 363, 364, 7, 12, 0, 0, 364, 365, 7, 10, - 0, 0, 365, 368, 1, 0, 0, 0, 366, 369, 5, 95, 0, 0, 367, 369, 3, 108, 53, - 0, 368, 366, 1, 0, 0, 0, 368, 367, 1, 0, 0, 0, 369, 370, 1, 0, 0, 0, 370, - 371, 7, 1, 0, 0, 371, 372, 7, 20, 0, 0, 372, 373, 7, 2, 0, 0, 373, 374, - 7, 7, 0, 0, 374, 375, 7, 10, 0, 0, 375, 376, 7, 12, 0, 0, 376, 69, 1, 0, - 0, 0, 377, 378, 7, 20, 0, 0, 378, 379, 7, 1, 0, 0, 379, 380, 7, 4, 0, 0, - 380, 381, 7, 20, 0, 0, 381, 382, 7, 1, 0, 0, 382, 383, 7, 0, 0, 0, 383, - 384, 7, 5, 0, 0, 384, 71, 1, 0, 0, 0, 385, 386, 7, 4, 0, 0, 386, 387, 7, - 5, 0, 0, 387, 388, 7, 2, 0, 0, 388, 391, 1, 0, 0, 0, 389, 392, 5, 95, 0, - 0, 390, 392, 3, 108, 53, 0, 391, 389, 1, 0, 0, 0, 391, 390, 1, 0, 0, 0, - 392, 393, 1, 0, 0, 0, 393, 394, 7, 12, 0, 0, 394, 395, 7, 6, 0, 0, 395, - 396, 7, 14, 0, 0, 396, 397, 7, 14, 0, 0, 397, 73, 1, 0, 0, 0, 398, 399, - 7, 4, 0, 0, 399, 400, 7, 5, 0, 0, 400, 401, 7, 2, 0, 0, 401, 404, 1, 0, - 0, 0, 402, 405, 5, 95, 0, 0, 403, 405, 3, 108, 53, 0, 404, 402, 1, 0, 0, - 0, 404, 403, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 407, 7, 0, 0, 0, 407, - 408, 7, 5, 0, 0, 408, 409, 7, 17, 0, 0, 409, 410, 7, 1, 0, 0, 410, 411, - 7, 6, 0, 0, 411, 412, 7, 14, 0, 0, 412, 413, 7, 2, 0, 0, 413, 75, 1, 0, - 0, 0, 414, 415, 7, 11, 0, 0, 415, 416, 7, 5, 0, 0, 416, 417, 7, 4, 0, 0, - 417, 418, 7, 2, 0, 0, 418, 419, 7, 11, 0, 0, 419, 420, 7, 7, 0, 0, 420, - 421, 7, 20, 0, 0, 421, 422, 7, 2, 0, 0, 422, 77, 1, 0, 0, 0, 423, 424, - 7, 0, 0, 0, 424, 425, 7, 10, 0, 0, 425, 79, 1, 0, 0, 0, 426, 427, 7, 1, - 0, 0, 427, 428, 7, 20, 0, 0, 428, 429, 7, 2, 0, 0, 429, 430, 7, 7, 0, 0, - 430, 431, 7, 10, 0, 0, 431, 432, 7, 12, 0, 0, 432, 433, 1, 0, 0, 0, 433, - 434, 6, 39, 0, 0, 434, 81, 1, 0, 0, 0, 435, 436, 7, 9, 0, 0, 436, 437, - 7, 11, 0, 0, 437, 438, 7, 10, 0, 0, 438, 439, 7, 20, 0, 0, 439, 440, 7, - 5, 0, 0, 440, 441, 7, 0, 0, 0, 441, 442, 7, 6, 0, 0, 442, 443, 7, 11, 0, - 0, 443, 444, 7, 5, 0, 0, 444, 445, 1, 0, 0, 0, 445, 446, 6, 40, 0, 0, 446, - 83, 1, 0, 0, 0, 447, 449, 7, 21, 0, 0, 448, 447, 1, 0, 0, 0, 448, 449, - 1, 0, 0, 0, 449, 451, 1, 0, 0, 0, 450, 452, 7, 22, 0, 0, 451, 450, 1, 0, - 0, 0, 452, 453, 1, 0, 0, 0, 453, 451, 1, 0, 0, 0, 453, 454, 1, 0, 0, 0, - 454, 85, 1, 0, 0, 0, 455, 461, 5, 39, 0, 0, 456, 460, 8, 23, 0, 0, 457, - 458, 5, 92, 0, 0, 458, 460, 9, 0, 0, 0, 459, 456, 1, 0, 0, 0, 459, 457, - 1, 0, 0, 0, 460, 463, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 461, 462, 1, 0, - 0, 0, 462, 464, 1, 0, 0, 0, 463, 461, 1, 0, 0, 0, 464, 465, 5, 39, 0, 0, - 465, 87, 1, 0, 0, 0, 466, 467, 7, 2, 0, 0, 467, 468, 7, 11, 0, 0, 468, - 469, 7, 6, 0, 0, 469, 476, 7, 5, 0, 0, 470, 471, 7, 17, 0, 0, 471, 472, - 7, 1, 0, 0, 472, 473, 7, 14, 0, 0, 473, 474, 7, 4, 0, 0, 474, 476, 7, 5, - 0, 0, 475, 466, 1, 0, 0, 0, 475, 470, 1, 0, 0, 0, 476, 89, 1, 0, 0, 0, - 477, 478, 5, 48, 0, 0, 478, 479, 7, 13, 0, 0, 479, 481, 1, 0, 0, 0, 480, - 482, 7, 24, 0, 0, 481, 480, 1, 0, 0, 0, 482, 483, 1, 0, 0, 0, 483, 481, - 1, 0, 0, 0, 483, 484, 1, 0, 0, 0, 484, 91, 1, 0, 0, 0, 485, 486, 5, 36, - 0, 0, 486, 487, 3, 96, 47, 0, 487, 93, 1, 0, 0, 0, 488, 489, 5, 35, 0, - 0, 489, 490, 3, 96, 47, 0, 490, 95, 1, 0, 0, 0, 491, 495, 7, 25, 0, 0, - 492, 494, 7, 26, 0, 0, 493, 492, 1, 0, 0, 0, 494, 497, 1, 0, 0, 0, 495, - 493, 1, 0, 0, 0, 495, 496, 1, 0, 0, 0, 496, 97, 1, 0, 0, 0, 497, 495, 1, - 0, 0, 0, 498, 500, 5, 64, 0, 0, 499, 501, 8, 27, 0, 0, 500, 499, 1, 0, - 0, 0, 501, 502, 1, 0, 0, 0, 502, 500, 1, 0, 0, 0, 502, 503, 1, 0, 0, 0, - 503, 99, 1, 0, 0, 0, 504, 505, 7, 28, 0, 0, 505, 506, 1, 0, 0, 0, 506, - 507, 6, 49, 1, 0, 507, 101, 1, 0, 0, 0, 508, 510, 7, 29, 0, 0, 509, 508, - 1, 0, 0, 0, 510, 511, 1, 0, 0, 0, 511, 509, 1, 0, 0, 0, 511, 512, 1, 0, - 0, 0, 512, 513, 1, 0, 0, 0, 513, 514, 6, 50, 1, 0, 514, 103, 1, 0, 0, 0, - 515, 516, 5, 47, 0, 0, 516, 517, 5, 42, 0, 0, 517, 521, 1, 0, 0, 0, 518, - 520, 9, 0, 0, 0, 519, 518, 1, 0, 0, 0, 520, 523, 1, 0, 0, 0, 521, 522, - 1, 0, 0, 0, 521, 519, 1, 0, 0, 0, 522, 524, 1, 0, 0, 0, 523, 521, 1, 0, - 0, 0, 524, 525, 5, 42, 0, 0, 525, 526, 5, 47, 0, 0, 526, 527, 1, 0, 0, - 0, 527, 528, 6, 51, 1, 0, 528, 105, 1, 0, 0, 0, 529, 530, 5, 47, 0, 0, - 530, 531, 5, 47, 0, 0, 531, 535, 1, 0, 0, 0, 532, 534, 8, 29, 0, 0, 533, - 532, 1, 0, 0, 0, 534, 537, 1, 0, 0, 0, 535, 533, 1, 0, 0, 0, 535, 536, - 1, 0, 0, 0, 536, 538, 1, 0, 0, 0, 537, 535, 1, 0, 0, 0, 538, 539, 6, 52, - 1, 0, 539, 107, 1, 0, 0, 0, 540, 542, 7, 28, 0, 0, 541, 540, 1, 0, 0, 0, - 542, 543, 1, 0, 0, 0, 543, 541, 1, 0, 0, 0, 543, 544, 1, 0, 0, 0, 544, - 109, 1, 0, 0, 0, 545, 546, 7, 22, 0, 0, 546, 111, 1, 0, 0, 0, 547, 548, - 5, 47, 0, 0, 548, 549, 5, 47, 0, 0, 549, 553, 1, 0, 0, 0, 550, 552, 8, - 29, 0, 0, 551, 550, 1, 0, 0, 0, 552, 555, 1, 0, 0, 0, 553, 551, 1, 0, 0, - 0, 553, 554, 1, 0, 0, 0, 554, 557, 1, 0, 0, 0, 555, 553, 1, 0, 0, 0, 556, - 558, 5, 13, 0, 0, 557, 556, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 558, 559, - 1, 0, 0, 0, 559, 572, 5, 10, 0, 0, 560, 561, 5, 47, 0, 0, 561, 562, 5, - 42, 0, 0, 562, 566, 1, 0, 0, 0, 563, 565, 9, 0, 0, 0, 564, 563, 1, 0, 0, - 0, 565, 568, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 566, 564, 1, 0, 0, 0, 567, - 569, 1, 0, 0, 0, 568, 566, 1, 0, 0, 0, 569, 570, 5, 42, 0, 0, 570, 572, - 5, 47, 0, 0, 571, 547, 1, 0, 0, 0, 571, 560, 1, 0, 0, 0, 572, 573, 1, 0, - 0, 0, 573, 574, 6, 55, 2, 0, 574, 113, 1, 0, 0, 0, 575, 582, 3, 2, 0, 0, - 576, 581, 3, 112, 55, 0, 577, 581, 3, 142, 70, 0, 578, 581, 3, 114, 56, - 0, 579, 581, 3, 116, 57, 0, 580, 576, 1, 0, 0, 0, 580, 577, 1, 0, 0, 0, - 580, 578, 1, 0, 0, 0, 580, 579, 1, 0, 0, 0, 581, 584, 1, 0, 0, 0, 582, - 580, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 583, 585, 1, 0, 0, 0, 584, 582, - 1, 0, 0, 0, 585, 586, 3, 4, 1, 0, 586, 587, 1, 0, 0, 0, 587, 588, 6, 56, - 3, 0, 588, 115, 1, 0, 0, 0, 589, 595, 5, 39, 0, 0, 590, 591, 5, 92, 0, - 0, 591, 594, 5, 39, 0, 0, 592, 594, 8, 30, 0, 0, 593, 590, 1, 0, 0, 0, - 593, 592, 1, 0, 0, 0, 594, 597, 1, 0, 0, 0, 595, 593, 1, 0, 0, 0, 595, - 596, 1, 0, 0, 0, 596, 598, 1, 0, 0, 0, 597, 595, 1, 0, 0, 0, 598, 599, - 5, 39, 0, 0, 599, 117, 1, 0, 0, 0, 600, 601, 3, 14, 6, 0, 601, 119, 1, - 0, 0, 0, 602, 603, 3, 16, 7, 0, 603, 121, 1, 0, 0, 0, 604, 605, 3, 18, - 8, 0, 605, 123, 1, 0, 0, 0, 606, 607, 3, 22, 10, 0, 607, 125, 1, 0, 0, - 0, 608, 609, 3, 56, 27, 0, 609, 127, 1, 0, 0, 0, 610, 611, 3, 52, 25, 0, - 611, 129, 1, 0, 0, 0, 612, 613, 3, 6, 2, 0, 613, 614, 3, 8, 3, 0, 614, - 131, 1, 0, 0, 0, 615, 616, 5, 36, 0, 0, 616, 617, 3, 96, 47, 0, 617, 133, - 1, 0, 0, 0, 618, 619, 7, 9, 0, 0, 619, 620, 7, 6, 0, 0, 620, 621, 7, 3, - 0, 0, 621, 622, 7, 14, 0, 0, 622, 623, 7, 7, 0, 0, 623, 641, 7, 20, 0, - 0, 624, 625, 7, 9, 0, 0, 625, 626, 7, 11, 0, 0, 626, 627, 7, 7, 0, 0, 627, - 628, 7, 31, 0, 0, 628, 629, 7, 1, 0, 0, 629, 630, 7, 2, 0, 0, 630, 641, - 7, 5, 0, 0, 631, 632, 7, 31, 0, 0, 632, 633, 7, 7, 0, 0, 633, 634, 7, 5, - 0, 0, 634, 641, 7, 32, 0, 0, 635, 636, 7, 10, 0, 0, 636, 637, 7, 32, 0, - 0, 637, 638, 7, 12, 0, 0, 638, 639, 7, 5, 0, 0, 639, 641, 7, 11, 0, 0, - 640, 618, 1, 0, 0, 0, 640, 624, 1, 0, 0, 0, 640, 631, 1, 0, 0, 0, 640, - 635, 1, 0, 0, 0, 641, 135, 1, 0, 0, 0, 642, 643, 3, 96, 47, 0, 643, 137, - 1, 0, 0, 0, 644, 645, 3, 100, 49, 0, 645, 646, 1, 0, 0, 0, 646, 647, 6, - 68, 1, 0, 647, 139, 1, 0, 0, 0, 648, 649, 3, 102, 50, 0, 649, 650, 1, 0, - 0, 0, 650, 651, 6, 69, 1, 0, 651, 141, 1, 0, 0, 0, 652, 654, 8, 33, 0, - 0, 653, 652, 1, 0, 0, 0, 654, 655, 1, 0, 0, 0, 655, 653, 1, 0, 0, 0, 655, - 656, 1, 0, 0, 0, 656, 143, 1, 0, 0, 0, 35, 0, 1, 218, 235, 240, 292, 299, - 333, 340, 354, 368, 391, 404, 448, 453, 459, 461, 475, 483, 495, 502, 511, - 521, 535, 543, 553, 557, 566, 571, 580, 582, 593, 595, 640, 655, 4, 5, - 1, 0, 0, 1, 0, 6, 0, 0, 4, 0, 0, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// KuneiformLexerInit initializes any static state used to implement KuneiformLexer. By default the -// static state used to implement the lexer is lazily initialized during the first call to -// NewKuneiformLexer(). You can call this function if you wish to initialize the static state ahead -// of time. -func KuneiformLexerInit() { - staticData := &KuneiformLexerLexerStaticData - staticData.once.Do(kuneiformlexerLexerInit) -} - -// NewKuneiformLexer produces a new lexer instance for the optional input antlr.CharStream. -func NewKuneiformLexer(input antlr.CharStream) *KuneiformLexer { - KuneiformLexerInit() - l := new(KuneiformLexer) - l.BaseLexer = antlr.NewBaseLexer(input) - staticData := &KuneiformLexerLexerStaticData - l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - l.channelNames = staticData.ChannelNames - l.modeNames = staticData.ModeNames - l.RuleNames = staticData.RuleNames - l.LiteralNames = staticData.LiteralNames - l.SymbolicNames = staticData.SymbolicNames - l.GrammarFileName = "KuneiformLexer.g4" - // TODO: l.EOF = antlr.TokenEOF - - return l -} - -// KuneiformLexer tokens. -const ( - KuneiformLexerLBRACE = 1 - KuneiformLexerRBRACE = 2 - KuneiformLexerLBRACKET = 3 - KuneiformLexerRBRACKET = 4 - KuneiformLexerCOL = 5 - KuneiformLexerSCOL = 6 - KuneiformLexerLPAREN = 7 - KuneiformLexerRPAREN = 8 - KuneiformLexerCOMMA = 9 - KuneiformLexerAT = 10 - KuneiformLexerPERIOD = 11 - KuneiformLexerEQUALS = 12 - KuneiformLexerDATABASE = 13 - KuneiformLexerUSE = 14 - KuneiformLexerIMPORT = 15 - KuneiformLexerAS = 16 - KuneiformLexerMIN = 17 - KuneiformLexerMAX = 18 - KuneiformLexerMIN_LEN = 19 - KuneiformLexerMAX_LEN = 20 - KuneiformLexerNOT_NULL = 21 - KuneiformLexerPRIMARY = 22 - KuneiformLexerDEFAULT = 23 - KuneiformLexerUNIQUE = 24 - KuneiformLexerINDEX = 25 - KuneiformLexerTABLE = 26 - KuneiformLexerTYPE = 27 - KuneiformLexerRETURNS = 28 - KuneiformLexerFOREIGN_KEY = 29 - KuneiformLexerFOREIGN_PROCEDURE = 30 - KuneiformLexerREFERENCES = 31 - KuneiformLexerON_UPDATE = 32 - KuneiformLexerON_DELETE = 33 - KuneiformLexerDO_NO_ACTION = 34 - KuneiformLexerDO_CASCADE = 35 - KuneiformLexerDO_SET_NULL = 36 - KuneiformLexerDO_SET_DEFAULT = 37 - KuneiformLexerDO_RESTRICT = 38 - KuneiformLexerDO = 39 - KuneiformLexerSTART_ACTION = 40 - KuneiformLexerSTART_PROCEDURE = 41 - KuneiformLexerNUMERIC_LITERAL = 42 - KuneiformLexerTEXT_LITERAL = 43 - KuneiformLexerBOOLEAN_LITERAL = 44 - KuneiformLexerBLOB_LITERAL = 45 - KuneiformLexerVAR = 46 - KuneiformLexerINDEX_NAME = 47 - KuneiformLexerIDENTIFIER = 48 - KuneiformLexerANNOTATION = 49 - KuneiformLexerWS = 50 - KuneiformLexerTERMINATOR = 51 - KuneiformLexerBLOCK_COMMENT = 52 - KuneiformLexerLINE_COMMENT = 53 - KuneiformLexerCOMMENT = 54 - KuneiformLexerSTMT_BODY = 55 - KuneiformLexerTEXT = 56 - KuneiformLexerSTMT_LPAREN = 57 - KuneiformLexerSTMT_RPAREN = 58 - KuneiformLexerSTMT_COMMA = 59 - KuneiformLexerSTMT_PERIOD = 60 - KuneiformLexerSTMT_RETURNS = 61 - KuneiformLexerSTMT_TABLE = 62 - KuneiformLexerSTMT_ARRAY = 63 - KuneiformLexerSTMT_VAR = 64 - KuneiformLexerSTMT_ACCESS = 65 - KuneiformLexerSTMT_IDENTIFIER = 66 - KuneiformLexerSTMT_WS = 67 - KuneiformLexerSTMT_TERMINATOR = 68 -) - -// KuneiformLexerSTMT_MODE is the KuneiformLexer mode. -const KuneiformLexerSTMT_MODE = 1 diff --git a/parse/kuneiform/gen/kuneiform_parser.go b/parse/kuneiform/gen/kuneiform_parser.go deleted file mode 100644 index 8f6b3d2cd..000000000 --- a/parse/kuneiform/gen/kuneiform_parser.go +++ /dev/null @@ -1,5610 +0,0 @@ -// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // KuneiformParser -import ( - "fmt" - "strconv" - "sync" - - "github.com/antlr4-go/antlr/v4" -) - -// Suppress unused import errors -var _ = fmt.Printf -var _ = strconv.Itoa -var _ = sync.Once{} - -type KuneiformParser struct { - *antlr.BaseParser -} - -var KuneiformParserParserStaticData struct { - once sync.Once - serializedATN []int32 - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func kuneiformparserParserInit() { - staticData := &KuneiformParserParserStaticData - staticData.LiteralNames = []string{ - "", "'{'", "'}'", "'['", "']'", "':'", "';'", "'('", "')'", "','", "'@'", - "'.'", "'='", "'database'", "'use'", "'import'", "'as'", "'min'", "'max'", - "'minlen'", "'maxlen'", "", "", "'default'", "'unique'", "'index'", - "'table'", "'type'", "'returns'", "", "", "", "", "", "", "'cascade'", - "", "", "'restrict'", "'do'", "'action'", "'procedure'", - } - staticData.SymbolicNames = []string{ - "", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COL", "SCOL", "LPAREN", - "RPAREN", "COMMA", "AT", "PERIOD", "EQUALS", "DATABASE", "USE", "IMPORT", - "AS", "MIN", "MAX", "MIN_LEN", "MAX_LEN", "NOT_NULL", "PRIMARY", "DEFAULT", - "UNIQUE", "INDEX", "TABLE", "TYPE", "RETURNS", "FOREIGN_KEY", "FOREIGN_PROCEDURE", - "REFERENCES", "ON_UPDATE", "ON_DELETE", "DO_NO_ACTION", "DO_CASCADE", - "DO_SET_NULL", "DO_SET_DEFAULT", "DO_RESTRICT", "DO", "START_ACTION", - "START_PROCEDURE", "NUMERIC_LITERAL", "TEXT_LITERAL", "BOOLEAN_LITERAL", - "BLOB_LITERAL", "VAR", "INDEX_NAME", "IDENTIFIER", "ANNOTATION", "WS", - "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", "COMMENT", "STMT_BODY", - "TEXT", "STMT_LPAREN", "STMT_RPAREN", "STMT_COMMA", "STMT_PERIOD", "STMT_RETURNS", - "STMT_TABLE", "STMT_ARRAY", "STMT_VAR", "STMT_ACCESS", "STMT_IDENTIFIER", - "STMT_WS", "STMT_TERMINATOR", - } - staticData.RuleNames = []string{ - "program", "stmt_mode", "database_declaration", "use_declaration", "foreign_declaration", - "table_declaration", "column_def", "index_def", "foreign_key_def", "foreign_key_action", - "identifier_list", "literal", "type_selector", "type_selector_list", - "named_type_list", "typed_variable_list", "constraint", "action_declaration", - "procedure_declaration", "stmt_return", "stmt_typed_param_list", "stmt_type_selector", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 1, 68, 305, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, - 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, - 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, - 21, 7, 21, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 50, 8, 0, 10, 0, 12, 0, - 53, 9, 0, 1, 0, 1, 0, 1, 1, 5, 1, 58, 8, 1, 10, 1, 12, 1, 61, 9, 1, 1, - 1, 1, 1, 3, 1, 65, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 81, 8, 3, 1, 3, 1, 3, 3, 3, 85, - 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 96, 8, - 4, 1, 4, 1, 4, 1, 4, 3, 4, 101, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, - 4, 1, 4, 1, 4, 3, 4, 111, 8, 4, 3, 4, 113, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, - 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 123, 8, 5, 5, 5, 125, 8, 5, 10, 5, 12, 5, - 128, 9, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 5, 6, 135, 8, 6, 10, 6, 12, 6, - 138, 9, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, - 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 156, 8, 8, 10, 8, 12, 8, 159, - 9, 8, 1, 9, 1, 9, 3, 9, 163, 8, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 5, - 10, 170, 8, 10, 10, 10, 12, 10, 173, 9, 10, 1, 11, 1, 11, 1, 12, 1, 12, - 1, 12, 3, 12, 180, 8, 12, 1, 13, 1, 13, 1, 13, 5, 13, 185, 8, 13, 10, 13, - 12, 13, 188, 9, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 195, 8, 14, - 10, 14, 12, 14, 198, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 5, 15, 205, - 8, 15, 10, 15, 12, 15, 208, 9, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, - 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, - 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 234, 8, - 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 242, 8, 17, 10, 17, - 12, 17, 245, 9, 17, 3, 17, 247, 8, 17, 1, 17, 1, 17, 4, 17, 251, 8, 17, - 11, 17, 12, 17, 252, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 261, - 8, 18, 1, 18, 1, 18, 4, 18, 265, 8, 18, 11, 18, 12, 18, 266, 1, 18, 1, - 18, 3, 18, 271, 8, 18, 1, 18, 1, 18, 1, 19, 3, 19, 276, 8, 19, 1, 19, 1, - 19, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19, 284, 8, 19, 10, 19, 12, 19, 287, - 9, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 296, 8, - 20, 10, 20, 12, 20, 299, 9, 20, 1, 21, 1, 21, 3, 21, 303, 8, 21, 1, 21, - 0, 0, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 0, 4, 2, 0, 22, 22, 24, 25, 1, 0, 32, 33, 1, 0, 34, - 38, 1, 0, 42, 45, 323, 0, 44, 1, 0, 0, 0, 2, 59, 1, 0, 0, 0, 4, 66, 1, - 0, 0, 0, 6, 70, 1, 0, 0, 0, 8, 90, 1, 0, 0, 0, 10, 114, 1, 0, 0, 0, 12, - 131, 1, 0, 0, 0, 14, 139, 1, 0, 0, 0, 16, 145, 1, 0, 0, 0, 18, 160, 1, - 0, 0, 0, 20, 166, 1, 0, 0, 0, 22, 174, 1, 0, 0, 0, 24, 176, 1, 0, 0, 0, - 26, 181, 1, 0, 0, 0, 28, 189, 1, 0, 0, 0, 30, 199, 1, 0, 0, 0, 32, 233, - 1, 0, 0, 0, 34, 235, 1, 0, 0, 0, 36, 256, 1, 0, 0, 0, 38, 275, 1, 0, 0, - 0, 40, 290, 1, 0, 0, 0, 42, 300, 1, 0, 0, 0, 44, 51, 3, 4, 2, 0, 45, 50, - 3, 6, 3, 0, 46, 50, 3, 10, 5, 0, 47, 50, 3, 2, 1, 0, 48, 50, 3, 8, 4, 0, - 49, 45, 1, 0, 0, 0, 49, 46, 1, 0, 0, 0, 49, 47, 1, 0, 0, 0, 49, 48, 1, - 0, 0, 0, 50, 53, 1, 0, 0, 0, 51, 49, 1, 0, 0, 0, 51, 52, 1, 0, 0, 0, 52, - 54, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 54, 55, 5, 0, 0, 1, 55, 1, 1, 0, 0, - 0, 56, 58, 5, 49, 0, 0, 57, 56, 1, 0, 0, 0, 58, 61, 1, 0, 0, 0, 59, 57, - 1, 0, 0, 0, 59, 60, 1, 0, 0, 0, 60, 64, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, - 62, 65, 3, 34, 17, 0, 63, 65, 3, 36, 18, 0, 64, 62, 1, 0, 0, 0, 64, 63, - 1, 0, 0, 0, 65, 3, 1, 0, 0, 0, 66, 67, 5, 13, 0, 0, 67, 68, 5, 48, 0, 0, - 68, 69, 5, 6, 0, 0, 69, 5, 1, 0, 0, 0, 70, 71, 5, 14, 0, 0, 71, 84, 5, - 48, 0, 0, 72, 73, 5, 1, 0, 0, 73, 74, 5, 48, 0, 0, 74, 75, 5, 5, 0, 0, - 75, 80, 3, 22, 11, 0, 76, 77, 5, 9, 0, 0, 77, 78, 5, 48, 0, 0, 78, 79, - 5, 5, 0, 0, 79, 81, 3, 22, 11, 0, 80, 76, 1, 0, 0, 0, 80, 81, 1, 0, 0, - 0, 81, 82, 1, 0, 0, 0, 82, 83, 5, 2, 0, 0, 83, 85, 1, 0, 0, 0, 84, 72, - 1, 0, 0, 0, 84, 85, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 87, 5, 16, 0, 0, - 87, 88, 5, 48, 0, 0, 88, 89, 5, 6, 0, 0, 89, 7, 1, 0, 0, 0, 90, 91, 5, - 30, 0, 0, 91, 92, 5, 48, 0, 0, 92, 95, 5, 7, 0, 0, 93, 96, 3, 26, 13, 0, - 94, 96, 3, 30, 15, 0, 95, 93, 1, 0, 0, 0, 95, 94, 1, 0, 0, 0, 95, 96, 1, - 0, 0, 0, 96, 97, 1, 0, 0, 0, 97, 112, 5, 8, 0, 0, 98, 110, 5, 28, 0, 0, - 99, 101, 5, 26, 0, 0, 100, 99, 1, 0, 0, 0, 100, 101, 1, 0, 0, 0, 101, 102, - 1, 0, 0, 0, 102, 103, 5, 7, 0, 0, 103, 104, 3, 28, 14, 0, 104, 105, 5, - 8, 0, 0, 105, 111, 1, 0, 0, 0, 106, 107, 5, 7, 0, 0, 107, 108, 3, 26, 13, - 0, 108, 109, 5, 8, 0, 0, 109, 111, 1, 0, 0, 0, 110, 100, 1, 0, 0, 0, 110, - 106, 1, 0, 0, 0, 111, 113, 1, 0, 0, 0, 112, 98, 1, 0, 0, 0, 112, 113, 1, - 0, 0, 0, 113, 9, 1, 0, 0, 0, 114, 115, 5, 26, 0, 0, 115, 116, 5, 48, 0, - 0, 116, 117, 5, 1, 0, 0, 117, 126, 3, 12, 6, 0, 118, 122, 5, 9, 0, 0, 119, - 123, 3, 12, 6, 0, 120, 123, 3, 14, 7, 0, 121, 123, 3, 16, 8, 0, 122, 119, - 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 121, 1, 0, 0, 0, 123, 125, 1, 0, - 0, 0, 124, 118, 1, 0, 0, 0, 125, 128, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, - 126, 127, 1, 0, 0, 0, 127, 129, 1, 0, 0, 0, 128, 126, 1, 0, 0, 0, 129, - 130, 5, 2, 0, 0, 130, 11, 1, 0, 0, 0, 131, 132, 5, 48, 0, 0, 132, 136, - 3, 24, 12, 0, 133, 135, 3, 32, 16, 0, 134, 133, 1, 0, 0, 0, 135, 138, 1, - 0, 0, 0, 136, 134, 1, 0, 0, 0, 136, 137, 1, 0, 0, 0, 137, 13, 1, 0, 0, - 0, 138, 136, 1, 0, 0, 0, 139, 140, 5, 47, 0, 0, 140, 141, 7, 0, 0, 0, 141, - 142, 5, 7, 0, 0, 142, 143, 3, 20, 10, 0, 143, 144, 5, 8, 0, 0, 144, 15, - 1, 0, 0, 0, 145, 146, 5, 29, 0, 0, 146, 147, 5, 7, 0, 0, 147, 148, 3, 20, - 10, 0, 148, 149, 5, 8, 0, 0, 149, 150, 5, 31, 0, 0, 150, 151, 5, 48, 0, - 0, 151, 152, 5, 7, 0, 0, 152, 153, 3, 20, 10, 0, 153, 157, 5, 8, 0, 0, - 154, 156, 3, 18, 9, 0, 155, 154, 1, 0, 0, 0, 156, 159, 1, 0, 0, 0, 157, - 155, 1, 0, 0, 0, 157, 158, 1, 0, 0, 0, 158, 17, 1, 0, 0, 0, 159, 157, 1, - 0, 0, 0, 160, 162, 7, 1, 0, 0, 161, 163, 5, 39, 0, 0, 162, 161, 1, 0, 0, - 0, 162, 163, 1, 0, 0, 0, 163, 164, 1, 0, 0, 0, 164, 165, 7, 2, 0, 0, 165, - 19, 1, 0, 0, 0, 166, 171, 5, 48, 0, 0, 167, 168, 5, 9, 0, 0, 168, 170, - 5, 48, 0, 0, 169, 167, 1, 0, 0, 0, 170, 173, 1, 0, 0, 0, 171, 169, 1, 0, - 0, 0, 171, 172, 1, 0, 0, 0, 172, 21, 1, 0, 0, 0, 173, 171, 1, 0, 0, 0, - 174, 175, 7, 3, 0, 0, 175, 23, 1, 0, 0, 0, 176, 179, 5, 48, 0, 0, 177, - 178, 5, 3, 0, 0, 178, 180, 5, 4, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, - 1, 0, 0, 0, 180, 25, 1, 0, 0, 0, 181, 186, 3, 24, 12, 0, 182, 183, 5, 9, - 0, 0, 183, 185, 3, 24, 12, 0, 184, 182, 1, 0, 0, 0, 185, 188, 1, 0, 0, - 0, 186, 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 27, 1, 0, 0, 0, 188, - 186, 1, 0, 0, 0, 189, 190, 5, 48, 0, 0, 190, 196, 3, 24, 12, 0, 191, 192, - 5, 9, 0, 0, 192, 193, 5, 48, 0, 0, 193, 195, 3, 24, 12, 0, 194, 191, 1, - 0, 0, 0, 195, 198, 1, 0, 0, 0, 196, 194, 1, 0, 0, 0, 196, 197, 1, 0, 0, - 0, 197, 29, 1, 0, 0, 0, 198, 196, 1, 0, 0, 0, 199, 200, 5, 46, 0, 0, 200, - 206, 3, 24, 12, 0, 201, 202, 5, 9, 0, 0, 202, 203, 5, 46, 0, 0, 203, 205, - 3, 24, 12, 0, 204, 201, 1, 0, 0, 0, 205, 208, 1, 0, 0, 0, 206, 204, 1, - 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 31, 1, 0, 0, 0, 208, 206, 1, 0, 0, - 0, 209, 210, 5, 17, 0, 0, 210, 211, 5, 7, 0, 0, 211, 212, 5, 42, 0, 0, - 212, 234, 5, 8, 0, 0, 213, 214, 5, 18, 0, 0, 214, 215, 5, 7, 0, 0, 215, - 216, 5, 42, 0, 0, 216, 234, 5, 8, 0, 0, 217, 218, 5, 19, 0, 0, 218, 219, - 5, 7, 0, 0, 219, 220, 5, 42, 0, 0, 220, 234, 5, 8, 0, 0, 221, 222, 5, 20, - 0, 0, 222, 223, 5, 7, 0, 0, 223, 224, 5, 42, 0, 0, 224, 234, 5, 8, 0, 0, - 225, 234, 5, 21, 0, 0, 226, 234, 5, 22, 0, 0, 227, 228, 5, 23, 0, 0, 228, - 229, 5, 7, 0, 0, 229, 230, 3, 22, 11, 0, 230, 231, 5, 8, 0, 0, 231, 234, - 1, 0, 0, 0, 232, 234, 5, 24, 0, 0, 233, 209, 1, 0, 0, 0, 233, 213, 1, 0, - 0, 0, 233, 217, 1, 0, 0, 0, 233, 221, 1, 0, 0, 0, 233, 225, 1, 0, 0, 0, - 233, 226, 1, 0, 0, 0, 233, 227, 1, 0, 0, 0, 233, 232, 1, 0, 0, 0, 234, - 33, 1, 0, 0, 0, 235, 236, 5, 40, 0, 0, 236, 237, 5, 66, 0, 0, 237, 246, - 5, 57, 0, 0, 238, 243, 5, 64, 0, 0, 239, 240, 5, 59, 0, 0, 240, 242, 5, - 64, 0, 0, 241, 239, 1, 0, 0, 0, 242, 245, 1, 0, 0, 0, 243, 241, 1, 0, 0, - 0, 243, 244, 1, 0, 0, 0, 244, 247, 1, 0, 0, 0, 245, 243, 1, 0, 0, 0, 246, - 238, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 250, - 5, 58, 0, 0, 249, 251, 5, 65, 0, 0, 250, 249, 1, 0, 0, 0, 251, 252, 1, - 0, 0, 0, 252, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, 253, 254, 1, 0, 0, - 0, 254, 255, 5, 55, 0, 0, 255, 35, 1, 0, 0, 0, 256, 257, 5, 41, 0, 0, 257, - 258, 5, 66, 0, 0, 258, 260, 5, 57, 0, 0, 259, 261, 3, 40, 20, 0, 260, 259, - 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 264, 5, 58, - 0, 0, 263, 265, 5, 65, 0, 0, 264, 263, 1, 0, 0, 0, 265, 266, 1, 0, 0, 0, - 266, 264, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 270, 1, 0, 0, 0, 268, - 269, 5, 61, 0, 0, 269, 271, 3, 38, 19, 0, 270, 268, 1, 0, 0, 0, 270, 271, - 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 273, 5, 55, 0, 0, 273, 37, 1, 0, - 0, 0, 274, 276, 5, 62, 0, 0, 275, 274, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, - 276, 277, 1, 0, 0, 0, 277, 278, 5, 57, 0, 0, 278, 279, 5, 66, 0, 0, 279, - 285, 3, 42, 21, 0, 280, 281, 5, 59, 0, 0, 281, 282, 5, 66, 0, 0, 282, 284, - 3, 42, 21, 0, 283, 280, 1, 0, 0, 0, 284, 287, 1, 0, 0, 0, 285, 283, 1, - 0, 0, 0, 285, 286, 1, 0, 0, 0, 286, 288, 1, 0, 0, 0, 287, 285, 1, 0, 0, - 0, 288, 289, 5, 58, 0, 0, 289, 39, 1, 0, 0, 0, 290, 291, 5, 64, 0, 0, 291, - 297, 3, 42, 21, 0, 292, 293, 5, 59, 0, 0, 293, 294, 5, 64, 0, 0, 294, 296, - 3, 42, 21, 0, 295, 292, 1, 0, 0, 0, 296, 299, 1, 0, 0, 0, 297, 295, 1, - 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 41, 1, 0, 0, 0, 299, 297, 1, 0, 0, - 0, 300, 302, 5, 66, 0, 0, 301, 303, 5, 63, 0, 0, 302, 301, 1, 0, 0, 0, - 302, 303, 1, 0, 0, 0, 303, 43, 1, 0, 0, 0, 31, 49, 51, 59, 64, 80, 84, - 95, 100, 110, 112, 122, 126, 136, 157, 162, 171, 179, 186, 196, 206, 233, - 243, 246, 252, 260, 266, 270, 275, 285, 297, 302, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// KuneiformParserInit initializes any static state used to implement KuneiformParser. By default the -// static state used to implement the parser is lazily initialized during the first call to -// NewKuneiformParser(). You can call this function if you wish to initialize the static state ahead -// of time. -func KuneiformParserInit() { - staticData := &KuneiformParserParserStaticData - staticData.once.Do(kuneiformparserParserInit) -} - -// NewKuneiformParser produces a new parser instance for the optional input antlr.TokenStream. -func NewKuneiformParser(input antlr.TokenStream) *KuneiformParser { - KuneiformParserInit() - this := new(KuneiformParser) - this.BaseParser = antlr.NewBaseParser(input) - staticData := &KuneiformParserParserStaticData - this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - this.RuleNames = staticData.RuleNames - this.LiteralNames = staticData.LiteralNames - this.SymbolicNames = staticData.SymbolicNames - this.GrammarFileName = "KuneiformParser.g4" - - return this -} - -// KuneiformParser tokens. -const ( - KuneiformParserEOF = antlr.TokenEOF - KuneiformParserLBRACE = 1 - KuneiformParserRBRACE = 2 - KuneiformParserLBRACKET = 3 - KuneiformParserRBRACKET = 4 - KuneiformParserCOL = 5 - KuneiformParserSCOL = 6 - KuneiformParserLPAREN = 7 - KuneiformParserRPAREN = 8 - KuneiformParserCOMMA = 9 - KuneiformParserAT = 10 - KuneiformParserPERIOD = 11 - KuneiformParserEQUALS = 12 - KuneiformParserDATABASE = 13 - KuneiformParserUSE = 14 - KuneiformParserIMPORT = 15 - KuneiformParserAS = 16 - KuneiformParserMIN = 17 - KuneiformParserMAX = 18 - KuneiformParserMIN_LEN = 19 - KuneiformParserMAX_LEN = 20 - KuneiformParserNOT_NULL = 21 - KuneiformParserPRIMARY = 22 - KuneiformParserDEFAULT = 23 - KuneiformParserUNIQUE = 24 - KuneiformParserINDEX = 25 - KuneiformParserTABLE = 26 - KuneiformParserTYPE = 27 - KuneiformParserRETURNS = 28 - KuneiformParserFOREIGN_KEY = 29 - KuneiformParserFOREIGN_PROCEDURE = 30 - KuneiformParserREFERENCES = 31 - KuneiformParserON_UPDATE = 32 - KuneiformParserON_DELETE = 33 - KuneiformParserDO_NO_ACTION = 34 - KuneiformParserDO_CASCADE = 35 - KuneiformParserDO_SET_NULL = 36 - KuneiformParserDO_SET_DEFAULT = 37 - KuneiformParserDO_RESTRICT = 38 - KuneiformParserDO = 39 - KuneiformParserSTART_ACTION = 40 - KuneiformParserSTART_PROCEDURE = 41 - KuneiformParserNUMERIC_LITERAL = 42 - KuneiformParserTEXT_LITERAL = 43 - KuneiformParserBOOLEAN_LITERAL = 44 - KuneiformParserBLOB_LITERAL = 45 - KuneiformParserVAR = 46 - KuneiformParserINDEX_NAME = 47 - KuneiformParserIDENTIFIER = 48 - KuneiformParserANNOTATION = 49 - KuneiformParserWS = 50 - KuneiformParserTERMINATOR = 51 - KuneiformParserBLOCK_COMMENT = 52 - KuneiformParserLINE_COMMENT = 53 - KuneiformParserCOMMENT = 54 - KuneiformParserSTMT_BODY = 55 - KuneiformParserTEXT = 56 - KuneiformParserSTMT_LPAREN = 57 - KuneiformParserSTMT_RPAREN = 58 - KuneiformParserSTMT_COMMA = 59 - KuneiformParserSTMT_PERIOD = 60 - KuneiformParserSTMT_RETURNS = 61 - KuneiformParserSTMT_TABLE = 62 - KuneiformParserSTMT_ARRAY = 63 - KuneiformParserSTMT_VAR = 64 - KuneiformParserSTMT_ACCESS = 65 - KuneiformParserSTMT_IDENTIFIER = 66 - KuneiformParserSTMT_WS = 67 - KuneiformParserSTMT_TERMINATOR = 68 -) - -// KuneiformParser rules. -const ( - KuneiformParserRULE_program = 0 - KuneiformParserRULE_stmt_mode = 1 - KuneiformParserRULE_database_declaration = 2 - KuneiformParserRULE_use_declaration = 3 - KuneiformParserRULE_foreign_declaration = 4 - KuneiformParserRULE_table_declaration = 5 - KuneiformParserRULE_column_def = 6 - KuneiformParserRULE_index_def = 7 - KuneiformParserRULE_foreign_key_def = 8 - KuneiformParserRULE_foreign_key_action = 9 - KuneiformParserRULE_identifier_list = 10 - KuneiformParserRULE_literal = 11 - KuneiformParserRULE_type_selector = 12 - KuneiformParserRULE_type_selector_list = 13 - KuneiformParserRULE_named_type_list = 14 - KuneiformParserRULE_typed_variable_list = 15 - KuneiformParserRULE_constraint = 16 - KuneiformParserRULE_action_declaration = 17 - KuneiformParserRULE_procedure_declaration = 18 - KuneiformParserRULE_stmt_return = 19 - KuneiformParserRULE_stmt_typed_param_list = 20 - KuneiformParserRULE_stmt_type_selector = 21 -) - -// IProgramContext is an interface to support dynamic dispatch. -type IProgramContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Database_declaration() IDatabase_declarationContext - EOF() antlr.TerminalNode - AllUse_declaration() []IUse_declarationContext - Use_declaration(i int) IUse_declarationContext - AllTable_declaration() []ITable_declarationContext - Table_declaration(i int) ITable_declarationContext - AllStmt_mode() []IStmt_modeContext - Stmt_mode(i int) IStmt_modeContext - AllForeign_declaration() []IForeign_declarationContext - Foreign_declaration(i int) IForeign_declarationContext - - // IsProgramContext differentiates from other interfaces. - IsProgramContext() -} - -type ProgramContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyProgramContext() *ProgramContext { - var p = new(ProgramContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_program - return p -} - -func InitEmptyProgramContext(p *ProgramContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_program -} - -func (*ProgramContext) IsProgramContext() {} - -func NewProgramContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProgramContext { - var p = new(ProgramContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_program - - return p -} - -func (s *ProgramContext) GetParser() antlr.Parser { return s.parser } - -func (s *ProgramContext) Database_declaration() IDatabase_declarationContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IDatabase_declarationContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IDatabase_declarationContext) -} - -func (s *ProgramContext) EOF() antlr.TerminalNode { - return s.GetToken(KuneiformParserEOF, 0) -} - -func (s *ProgramContext) AllUse_declaration() []IUse_declarationContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IUse_declarationContext); ok { - len++ - } - } - - tst := make([]IUse_declarationContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IUse_declarationContext); ok { - tst[i] = t.(IUse_declarationContext) - i++ - } - } - - return tst -} - -func (s *ProgramContext) Use_declaration(i int) IUse_declarationContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUse_declarationContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IUse_declarationContext) -} - -func (s *ProgramContext) AllTable_declaration() []ITable_declarationContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ITable_declarationContext); ok { - len++ - } - } - - tst := make([]ITable_declarationContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ITable_declarationContext); ok { - tst[i] = t.(ITable_declarationContext) - i++ - } - } - - return tst -} - -func (s *ProgramContext) Table_declaration(i int) ITable_declarationContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_declarationContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ITable_declarationContext) -} - -func (s *ProgramContext) AllStmt_mode() []IStmt_modeContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStmt_modeContext); ok { - len++ - } - } - - tst := make([]IStmt_modeContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStmt_modeContext); ok { - tst[i] = t.(IStmt_modeContext) - i++ - } - } - - return tst -} - -func (s *ProgramContext) Stmt_mode(i int) IStmt_modeContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmt_modeContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStmt_modeContext) -} - -func (s *ProgramContext) AllForeign_declaration() []IForeign_declarationContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IForeign_declarationContext); ok { - len++ - } - } - - tst := make([]IForeign_declarationContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IForeign_declarationContext); ok { - tst[i] = t.(IForeign_declarationContext) - i++ - } - } - - return tst -} - -func (s *ProgramContext) Foreign_declaration(i int) IForeign_declarationContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IForeign_declarationContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IForeign_declarationContext) -} - -func (s *ProgramContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ProgramContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *ProgramContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitProgram(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Program() (localctx IProgramContext) { - localctx = NewProgramContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 0, KuneiformParserRULE_program) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(44) - p.Database_declaration() - } - p.SetState(51) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&566249629171712) != 0 { - p.SetState(49) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case KuneiformParserUSE: - { - p.SetState(45) - p.Use_declaration() - } - - case KuneiformParserTABLE: - { - p.SetState(46) - p.Table_declaration() - } - - case KuneiformParserSTART_ACTION, KuneiformParserSTART_PROCEDURE, KuneiformParserANNOTATION: - { - p.SetState(47) - p.Stmt_mode() - } - - case KuneiformParserFOREIGN_PROCEDURE: - { - p.SetState(48) - p.Foreign_declaration() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - - p.SetState(53) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(54) - p.Match(KuneiformParserEOF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStmt_modeContext is an interface to support dynamic dispatch. -type IStmt_modeContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Action_declaration() IAction_declarationContext - Procedure_declaration() IProcedure_declarationContext - AllANNOTATION() []antlr.TerminalNode - ANNOTATION(i int) antlr.TerminalNode - - // IsStmt_modeContext differentiates from other interfaces. - IsStmt_modeContext() -} - -type Stmt_modeContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStmt_modeContext() *Stmt_modeContext { - var p = new(Stmt_modeContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_mode - return p -} - -func InitEmptyStmt_modeContext(p *Stmt_modeContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_mode -} - -func (*Stmt_modeContext) IsStmt_modeContext() {} - -func NewStmt_modeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Stmt_modeContext { - var p = new(Stmt_modeContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_stmt_mode - - return p -} - -func (s *Stmt_modeContext) GetParser() antlr.Parser { return s.parser } - -func (s *Stmt_modeContext) Action_declaration() IAction_declarationContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IAction_declarationContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IAction_declarationContext) -} - -func (s *Stmt_modeContext) Procedure_declaration() IProcedure_declarationContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IProcedure_declarationContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IProcedure_declarationContext) -} - -func (s *Stmt_modeContext) AllANNOTATION() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserANNOTATION) -} - -func (s *Stmt_modeContext) ANNOTATION(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserANNOTATION, i) -} - -func (s *Stmt_modeContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_modeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Stmt_modeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitStmt_mode(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Stmt_mode() (localctx IStmt_modeContext) { - localctx = NewStmt_modeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 2, KuneiformParserRULE_stmt_mode) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(59) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserANNOTATION { - { - p.SetState(56) - p.Match(KuneiformParserANNOTATION) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(61) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(64) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case KuneiformParserSTART_ACTION: - { - p.SetState(62) - p.Action_declaration() - } - - case KuneiformParserSTART_PROCEDURE: - { - p.SetState(63) - p.Procedure_declaration() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IDatabase_declarationContext is an interface to support dynamic dispatch. -type IDatabase_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - DATABASE() antlr.TerminalNode - IDENTIFIER() antlr.TerminalNode - SCOL() antlr.TerminalNode - - // IsDatabase_declarationContext differentiates from other interfaces. - IsDatabase_declarationContext() -} - -type Database_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyDatabase_declarationContext() *Database_declarationContext { - var p = new(Database_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_database_declaration - return p -} - -func InitEmptyDatabase_declarationContext(p *Database_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_database_declaration -} - -func (*Database_declarationContext) IsDatabase_declarationContext() {} - -func NewDatabase_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Database_declarationContext { - var p = new(Database_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_database_declaration - - return p -} - -func (s *Database_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Database_declarationContext) DATABASE() antlr.TerminalNode { - return s.GetToken(KuneiformParserDATABASE, 0) -} - -func (s *Database_declarationContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Database_declarationContext) SCOL() antlr.TerminalNode { - return s.GetToken(KuneiformParserSCOL, 0) -} - -func (s *Database_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Database_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Database_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitDatabase_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Database_declaration() (localctx IDatabase_declarationContext) { - localctx = NewDatabase_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 4, KuneiformParserRULE_database_declaration) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(66) - p.Match(KuneiformParserDATABASE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(67) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(68) - p.Match(KuneiformParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUse_declarationContext is an interface to support dynamic dispatch. -type IUse_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetExtension_name returns the extension_name token. - GetExtension_name() antlr.Token - - // GetAlias returns the alias token. - GetAlias() antlr.Token - - // SetExtension_name sets the extension_name token. - SetExtension_name(antlr.Token) - - // SetAlias sets the alias token. - SetAlias(antlr.Token) - - // Getter signatures - USE() antlr.TerminalNode - AS() antlr.TerminalNode - SCOL() antlr.TerminalNode - AllIDENTIFIER() []antlr.TerminalNode - IDENTIFIER(i int) antlr.TerminalNode - LBRACE() antlr.TerminalNode - AllCOL() []antlr.TerminalNode - COL(i int) antlr.TerminalNode - AllLiteral() []ILiteralContext - Literal(i int) ILiteralContext - RBRACE() antlr.TerminalNode - COMMA() antlr.TerminalNode - - // IsUse_declarationContext differentiates from other interfaces. - IsUse_declarationContext() -} - -type Use_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - extension_name antlr.Token - alias antlr.Token -} - -func NewEmptyUse_declarationContext() *Use_declarationContext { - var p = new(Use_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_use_declaration - return p -} - -func InitEmptyUse_declarationContext(p *Use_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_use_declaration -} - -func (*Use_declarationContext) IsUse_declarationContext() {} - -func NewUse_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Use_declarationContext { - var p = new(Use_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_use_declaration - - return p -} - -func (s *Use_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Use_declarationContext) GetExtension_name() antlr.Token { return s.extension_name } - -func (s *Use_declarationContext) GetAlias() antlr.Token { return s.alias } - -func (s *Use_declarationContext) SetExtension_name(v antlr.Token) { s.extension_name = v } - -func (s *Use_declarationContext) SetAlias(v antlr.Token) { s.alias = v } - -func (s *Use_declarationContext) USE() antlr.TerminalNode { - return s.GetToken(KuneiformParserUSE, 0) -} - -func (s *Use_declarationContext) AS() antlr.TerminalNode { - return s.GetToken(KuneiformParserAS, 0) -} - -func (s *Use_declarationContext) SCOL() antlr.TerminalNode { - return s.GetToken(KuneiformParserSCOL, 0) -} - -func (s *Use_declarationContext) AllIDENTIFIER() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserIDENTIFIER) -} - -func (s *Use_declarationContext) IDENTIFIER(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, i) -} - -func (s *Use_declarationContext) LBRACE() antlr.TerminalNode { - return s.GetToken(KuneiformParserLBRACE, 0) -} - -func (s *Use_declarationContext) AllCOL() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOL) -} - -func (s *Use_declarationContext) COL(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOL, i) -} - -func (s *Use_declarationContext) AllLiteral() []ILiteralContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ILiteralContext); ok { - len++ - } - } - - tst := make([]ILiteralContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ILiteralContext); ok { - tst[i] = t.(ILiteralContext) - i++ - } - } - - return tst -} - -func (s *Use_declarationContext) Literal(i int) ILiteralContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ILiteralContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ILiteralContext) -} - -func (s *Use_declarationContext) RBRACE() antlr.TerminalNode { - return s.GetToken(KuneiformParserRBRACE, 0) -} - -func (s *Use_declarationContext) COMMA() antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, 0) -} - -func (s *Use_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Use_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Use_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitUse_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Use_declaration() (localctx IUse_declarationContext) { - localctx = NewUse_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 6, KuneiformParserRULE_use_declaration) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(70) - p.Match(KuneiformParserUSE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(71) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Use_declarationContext).extension_name = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(84) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserLBRACE { - { - p.SetState(72) - p.Match(KuneiformParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(73) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(74) - p.Match(KuneiformParserCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(75) - p.Literal() - } - p.SetState(80) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserCOMMA { - { - p.SetState(76) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(77) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(78) - p.Match(KuneiformParserCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(79) - p.Literal() - } - - } - { - p.SetState(82) - p.Match(KuneiformParserRBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(86) - p.Match(KuneiformParserAS) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(87) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Use_declarationContext).alias = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(88) - p.Match(KuneiformParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IForeign_declarationContext is an interface to support dynamic dispatch. -type IForeign_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetName returns the name token. - GetName() antlr.Token - - // SetName sets the name token. - SetName(antlr.Token) - - // GetUnnamed_params returns the unnamed_params rule contexts. - GetUnnamed_params() IType_selector_listContext - - // GetNamed_params returns the named_params rule contexts. - GetNamed_params() ITyped_variable_listContext - - // GetReturn_columns returns the return_columns rule contexts. - GetReturn_columns() INamed_type_listContext - - // GetUnnamed_return_types returns the unnamed_return_types rule contexts. - GetUnnamed_return_types() IType_selector_listContext - - // SetUnnamed_params sets the unnamed_params rule contexts. - SetUnnamed_params(IType_selector_listContext) - - // SetNamed_params sets the named_params rule contexts. - SetNamed_params(ITyped_variable_listContext) - - // SetReturn_columns sets the return_columns rule contexts. - SetReturn_columns(INamed_type_listContext) - - // SetUnnamed_return_types sets the unnamed_return_types rule contexts. - SetUnnamed_return_types(IType_selector_listContext) - - // Getter signatures - FOREIGN_PROCEDURE() antlr.TerminalNode - AllLPAREN() []antlr.TerminalNode - LPAREN(i int) antlr.TerminalNode - AllRPAREN() []antlr.TerminalNode - RPAREN(i int) antlr.TerminalNode - IDENTIFIER() antlr.TerminalNode - RETURNS() antlr.TerminalNode - AllType_selector_list() []IType_selector_listContext - Type_selector_list(i int) IType_selector_listContext - Typed_variable_list() ITyped_variable_listContext - Named_type_list() INamed_type_listContext - TABLE() antlr.TerminalNode - - // IsForeign_declarationContext differentiates from other interfaces. - IsForeign_declarationContext() -} - -type Foreign_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - name antlr.Token - unnamed_params IType_selector_listContext - named_params ITyped_variable_listContext - return_columns INamed_type_listContext - unnamed_return_types IType_selector_listContext -} - -func NewEmptyForeign_declarationContext() *Foreign_declarationContext { - var p = new(Foreign_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_declaration - return p -} - -func InitEmptyForeign_declarationContext(p *Foreign_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_declaration -} - -func (*Foreign_declarationContext) IsForeign_declarationContext() {} - -func NewForeign_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_declarationContext { - var p = new(Foreign_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_foreign_declaration - - return p -} - -func (s *Foreign_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Foreign_declarationContext) GetName() antlr.Token { return s.name } - -func (s *Foreign_declarationContext) SetName(v antlr.Token) { s.name = v } - -func (s *Foreign_declarationContext) GetUnnamed_params() IType_selector_listContext { - return s.unnamed_params -} - -func (s *Foreign_declarationContext) GetNamed_params() ITyped_variable_listContext { - return s.named_params -} - -func (s *Foreign_declarationContext) GetReturn_columns() INamed_type_listContext { - return s.return_columns -} - -func (s *Foreign_declarationContext) GetUnnamed_return_types() IType_selector_listContext { - return s.unnamed_return_types -} - -func (s *Foreign_declarationContext) SetUnnamed_params(v IType_selector_listContext) { - s.unnamed_params = v -} - -func (s *Foreign_declarationContext) SetNamed_params(v ITyped_variable_listContext) { - s.named_params = v -} - -func (s *Foreign_declarationContext) SetReturn_columns(v INamed_type_listContext) { - s.return_columns = v -} - -func (s *Foreign_declarationContext) SetUnnamed_return_types(v IType_selector_listContext) { - s.unnamed_return_types = v -} - -func (s *Foreign_declarationContext) FOREIGN_PROCEDURE() antlr.TerminalNode { - return s.GetToken(KuneiformParserFOREIGN_PROCEDURE, 0) -} - -func (s *Foreign_declarationContext) AllLPAREN() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserLPAREN) -} - -func (s *Foreign_declarationContext) LPAREN(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, i) -} - -func (s *Foreign_declarationContext) AllRPAREN() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserRPAREN) -} - -func (s *Foreign_declarationContext) RPAREN(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, i) -} - -func (s *Foreign_declarationContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Foreign_declarationContext) RETURNS() antlr.TerminalNode { - return s.GetToken(KuneiformParserRETURNS, 0) -} - -func (s *Foreign_declarationContext) AllType_selector_list() []IType_selector_listContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IType_selector_listContext); ok { - len++ - } - } - - tst := make([]IType_selector_listContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IType_selector_listContext); ok { - tst[i] = t.(IType_selector_listContext) - i++ - } - } - - return tst -} - -func (s *Foreign_declarationContext) Type_selector_list(i int) IType_selector_listContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_selector_listContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IType_selector_listContext) -} - -func (s *Foreign_declarationContext) Typed_variable_list() ITyped_variable_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITyped_variable_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITyped_variable_listContext) -} - -func (s *Foreign_declarationContext) Named_type_list() INamed_type_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(INamed_type_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(INamed_type_listContext) -} - -func (s *Foreign_declarationContext) TABLE() antlr.TerminalNode { - return s.GetToken(KuneiformParserTABLE, 0) -} - -func (s *Foreign_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Foreign_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Foreign_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitForeign_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Foreign_declaration() (localctx IForeign_declarationContext) { - localctx = NewForeign_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 8, KuneiformParserRULE_foreign_declaration) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(90) - p.Match(KuneiformParserFOREIGN_PROCEDURE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(91) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Foreign_declarationContext).name = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(92) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(95) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - switch p.GetTokenStream().LA(1) { - case KuneiformParserIDENTIFIER: - { - p.SetState(93) - - var _x = p.Type_selector_list() - - localctx.(*Foreign_declarationContext).unnamed_params = _x - } - - case KuneiformParserVAR: - { - p.SetState(94) - - var _x = p.Typed_variable_list() - - localctx.(*Foreign_declarationContext).named_params = _x - } - - case KuneiformParserRPAREN: - - default: - } - { - p.SetState(97) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(112) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserRETURNS { - { - p.SetState(98) - p.Match(KuneiformParserRETURNS) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(110) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 8, p.GetParserRuleContext()) { - case 1: - p.SetState(100) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserTABLE { - { - p.SetState(99) - p.Match(KuneiformParserTABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(102) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(103) - - var _x = p.Named_type_list() - - localctx.(*Foreign_declarationContext).return_columns = _x - } - { - p.SetState(104) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 2: - { - p.SetState(106) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(107) - - var _x = p.Type_selector_list() - - localctx.(*Foreign_declarationContext).unnamed_return_types = _x - } - { - p.SetState(108) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITable_declarationContext is an interface to support dynamic dispatch. -type ITable_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - TABLE() antlr.TerminalNode - IDENTIFIER() antlr.TerminalNode - LBRACE() antlr.TerminalNode - AllColumn_def() []IColumn_defContext - Column_def(i int) IColumn_defContext - RBRACE() antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - AllIndex_def() []IIndex_defContext - Index_def(i int) IIndex_defContext - AllForeign_key_def() []IForeign_key_defContext - Foreign_key_def(i int) IForeign_key_defContext - - // IsTable_declarationContext differentiates from other interfaces. - IsTable_declarationContext() -} - -type Table_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTable_declarationContext() *Table_declarationContext { - var p = new(Table_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_table_declaration - return p -} - -func InitEmptyTable_declarationContext(p *Table_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_table_declaration -} - -func (*Table_declarationContext) IsTable_declarationContext() {} - -func NewTable_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Table_declarationContext { - var p = new(Table_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_table_declaration - - return p -} - -func (s *Table_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Table_declarationContext) TABLE() antlr.TerminalNode { - return s.GetToken(KuneiformParserTABLE, 0) -} - -func (s *Table_declarationContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Table_declarationContext) LBRACE() antlr.TerminalNode { - return s.GetToken(KuneiformParserLBRACE, 0) -} - -func (s *Table_declarationContext) AllColumn_def() []IColumn_defContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IColumn_defContext); ok { - len++ - } - } - - tst := make([]IColumn_defContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IColumn_defContext); ok { - tst[i] = t.(IColumn_defContext) - i++ - } - } - - return tst -} - -func (s *Table_declarationContext) Column_def(i int) IColumn_defContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_defContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IColumn_defContext) -} - -func (s *Table_declarationContext) RBRACE() antlr.TerminalNode { - return s.GetToken(KuneiformParserRBRACE, 0) -} - -func (s *Table_declarationContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOMMA) -} - -func (s *Table_declarationContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, i) -} - -func (s *Table_declarationContext) AllIndex_def() []IIndex_defContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IIndex_defContext); ok { - len++ - } - } - - tst := make([]IIndex_defContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IIndex_defContext); ok { - tst[i] = t.(IIndex_defContext) - i++ - } - } - - return tst -} - -func (s *Table_declarationContext) Index_def(i int) IIndex_defContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IIndex_defContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IIndex_defContext) -} - -func (s *Table_declarationContext) AllForeign_key_def() []IForeign_key_defContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IForeign_key_defContext); ok { - len++ - } - } - - tst := make([]IForeign_key_defContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IForeign_key_defContext); ok { - tst[i] = t.(IForeign_key_defContext) - i++ - } - } - - return tst -} - -func (s *Table_declarationContext) Foreign_key_def(i int) IForeign_key_defContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IForeign_key_defContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IForeign_key_defContext) -} - -func (s *Table_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Table_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Table_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitTable_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Table_declaration() (localctx ITable_declarationContext) { - localctx = NewTable_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 10, KuneiformParserRULE_table_declaration) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(114) - p.Match(KuneiformParserTABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(115) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(116) - p.Match(KuneiformParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(117) - p.Column_def() - } - p.SetState(126) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserCOMMA { - { - p.SetState(118) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(122) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case KuneiformParserIDENTIFIER: - { - p.SetState(119) - p.Column_def() - } - - case KuneiformParserINDEX_NAME: - { - p.SetState(120) - p.Index_def() - } - - case KuneiformParserFOREIGN_KEY: - { - p.SetState(121) - p.Foreign_key_def() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - - p.SetState(128) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(129) - p.Match(KuneiformParserRBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IColumn_defContext is an interface to support dynamic dispatch. -type IColumn_defContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetName returns the name token. - GetName() antlr.Token - - // SetName sets the name token. - SetName(antlr.Token) - - // GetType_ returns the type_ rule contexts. - GetType_() IType_selectorContext - - // SetType_ sets the type_ rule contexts. - SetType_(IType_selectorContext) - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - Type_selector() IType_selectorContext - AllConstraint() []IConstraintContext - Constraint(i int) IConstraintContext - - // IsColumn_defContext differentiates from other interfaces. - IsColumn_defContext() -} - -type Column_defContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - name antlr.Token - type_ IType_selectorContext -} - -func NewEmptyColumn_defContext() *Column_defContext { - var p = new(Column_defContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_column_def - return p -} - -func InitEmptyColumn_defContext(p *Column_defContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_column_def -} - -func (*Column_defContext) IsColumn_defContext() {} - -func NewColumn_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_defContext { - var p = new(Column_defContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_column_def - - return p -} - -func (s *Column_defContext) GetParser() antlr.Parser { return s.parser } - -func (s *Column_defContext) GetName() antlr.Token { return s.name } - -func (s *Column_defContext) SetName(v antlr.Token) { s.name = v } - -func (s *Column_defContext) GetType_() IType_selectorContext { return s.type_ } - -func (s *Column_defContext) SetType_(v IType_selectorContext) { s.type_ = v } - -func (s *Column_defContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Column_defContext) Type_selector() IType_selectorContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_selectorContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_selectorContext) -} - -func (s *Column_defContext) AllConstraint() []IConstraintContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IConstraintContext); ok { - len++ - } - } - - tst := make([]IConstraintContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IConstraintContext); ok { - tst[i] = t.(IConstraintContext) - i++ - } - } - - return tst -} - -func (s *Column_defContext) Constraint(i int) IConstraintContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IConstraintContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IConstraintContext) -} - -func (s *Column_defContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Column_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitColumn_def(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Column_def() (localctx IColumn_defContext) { - localctx = NewColumn_defContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 12, KuneiformParserRULE_column_def) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(131) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Column_defContext).name = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(132) - - var _x = p.Type_selector() - - localctx.(*Column_defContext).type_ = _x - } - p.SetState(136) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&33423360) != 0 { - { - p.SetState(133) - p.Constraint() - } - - p.SetState(138) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IIndex_defContext is an interface to support dynamic dispatch. -type IIndex_defContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetColumns returns the columns rule contexts. - GetColumns() IIdentifier_listContext - - // SetColumns sets the columns rule contexts. - SetColumns(IIdentifier_listContext) - - // Getter signatures - INDEX_NAME() antlr.TerminalNode - LPAREN() antlr.TerminalNode - RPAREN() antlr.TerminalNode - UNIQUE() antlr.TerminalNode - INDEX() antlr.TerminalNode - PRIMARY() antlr.TerminalNode - Identifier_list() IIdentifier_listContext - - // IsIndex_defContext differentiates from other interfaces. - IsIndex_defContext() -} - -type Index_defContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - columns IIdentifier_listContext -} - -func NewEmptyIndex_defContext() *Index_defContext { - var p = new(Index_defContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_index_def - return p -} - -func InitEmptyIndex_defContext(p *Index_defContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_index_def -} - -func (*Index_defContext) IsIndex_defContext() {} - -func NewIndex_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Index_defContext { - var p = new(Index_defContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_index_def - - return p -} - -func (s *Index_defContext) GetParser() antlr.Parser { return s.parser } - -func (s *Index_defContext) GetColumns() IIdentifier_listContext { return s.columns } - -func (s *Index_defContext) SetColumns(v IIdentifier_listContext) { s.columns = v } - -func (s *Index_defContext) INDEX_NAME() antlr.TerminalNode { - return s.GetToken(KuneiformParserINDEX_NAME, 0) -} - -func (s *Index_defContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *Index_defContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *Index_defContext) UNIQUE() antlr.TerminalNode { - return s.GetToken(KuneiformParserUNIQUE, 0) -} - -func (s *Index_defContext) INDEX() antlr.TerminalNode { - return s.GetToken(KuneiformParserINDEX, 0) -} - -func (s *Index_defContext) PRIMARY() antlr.TerminalNode { - return s.GetToken(KuneiformParserPRIMARY, 0) -} - -func (s *Index_defContext) Identifier_list() IIdentifier_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IIdentifier_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IIdentifier_listContext) -} - -func (s *Index_defContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Index_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Index_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitIndex_def(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Index_def() (localctx IIndex_defContext) { - localctx = NewIndex_defContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 14, KuneiformParserRULE_index_def) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(139) - p.Match(KuneiformParserINDEX_NAME) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(140) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&54525952) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(141) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(142) - - var _x = p.Identifier_list() - - localctx.(*Index_defContext).columns = _x - } - { - p.SetState(143) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IForeign_key_defContext is an interface to support dynamic dispatch. -type IForeign_key_defContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetParent_table returns the parent_table token. - GetParent_table() antlr.Token - - // SetParent_table sets the parent_table token. - SetParent_table(antlr.Token) - - // GetChild_keys returns the child_keys rule contexts. - GetChild_keys() IIdentifier_listContext - - // GetParent_keys returns the parent_keys rule contexts. - GetParent_keys() IIdentifier_listContext - - // SetChild_keys sets the child_keys rule contexts. - SetChild_keys(IIdentifier_listContext) - - // SetParent_keys sets the parent_keys rule contexts. - SetParent_keys(IIdentifier_listContext) - - // Getter signatures - FOREIGN_KEY() antlr.TerminalNode - AllLPAREN() []antlr.TerminalNode - LPAREN(i int) antlr.TerminalNode - AllRPAREN() []antlr.TerminalNode - RPAREN(i int) antlr.TerminalNode - REFERENCES() antlr.TerminalNode - AllIdentifier_list() []IIdentifier_listContext - Identifier_list(i int) IIdentifier_listContext - IDENTIFIER() antlr.TerminalNode - AllForeign_key_action() []IForeign_key_actionContext - Foreign_key_action(i int) IForeign_key_actionContext - - // IsForeign_key_defContext differentiates from other interfaces. - IsForeign_key_defContext() -} - -type Foreign_key_defContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - child_keys IIdentifier_listContext - parent_table antlr.Token - parent_keys IIdentifier_listContext -} - -func NewEmptyForeign_key_defContext() *Foreign_key_defContext { - var p = new(Foreign_key_defContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_key_def - return p -} - -func InitEmptyForeign_key_defContext(p *Foreign_key_defContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_key_def -} - -func (*Foreign_key_defContext) IsForeign_key_defContext() {} - -func NewForeign_key_defContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_key_defContext { - var p = new(Foreign_key_defContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_foreign_key_def - - return p -} - -func (s *Foreign_key_defContext) GetParser() antlr.Parser { return s.parser } - -func (s *Foreign_key_defContext) GetParent_table() antlr.Token { return s.parent_table } - -func (s *Foreign_key_defContext) SetParent_table(v antlr.Token) { s.parent_table = v } - -func (s *Foreign_key_defContext) GetChild_keys() IIdentifier_listContext { return s.child_keys } - -func (s *Foreign_key_defContext) GetParent_keys() IIdentifier_listContext { return s.parent_keys } - -func (s *Foreign_key_defContext) SetChild_keys(v IIdentifier_listContext) { s.child_keys = v } - -func (s *Foreign_key_defContext) SetParent_keys(v IIdentifier_listContext) { s.parent_keys = v } - -func (s *Foreign_key_defContext) FOREIGN_KEY() antlr.TerminalNode { - return s.GetToken(KuneiformParserFOREIGN_KEY, 0) -} - -func (s *Foreign_key_defContext) AllLPAREN() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserLPAREN) -} - -func (s *Foreign_key_defContext) LPAREN(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, i) -} - -func (s *Foreign_key_defContext) AllRPAREN() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserRPAREN) -} - -func (s *Foreign_key_defContext) RPAREN(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, i) -} - -func (s *Foreign_key_defContext) REFERENCES() antlr.TerminalNode { - return s.GetToken(KuneiformParserREFERENCES, 0) -} - -func (s *Foreign_key_defContext) AllIdentifier_list() []IIdentifier_listContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IIdentifier_listContext); ok { - len++ - } - } - - tst := make([]IIdentifier_listContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IIdentifier_listContext); ok { - tst[i] = t.(IIdentifier_listContext) - i++ - } - } - - return tst -} - -func (s *Foreign_key_defContext) Identifier_list(i int) IIdentifier_listContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IIdentifier_listContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IIdentifier_listContext) -} - -func (s *Foreign_key_defContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Foreign_key_defContext) AllForeign_key_action() []IForeign_key_actionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IForeign_key_actionContext); ok { - len++ - } - } - - tst := make([]IForeign_key_actionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IForeign_key_actionContext); ok { - tst[i] = t.(IForeign_key_actionContext) - i++ - } - } - - return tst -} - -func (s *Foreign_key_defContext) Foreign_key_action(i int) IForeign_key_actionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IForeign_key_actionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IForeign_key_actionContext) -} - -func (s *Foreign_key_defContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Foreign_key_defContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Foreign_key_defContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitForeign_key_def(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Foreign_key_def() (localctx IForeign_key_defContext) { - localctx = NewForeign_key_defContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 16, KuneiformParserRULE_foreign_key_def) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(145) - p.Match(KuneiformParserFOREIGN_KEY) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(146) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(147) - - var _x = p.Identifier_list() - - localctx.(*Foreign_key_defContext).child_keys = _x - } - { - p.SetState(148) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(149) - p.Match(KuneiformParserREFERENCES) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(150) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Foreign_key_defContext).parent_table = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(151) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(152) - - var _x = p.Identifier_list() - - localctx.(*Foreign_key_defContext).parent_keys = _x - } - { - p.SetState(153) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(157) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserON_UPDATE || _la == KuneiformParserON_DELETE { - { - p.SetState(154) - p.Foreign_key_action() - } - - p.SetState(159) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IForeign_key_actionContext is an interface to support dynamic dispatch. -type IForeign_key_actionContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ON_UPDATE() antlr.TerminalNode - ON_DELETE() antlr.TerminalNode - DO_NO_ACTION() antlr.TerminalNode - DO_CASCADE() antlr.TerminalNode - DO_SET_NULL() antlr.TerminalNode - DO_SET_DEFAULT() antlr.TerminalNode - DO_RESTRICT() antlr.TerminalNode - DO() antlr.TerminalNode - - // IsForeign_key_actionContext differentiates from other interfaces. - IsForeign_key_actionContext() -} - -type Foreign_key_actionContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyForeign_key_actionContext() *Foreign_key_actionContext { - var p = new(Foreign_key_actionContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_key_action - return p -} - -func InitEmptyForeign_key_actionContext(p *Foreign_key_actionContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_foreign_key_action -} - -func (*Foreign_key_actionContext) IsForeign_key_actionContext() {} - -func NewForeign_key_actionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Foreign_key_actionContext { - var p = new(Foreign_key_actionContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_foreign_key_action - - return p -} - -func (s *Foreign_key_actionContext) GetParser() antlr.Parser { return s.parser } - -func (s *Foreign_key_actionContext) ON_UPDATE() antlr.TerminalNode { - return s.GetToken(KuneiformParserON_UPDATE, 0) -} - -func (s *Foreign_key_actionContext) ON_DELETE() antlr.TerminalNode { - return s.GetToken(KuneiformParserON_DELETE, 0) -} - -func (s *Foreign_key_actionContext) DO_NO_ACTION() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO_NO_ACTION, 0) -} - -func (s *Foreign_key_actionContext) DO_CASCADE() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO_CASCADE, 0) -} - -func (s *Foreign_key_actionContext) DO_SET_NULL() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO_SET_NULL, 0) -} - -func (s *Foreign_key_actionContext) DO_SET_DEFAULT() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO_SET_DEFAULT, 0) -} - -func (s *Foreign_key_actionContext) DO_RESTRICT() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO_RESTRICT, 0) -} - -func (s *Foreign_key_actionContext) DO() antlr.TerminalNode { - return s.GetToken(KuneiformParserDO, 0) -} - -func (s *Foreign_key_actionContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Foreign_key_actionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Foreign_key_actionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitForeign_key_action(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Foreign_key_action() (localctx IForeign_key_actionContext) { - localctx = NewForeign_key_actionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 18, KuneiformParserRULE_foreign_key_action) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(160) - _la = p.GetTokenStream().LA(1) - - if !(_la == KuneiformParserON_UPDATE || _la == KuneiformParserON_DELETE) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - p.SetState(162) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserDO { - { - p.SetState(161) - p.Match(KuneiformParserDO) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(164) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&532575944704) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IIdentifier_listContext is an interface to support dynamic dispatch. -type IIdentifier_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllIDENTIFIER() []antlr.TerminalNode - IDENTIFIER(i int) antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsIdentifier_listContext differentiates from other interfaces. - IsIdentifier_listContext() -} - -type Identifier_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyIdentifier_listContext() *Identifier_listContext { - var p = new(Identifier_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_identifier_list - return p -} - -func InitEmptyIdentifier_listContext(p *Identifier_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_identifier_list -} - -func (*Identifier_listContext) IsIdentifier_listContext() {} - -func NewIdentifier_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Identifier_listContext { - var p = new(Identifier_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_identifier_list - - return p -} - -func (s *Identifier_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Identifier_listContext) AllIDENTIFIER() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserIDENTIFIER) -} - -func (s *Identifier_listContext) IDENTIFIER(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, i) -} - -func (s *Identifier_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOMMA) -} - -func (s *Identifier_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, i) -} - -func (s *Identifier_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Identifier_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Identifier_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitIdentifier_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Identifier_list() (localctx IIdentifier_listContext) { - localctx = NewIdentifier_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 20, KuneiformParserRULE_identifier_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(166) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(171) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserCOMMA { - { - p.SetState(167) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(168) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(173) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ILiteralContext is an interface to support dynamic dispatch. -type ILiteralContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - NUMERIC_LITERAL() antlr.TerminalNode - BLOB_LITERAL() antlr.TerminalNode - TEXT_LITERAL() antlr.TerminalNode - BOOLEAN_LITERAL() antlr.TerminalNode - - // IsLiteralContext differentiates from other interfaces. - IsLiteralContext() -} - -type LiteralContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyLiteralContext() *LiteralContext { - var p = new(LiteralContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_literal - return p -} - -func InitEmptyLiteralContext(p *LiteralContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_literal -} - -func (*LiteralContext) IsLiteralContext() {} - -func NewLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LiteralContext { - var p = new(LiteralContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_literal - - return p -} - -func (s *LiteralContext) GetParser() antlr.Parser { return s.parser } - -func (s *LiteralContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNUMERIC_LITERAL, 0) -} - -func (s *LiteralContext) BLOB_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserBLOB_LITERAL, 0) -} - -func (s *LiteralContext) TEXT_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserTEXT_LITERAL, 0) -} - -func (s *LiteralContext) BOOLEAN_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserBOOLEAN_LITERAL, 0) -} - -func (s *LiteralContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *LiteralContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *LiteralContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitLiteral(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Literal() (localctx ILiteralContext) { - localctx = NewLiteralContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 22, KuneiformParserRULE_literal) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(174) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&65970697666560) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IType_selectorContext is an interface to support dynamic dispatch. -type IType_selectorContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetType_ returns the type_ token. - GetType_() antlr.Token - - // SetType_ sets the type_ token. - SetType_(antlr.Token) - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - LBRACKET() antlr.TerminalNode - RBRACKET() antlr.TerminalNode - - // IsType_selectorContext differentiates from other interfaces. - IsType_selectorContext() -} - -type Type_selectorContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - type_ antlr.Token -} - -func NewEmptyType_selectorContext() *Type_selectorContext { - var p = new(Type_selectorContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_type_selector - return p -} - -func InitEmptyType_selectorContext(p *Type_selectorContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_type_selector -} - -func (*Type_selectorContext) IsType_selectorContext() {} - -func NewType_selectorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_selectorContext { - var p = new(Type_selectorContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_type_selector - - return p -} - -func (s *Type_selectorContext) GetParser() antlr.Parser { return s.parser } - -func (s *Type_selectorContext) GetType_() antlr.Token { return s.type_ } - -func (s *Type_selectorContext) SetType_(v antlr.Token) { s.type_ = v } - -func (s *Type_selectorContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, 0) -} - -func (s *Type_selectorContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(KuneiformParserLBRACKET, 0) -} - -func (s *Type_selectorContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(KuneiformParserRBRACKET, 0) -} - -func (s *Type_selectorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Type_selectorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Type_selectorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitType_selector(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Type_selector() (localctx IType_selectorContext) { - localctx = NewType_selectorContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 24, KuneiformParserRULE_type_selector) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(176) - - var _m = p.Match(KuneiformParserIDENTIFIER) - - localctx.(*Type_selectorContext).type_ = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(179) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserLBRACKET { - { - p.SetState(177) - p.Match(KuneiformParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(178) - p.Match(KuneiformParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IType_selector_listContext is an interface to support dynamic dispatch. -type IType_selector_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllType_selector() []IType_selectorContext - Type_selector(i int) IType_selectorContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsType_selector_listContext differentiates from other interfaces. - IsType_selector_listContext() -} - -type Type_selector_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyType_selector_listContext() *Type_selector_listContext { - var p = new(Type_selector_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_type_selector_list - return p -} - -func InitEmptyType_selector_listContext(p *Type_selector_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_type_selector_list -} - -func (*Type_selector_listContext) IsType_selector_listContext() {} - -func NewType_selector_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_selector_listContext { - var p = new(Type_selector_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_type_selector_list - - return p -} - -func (s *Type_selector_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Type_selector_listContext) AllType_selector() []IType_selectorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IType_selectorContext); ok { - len++ - } - } - - tst := make([]IType_selectorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IType_selectorContext); ok { - tst[i] = t.(IType_selectorContext) - i++ - } - } - - return tst -} - -func (s *Type_selector_listContext) Type_selector(i int) IType_selectorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_selectorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IType_selectorContext) -} - -func (s *Type_selector_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOMMA) -} - -func (s *Type_selector_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, i) -} - -func (s *Type_selector_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Type_selector_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Type_selector_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitType_selector_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Type_selector_list() (localctx IType_selector_listContext) { - localctx = NewType_selector_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 26, KuneiformParserRULE_type_selector_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(181) - p.Type_selector() - } - p.SetState(186) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserCOMMA { - { - p.SetState(182) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(183) - p.Type_selector() - } - - p.SetState(188) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// INamed_type_listContext is an interface to support dynamic dispatch. -type INamed_type_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllIDENTIFIER() []antlr.TerminalNode - IDENTIFIER(i int) antlr.TerminalNode - AllType_selector() []IType_selectorContext - Type_selector(i int) IType_selectorContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsNamed_type_listContext differentiates from other interfaces. - IsNamed_type_listContext() -} - -type Named_type_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyNamed_type_listContext() *Named_type_listContext { - var p = new(Named_type_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_named_type_list - return p -} - -func InitEmptyNamed_type_listContext(p *Named_type_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_named_type_list -} - -func (*Named_type_listContext) IsNamed_type_listContext() {} - -func NewNamed_type_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Named_type_listContext { - var p = new(Named_type_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_named_type_list - - return p -} - -func (s *Named_type_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Named_type_listContext) AllIDENTIFIER() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserIDENTIFIER) -} - -func (s *Named_type_listContext) IDENTIFIER(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserIDENTIFIER, i) -} - -func (s *Named_type_listContext) AllType_selector() []IType_selectorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IType_selectorContext); ok { - len++ - } - } - - tst := make([]IType_selectorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IType_selectorContext); ok { - tst[i] = t.(IType_selectorContext) - i++ - } - } - - return tst -} - -func (s *Named_type_listContext) Type_selector(i int) IType_selectorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_selectorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IType_selectorContext) -} - -func (s *Named_type_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOMMA) -} - -func (s *Named_type_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, i) -} - -func (s *Named_type_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Named_type_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Named_type_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitNamed_type_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Named_type_list() (localctx INamed_type_listContext) { - localctx = NewNamed_type_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 28, KuneiformParserRULE_named_type_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(189) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(190) - p.Type_selector() - } - p.SetState(196) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserCOMMA { - { - p.SetState(191) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(192) - p.Match(KuneiformParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(193) - p.Type_selector() - } - - p.SetState(198) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITyped_variable_listContext is an interface to support dynamic dispatch. -type ITyped_variable_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllVAR() []antlr.TerminalNode - VAR(i int) antlr.TerminalNode - AllType_selector() []IType_selectorContext - Type_selector(i int) IType_selectorContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsTyped_variable_listContext differentiates from other interfaces. - IsTyped_variable_listContext() -} - -type Typed_variable_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTyped_variable_listContext() *Typed_variable_listContext { - var p = new(Typed_variable_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_typed_variable_list - return p -} - -func InitEmptyTyped_variable_listContext(p *Typed_variable_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_typed_variable_list -} - -func (*Typed_variable_listContext) IsTyped_variable_listContext() {} - -func NewTyped_variable_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Typed_variable_listContext { - var p = new(Typed_variable_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_typed_variable_list - - return p -} - -func (s *Typed_variable_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Typed_variable_listContext) AllVAR() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserVAR) -} - -func (s *Typed_variable_listContext) VAR(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserVAR, i) -} - -func (s *Typed_variable_listContext) AllType_selector() []IType_selectorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IType_selectorContext); ok { - len++ - } - } - - tst := make([]IType_selectorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IType_selectorContext); ok { - tst[i] = t.(IType_selectorContext) - i++ - } - } - - return tst -} - -func (s *Typed_variable_listContext) Type_selector(i int) IType_selectorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_selectorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IType_selectorContext) -} - -func (s *Typed_variable_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserCOMMA) -} - -func (s *Typed_variable_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserCOMMA, i) -} - -func (s *Typed_variable_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Typed_variable_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Typed_variable_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitTyped_variable_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Typed_variable_list() (localctx ITyped_variable_listContext) { - localctx = NewTyped_variable_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 30, KuneiformParserRULE_typed_variable_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(199) - p.Match(KuneiformParserVAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(200) - p.Type_selector() - } - p.SetState(206) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserCOMMA { - { - p.SetState(201) - p.Match(KuneiformParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(202) - p.Match(KuneiformParserVAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(203) - p.Type_selector() - } - - p.SetState(208) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IConstraintContext is an interface to support dynamic dispatch. -type IConstraintContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsConstraintContext differentiates from other interfaces. - IsConstraintContext() -} - -type ConstraintContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyConstraintContext() *ConstraintContext { - var p = new(ConstraintContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_constraint - return p -} - -func InitEmptyConstraintContext(p *ConstraintContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_constraint -} - -func (*ConstraintContext) IsConstraintContext() {} - -func NewConstraintContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ConstraintContext { - var p = new(ConstraintContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_constraint - - return p -} - -func (s *ConstraintContext) GetParser() antlr.Parser { return s.parser } - -func (s *ConstraintContext) CopyAll(ctx *ConstraintContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *ConstraintContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ConstraintContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type MIN_LENContext struct { - ConstraintContext -} - -func NewMIN_LENContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MIN_LENContext { - var p = new(MIN_LENContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *MIN_LENContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MIN_LENContext) MIN_LEN() antlr.TerminalNode { - return s.GetToken(KuneiformParserMIN_LEN, 0) -} - -func (s *MIN_LENContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *MIN_LENContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNUMERIC_LITERAL, 0) -} - -func (s *MIN_LENContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *MIN_LENContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitMIN_LEN(s) - - default: - return t.VisitChildren(s) - } -} - -type MINContext struct { - ConstraintContext -} - -func NewMINContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MINContext { - var p = new(MINContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *MINContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MINContext) MIN() antlr.TerminalNode { - return s.GetToken(KuneiformParserMIN, 0) -} - -func (s *MINContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *MINContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNUMERIC_LITERAL, 0) -} - -func (s *MINContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *MINContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitMIN(s) - - default: - return t.VisitChildren(s) - } -} - -type PRIMARY_KEYContext struct { - ConstraintContext -} - -func NewPRIMARY_KEYContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *PRIMARY_KEYContext { - var p = new(PRIMARY_KEYContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *PRIMARY_KEYContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *PRIMARY_KEYContext) PRIMARY() antlr.TerminalNode { - return s.GetToken(KuneiformParserPRIMARY, 0) -} - -func (s *PRIMARY_KEYContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitPRIMARY_KEY(s) - - default: - return t.VisitChildren(s) - } -} - -type MAXContext struct { - ConstraintContext -} - -func NewMAXContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MAXContext { - var p = new(MAXContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *MAXContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MAXContext) MAX() antlr.TerminalNode { - return s.GetToken(KuneiformParserMAX, 0) -} - -func (s *MAXContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *MAXContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNUMERIC_LITERAL, 0) -} - -func (s *MAXContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *MAXContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitMAX(s) - - default: - return t.VisitChildren(s) - } -} - -type MAX_LENContext struct { - ConstraintContext -} - -func NewMAX_LENContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MAX_LENContext { - var p = new(MAX_LENContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *MAX_LENContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MAX_LENContext) MAX_LEN() antlr.TerminalNode { - return s.GetToken(KuneiformParserMAX_LEN, 0) -} - -func (s *MAX_LENContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *MAX_LENContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNUMERIC_LITERAL, 0) -} - -func (s *MAX_LENContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *MAX_LENContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitMAX_LEN(s) - - default: - return t.VisitChildren(s) - } -} - -type UNIQUEContext struct { - ConstraintContext -} - -func NewUNIQUEContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *UNIQUEContext { - var p = new(UNIQUEContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *UNIQUEContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *UNIQUEContext) UNIQUE() antlr.TerminalNode { - return s.GetToken(KuneiformParserUNIQUE, 0) -} - -func (s *UNIQUEContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitUNIQUE(s) - - default: - return t.VisitChildren(s) - } -} - -type NOT_NULLContext struct { - ConstraintContext -} - -func NewNOT_NULLContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *NOT_NULLContext { - var p = new(NOT_NULLContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *NOT_NULLContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *NOT_NULLContext) NOT_NULL() antlr.TerminalNode { - return s.GetToken(KuneiformParserNOT_NULL, 0) -} - -func (s *NOT_NULLContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitNOT_NULL(s) - - default: - return t.VisitChildren(s) - } -} - -type DEFAULTContext struct { - ConstraintContext -} - -func NewDEFAULTContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *DEFAULTContext { - var p = new(DEFAULTContext) - - InitEmptyConstraintContext(&p.ConstraintContext) - p.parser = parser - p.CopyAll(ctx.(*ConstraintContext)) - - return p -} - -func (s *DEFAULTContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *DEFAULTContext) DEFAULT() antlr.TerminalNode { - return s.GetToken(KuneiformParserDEFAULT, 0) -} - -func (s *DEFAULTContext) LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserLPAREN, 0) -} - -func (s *DEFAULTContext) Literal() ILiteralContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ILiteralContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ILiteralContext) -} - -func (s *DEFAULTContext) RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserRPAREN, 0) -} - -func (s *DEFAULTContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitDEFAULT(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Constraint() (localctx IConstraintContext) { - localctx = NewConstraintContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 32, KuneiformParserRULE_constraint) - p.SetState(233) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case KuneiformParserMIN: - localctx = NewMINContext(p, localctx) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(209) - p.Match(KuneiformParserMIN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(210) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(211) - p.Match(KuneiformParserNUMERIC_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(212) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserMAX: - localctx = NewMAXContext(p, localctx) - p.EnterOuterAlt(localctx, 2) - { - p.SetState(213) - p.Match(KuneiformParserMAX) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(214) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(215) - p.Match(KuneiformParserNUMERIC_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(216) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserMIN_LEN: - localctx = NewMIN_LENContext(p, localctx) - p.EnterOuterAlt(localctx, 3) - { - p.SetState(217) - p.Match(KuneiformParserMIN_LEN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(218) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(219) - p.Match(KuneiformParserNUMERIC_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(220) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserMAX_LEN: - localctx = NewMAX_LENContext(p, localctx) - p.EnterOuterAlt(localctx, 4) - { - p.SetState(221) - p.Match(KuneiformParserMAX_LEN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(222) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(223) - p.Match(KuneiformParserNUMERIC_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(224) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserNOT_NULL: - localctx = NewNOT_NULLContext(p, localctx) - p.EnterOuterAlt(localctx, 5) - { - p.SetState(225) - p.Match(KuneiformParserNOT_NULL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserPRIMARY: - localctx = NewPRIMARY_KEYContext(p, localctx) - p.EnterOuterAlt(localctx, 6) - { - p.SetState(226) - p.Match(KuneiformParserPRIMARY) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserDEFAULT: - localctx = NewDEFAULTContext(p, localctx) - p.EnterOuterAlt(localctx, 7) - { - p.SetState(227) - p.Match(KuneiformParserDEFAULT) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(228) - p.Match(KuneiformParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(229) - p.Literal() - } - { - p.SetState(230) - p.Match(KuneiformParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case KuneiformParserUNIQUE: - localctx = NewUNIQUEContext(p, localctx) - p.EnterOuterAlt(localctx, 8) - { - p.SetState(232) - p.Match(KuneiformParserUNIQUE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IAction_declarationContext is an interface to support dynamic dispatch. -type IAction_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - START_ACTION() antlr.TerminalNode - STMT_IDENTIFIER() antlr.TerminalNode - STMT_LPAREN() antlr.TerminalNode - STMT_RPAREN() antlr.TerminalNode - STMT_BODY() antlr.TerminalNode - AllSTMT_VAR() []antlr.TerminalNode - STMT_VAR(i int) antlr.TerminalNode - AllSTMT_ACCESS() []antlr.TerminalNode - STMT_ACCESS(i int) antlr.TerminalNode - AllSTMT_COMMA() []antlr.TerminalNode - STMT_COMMA(i int) antlr.TerminalNode - - // IsAction_declarationContext differentiates from other interfaces. - IsAction_declarationContext() -} - -type Action_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyAction_declarationContext() *Action_declarationContext { - var p = new(Action_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_action_declaration - return p -} - -func InitEmptyAction_declarationContext(p *Action_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_action_declaration -} - -func (*Action_declarationContext) IsAction_declarationContext() {} - -func NewAction_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Action_declarationContext { - var p = new(Action_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_action_declaration - - return p -} - -func (s *Action_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Action_declarationContext) START_ACTION() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTART_ACTION, 0) -} - -func (s *Action_declarationContext) STMT_IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_IDENTIFIER, 0) -} - -func (s *Action_declarationContext) STMT_LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_LPAREN, 0) -} - -func (s *Action_declarationContext) STMT_RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_RPAREN, 0) -} - -func (s *Action_declarationContext) STMT_BODY() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_BODY, 0) -} - -func (s *Action_declarationContext) AllSTMT_VAR() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_VAR) -} - -func (s *Action_declarationContext) STMT_VAR(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_VAR, i) -} - -func (s *Action_declarationContext) AllSTMT_ACCESS() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_ACCESS) -} - -func (s *Action_declarationContext) STMT_ACCESS(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_ACCESS, i) -} - -func (s *Action_declarationContext) AllSTMT_COMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_COMMA) -} - -func (s *Action_declarationContext) STMT_COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_COMMA, i) -} - -func (s *Action_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Action_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Action_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitAction_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Action_declaration() (localctx IAction_declarationContext) { - localctx = NewAction_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 34, KuneiformParserRULE_action_declaration) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(235) - p.Match(KuneiformParserSTART_ACTION) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(236) - p.Match(KuneiformParserSTMT_IDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(237) - p.Match(KuneiformParserSTMT_LPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(246) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserSTMT_VAR { - { - p.SetState(238) - p.Match(KuneiformParserSTMT_VAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(243) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserSTMT_COMMA { - { - p.SetState(239) - p.Match(KuneiformParserSTMT_COMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(240) - p.Match(KuneiformParserSTMT_VAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(245) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - - } - { - p.SetState(248) - p.Match(KuneiformParserSTMT_RPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(250) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ok := true; ok; ok = _la == KuneiformParserSTMT_ACCESS { - { - p.SetState(249) - p.Match(KuneiformParserSTMT_ACCESS) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(252) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(254) - p.Match(KuneiformParserSTMT_BODY) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IProcedure_declarationContext is an interface to support dynamic dispatch. -type IProcedure_declarationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetProcedure_name returns the procedure_name token. - GetProcedure_name() antlr.Token - - // SetProcedure_name sets the procedure_name token. - SetProcedure_name(antlr.Token) - - // Getter signatures - START_PROCEDURE() antlr.TerminalNode - STMT_LPAREN() antlr.TerminalNode - STMT_RPAREN() antlr.TerminalNode - STMT_BODY() antlr.TerminalNode - STMT_IDENTIFIER() antlr.TerminalNode - Stmt_typed_param_list() IStmt_typed_param_listContext - AllSTMT_ACCESS() []antlr.TerminalNode - STMT_ACCESS(i int) antlr.TerminalNode - STMT_RETURNS() antlr.TerminalNode - Stmt_return() IStmt_returnContext - - // IsProcedure_declarationContext differentiates from other interfaces. - IsProcedure_declarationContext() -} - -type Procedure_declarationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - procedure_name antlr.Token -} - -func NewEmptyProcedure_declarationContext() *Procedure_declarationContext { - var p = new(Procedure_declarationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_procedure_declaration - return p -} - -func InitEmptyProcedure_declarationContext(p *Procedure_declarationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_procedure_declaration -} - -func (*Procedure_declarationContext) IsProcedure_declarationContext() {} - -func NewProcedure_declarationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Procedure_declarationContext { - var p = new(Procedure_declarationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_procedure_declaration - - return p -} - -func (s *Procedure_declarationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Procedure_declarationContext) GetProcedure_name() antlr.Token { return s.procedure_name } - -func (s *Procedure_declarationContext) SetProcedure_name(v antlr.Token) { s.procedure_name = v } - -func (s *Procedure_declarationContext) START_PROCEDURE() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTART_PROCEDURE, 0) -} - -func (s *Procedure_declarationContext) STMT_LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_LPAREN, 0) -} - -func (s *Procedure_declarationContext) STMT_RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_RPAREN, 0) -} - -func (s *Procedure_declarationContext) STMT_BODY() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_BODY, 0) -} - -func (s *Procedure_declarationContext) STMT_IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_IDENTIFIER, 0) -} - -func (s *Procedure_declarationContext) Stmt_typed_param_list() IStmt_typed_param_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmt_typed_param_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IStmt_typed_param_listContext) -} - -func (s *Procedure_declarationContext) AllSTMT_ACCESS() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_ACCESS) -} - -func (s *Procedure_declarationContext) STMT_ACCESS(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_ACCESS, i) -} - -func (s *Procedure_declarationContext) STMT_RETURNS() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_RETURNS, 0) -} - -func (s *Procedure_declarationContext) Stmt_return() IStmt_returnContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmt_returnContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IStmt_returnContext) -} - -func (s *Procedure_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Procedure_declarationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Procedure_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitProcedure_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Procedure_declaration() (localctx IProcedure_declarationContext) { - localctx = NewProcedure_declarationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 36, KuneiformParserRULE_procedure_declaration) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(256) - p.Match(KuneiformParserSTART_PROCEDURE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(257) - - var _m = p.Match(KuneiformParserSTMT_IDENTIFIER) - - localctx.(*Procedure_declarationContext).procedure_name = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(258) - p.Match(KuneiformParserSTMT_LPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(260) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserSTMT_VAR { - { - p.SetState(259) - p.Stmt_typed_param_list() - } - - } - { - p.SetState(262) - p.Match(KuneiformParserSTMT_RPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(264) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ok := true; ok; ok = _la == KuneiformParserSTMT_ACCESS { - { - p.SetState(263) - p.Match(KuneiformParserSTMT_ACCESS) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(266) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(270) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserSTMT_RETURNS { - { - p.SetState(268) - p.Match(KuneiformParserSTMT_RETURNS) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(269) - p.Stmt_return() - } - - } - { - p.SetState(272) - p.Match(KuneiformParserSTMT_BODY) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStmt_returnContext is an interface to support dynamic dispatch. -type IStmt_returnContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - STMT_LPAREN() antlr.TerminalNode - AllSTMT_IDENTIFIER() []antlr.TerminalNode - STMT_IDENTIFIER(i int) antlr.TerminalNode - AllStmt_type_selector() []IStmt_type_selectorContext - Stmt_type_selector(i int) IStmt_type_selectorContext - STMT_RPAREN() antlr.TerminalNode - STMT_TABLE() antlr.TerminalNode - AllSTMT_COMMA() []antlr.TerminalNode - STMT_COMMA(i int) antlr.TerminalNode - - // IsStmt_returnContext differentiates from other interfaces. - IsStmt_returnContext() -} - -type Stmt_returnContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStmt_returnContext() *Stmt_returnContext { - var p = new(Stmt_returnContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_return - return p -} - -func InitEmptyStmt_returnContext(p *Stmt_returnContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_return -} - -func (*Stmt_returnContext) IsStmt_returnContext() {} - -func NewStmt_returnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Stmt_returnContext { - var p = new(Stmt_returnContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_stmt_return - - return p -} - -func (s *Stmt_returnContext) GetParser() antlr.Parser { return s.parser } - -func (s *Stmt_returnContext) STMT_LPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_LPAREN, 0) -} - -func (s *Stmt_returnContext) AllSTMT_IDENTIFIER() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_IDENTIFIER) -} - -func (s *Stmt_returnContext) STMT_IDENTIFIER(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_IDENTIFIER, i) -} - -func (s *Stmt_returnContext) AllStmt_type_selector() []IStmt_type_selectorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStmt_type_selectorContext); ok { - len++ - } - } - - tst := make([]IStmt_type_selectorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStmt_type_selectorContext); ok { - tst[i] = t.(IStmt_type_selectorContext) - i++ - } - } - - return tst -} - -func (s *Stmt_returnContext) Stmt_type_selector(i int) IStmt_type_selectorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmt_type_selectorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStmt_type_selectorContext) -} - -func (s *Stmt_returnContext) STMT_RPAREN() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_RPAREN, 0) -} - -func (s *Stmt_returnContext) STMT_TABLE() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_TABLE, 0) -} - -func (s *Stmt_returnContext) AllSTMT_COMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_COMMA) -} - -func (s *Stmt_returnContext) STMT_COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_COMMA, i) -} - -func (s *Stmt_returnContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_returnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Stmt_returnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitStmt_return(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Stmt_return() (localctx IStmt_returnContext) { - localctx = NewStmt_returnContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 38, KuneiformParserRULE_stmt_return) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(275) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserSTMT_TABLE { - { - p.SetState(274) - p.Match(KuneiformParserSTMT_TABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(277) - p.Match(KuneiformParserSTMT_LPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(278) - p.Match(KuneiformParserSTMT_IDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(279) - p.Stmt_type_selector() - } - p.SetState(285) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserSTMT_COMMA { - { - p.SetState(280) - p.Match(KuneiformParserSTMT_COMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(281) - p.Match(KuneiformParserSTMT_IDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(282) - p.Stmt_type_selector() - } - - p.SetState(287) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(288) - p.Match(KuneiformParserSTMT_RPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStmt_typed_param_listContext is an interface to support dynamic dispatch. -type IStmt_typed_param_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllSTMT_VAR() []antlr.TerminalNode - STMT_VAR(i int) antlr.TerminalNode - AllStmt_type_selector() []IStmt_type_selectorContext - Stmt_type_selector(i int) IStmt_type_selectorContext - AllSTMT_COMMA() []antlr.TerminalNode - STMT_COMMA(i int) antlr.TerminalNode - - // IsStmt_typed_param_listContext differentiates from other interfaces. - IsStmt_typed_param_listContext() -} - -type Stmt_typed_param_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStmt_typed_param_listContext() *Stmt_typed_param_listContext { - var p = new(Stmt_typed_param_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_typed_param_list - return p -} - -func InitEmptyStmt_typed_param_listContext(p *Stmt_typed_param_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_typed_param_list -} - -func (*Stmt_typed_param_listContext) IsStmt_typed_param_listContext() {} - -func NewStmt_typed_param_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Stmt_typed_param_listContext { - var p = new(Stmt_typed_param_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_stmt_typed_param_list - - return p -} - -func (s *Stmt_typed_param_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Stmt_typed_param_listContext) AllSTMT_VAR() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_VAR) -} - -func (s *Stmt_typed_param_listContext) STMT_VAR(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_VAR, i) -} - -func (s *Stmt_typed_param_listContext) AllStmt_type_selector() []IStmt_type_selectorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStmt_type_selectorContext); ok { - len++ - } - } - - tst := make([]IStmt_type_selectorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStmt_type_selectorContext); ok { - tst[i] = t.(IStmt_type_selectorContext) - i++ - } - } - - return tst -} - -func (s *Stmt_typed_param_listContext) Stmt_type_selector(i int) IStmt_type_selectorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStmt_type_selectorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStmt_type_selectorContext) -} - -func (s *Stmt_typed_param_listContext) AllSTMT_COMMA() []antlr.TerminalNode { - return s.GetTokens(KuneiformParserSTMT_COMMA) -} - -func (s *Stmt_typed_param_listContext) STMT_COMMA(i int) antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_COMMA, i) -} - -func (s *Stmt_typed_param_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_typed_param_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Stmt_typed_param_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitStmt_typed_param_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Stmt_typed_param_list() (localctx IStmt_typed_param_listContext) { - localctx = NewStmt_typed_param_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 40, KuneiformParserRULE_stmt_typed_param_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(290) - p.Match(KuneiformParserSTMT_VAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(291) - p.Stmt_type_selector() - } - p.SetState(297) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == KuneiformParserSTMT_COMMA { - { - p.SetState(292) - p.Match(KuneiformParserSTMT_COMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(293) - p.Match(KuneiformParserSTMT_VAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(294) - p.Stmt_type_selector() - } - - p.SetState(299) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStmt_type_selectorContext is an interface to support dynamic dispatch. -type IStmt_type_selectorContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetType_ returns the type_ token. - GetType_() antlr.Token - - // SetType_ sets the type_ token. - SetType_(antlr.Token) - - // Getter signatures - STMT_IDENTIFIER() antlr.TerminalNode - STMT_ARRAY() antlr.TerminalNode - - // IsStmt_type_selectorContext differentiates from other interfaces. - IsStmt_type_selectorContext() -} - -type Stmt_type_selectorContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - type_ antlr.Token -} - -func NewEmptyStmt_type_selectorContext() *Stmt_type_selectorContext { - var p = new(Stmt_type_selectorContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_type_selector - return p -} - -func InitEmptyStmt_type_selectorContext(p *Stmt_type_selectorContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = KuneiformParserRULE_stmt_type_selector -} - -func (*Stmt_type_selectorContext) IsStmt_type_selectorContext() {} - -func NewStmt_type_selectorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Stmt_type_selectorContext { - var p = new(Stmt_type_selectorContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = KuneiformParserRULE_stmt_type_selector - - return p -} - -func (s *Stmt_type_selectorContext) GetParser() antlr.Parser { return s.parser } - -func (s *Stmt_type_selectorContext) GetType_() antlr.Token { return s.type_ } - -func (s *Stmt_type_selectorContext) SetType_(v antlr.Token) { s.type_ = v } - -func (s *Stmt_type_selectorContext) STMT_IDENTIFIER() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_IDENTIFIER, 0) -} - -func (s *Stmt_type_selectorContext) STMT_ARRAY() antlr.TerminalNode { - return s.GetToken(KuneiformParserSTMT_ARRAY, 0) -} - -func (s *Stmt_type_selectorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_type_selectorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Stmt_type_selectorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case KuneiformParserVisitor: - return t.VisitStmt_type_selector(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *KuneiformParser) Stmt_type_selector() (localctx IStmt_type_selectorContext) { - localctx = NewStmt_type_selectorContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 42, KuneiformParserRULE_stmt_type_selector) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(300) - - var _m = p.Match(KuneiformParserSTMT_IDENTIFIER) - - localctx.(*Stmt_type_selectorContext).type_ = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(302) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == KuneiformParserSTMT_ARRAY { - { - p.SetState(301) - p.Match(KuneiformParserSTMT_ARRAY) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} diff --git a/parse/kuneiform/gen/kuneiformparser_base_visitor.go b/parse/kuneiform/gen/kuneiformparser_base_visitor.go deleted file mode 100644 index 0a06a44e3..000000000 --- a/parse/kuneiform/gen/kuneiformparser_base_visitor.go +++ /dev/null @@ -1,124 +0,0 @@ -// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // KuneiformParser -import "github.com/antlr4-go/antlr/v4" - -type BaseKuneiformParserVisitor struct { - *antlr.BaseParseTreeVisitor -} - -func (v *BaseKuneiformParserVisitor) VisitProgram(ctx *ProgramContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitStmt_mode(ctx *Stmt_modeContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitDatabase_declaration(ctx *Database_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitUse_declaration(ctx *Use_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitForeign_declaration(ctx *Foreign_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitTable_declaration(ctx *Table_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitColumn_def(ctx *Column_defContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitIndex_def(ctx *Index_defContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitForeign_key_def(ctx *Foreign_key_defContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitForeign_key_action(ctx *Foreign_key_actionContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitIdentifier_list(ctx *Identifier_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitLiteral(ctx *LiteralContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitType_selector(ctx *Type_selectorContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitType_selector_list(ctx *Type_selector_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitNamed_type_list(ctx *Named_type_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitTyped_variable_list(ctx *Typed_variable_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitMIN(ctx *MINContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitMAX(ctx *MAXContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitMIN_LEN(ctx *MIN_LENContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitMAX_LEN(ctx *MAX_LENContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitNOT_NULL(ctx *NOT_NULLContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitPRIMARY_KEY(ctx *PRIMARY_KEYContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitDEFAULT(ctx *DEFAULTContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitUNIQUE(ctx *UNIQUEContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitAction_declaration(ctx *Action_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitProcedure_declaration(ctx *Procedure_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitStmt_return(ctx *Stmt_returnContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitStmt_typed_param_list(ctx *Stmt_typed_param_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseKuneiformParserVisitor) VisitStmt_type_selector(ctx *Stmt_type_selectorContext) interface{} { - return v.VisitChildren(ctx) -} diff --git a/parse/kuneiform/gen/kuneiformparser_visitor.go b/parse/kuneiform/gen/kuneiformparser_visitor.go deleted file mode 100644 index 8895cc8bb..000000000 --- a/parse/kuneiform/gen/kuneiformparser_visitor.go +++ /dev/null @@ -1,96 +0,0 @@ -// Code generated from KuneiformParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // KuneiformParser -import "github.com/antlr4-go/antlr/v4" - -// A complete Visitor for a parse tree produced by KuneiformParser. -type KuneiformParserVisitor interface { - antlr.ParseTreeVisitor - - // Visit a parse tree produced by KuneiformParser#program. - VisitProgram(ctx *ProgramContext) interface{} - - // Visit a parse tree produced by KuneiformParser#stmt_mode. - VisitStmt_mode(ctx *Stmt_modeContext) interface{} - - // Visit a parse tree produced by KuneiformParser#database_declaration. - VisitDatabase_declaration(ctx *Database_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#use_declaration. - VisitUse_declaration(ctx *Use_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#foreign_declaration. - VisitForeign_declaration(ctx *Foreign_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#table_declaration. - VisitTable_declaration(ctx *Table_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#column_def. - VisitColumn_def(ctx *Column_defContext) interface{} - - // Visit a parse tree produced by KuneiformParser#index_def. - VisitIndex_def(ctx *Index_defContext) interface{} - - // Visit a parse tree produced by KuneiformParser#foreign_key_def. - VisitForeign_key_def(ctx *Foreign_key_defContext) interface{} - - // Visit a parse tree produced by KuneiformParser#foreign_key_action. - VisitForeign_key_action(ctx *Foreign_key_actionContext) interface{} - - // Visit a parse tree produced by KuneiformParser#identifier_list. - VisitIdentifier_list(ctx *Identifier_listContext) interface{} - - // Visit a parse tree produced by KuneiformParser#literal. - VisitLiteral(ctx *LiteralContext) interface{} - - // Visit a parse tree produced by KuneiformParser#type_selector. - VisitType_selector(ctx *Type_selectorContext) interface{} - - // Visit a parse tree produced by KuneiformParser#type_selector_list. - VisitType_selector_list(ctx *Type_selector_listContext) interface{} - - // Visit a parse tree produced by KuneiformParser#named_type_list. - VisitNamed_type_list(ctx *Named_type_listContext) interface{} - - // Visit a parse tree produced by KuneiformParser#typed_variable_list. - VisitTyped_variable_list(ctx *Typed_variable_listContext) interface{} - - // Visit a parse tree produced by KuneiformParser#MIN. - VisitMIN(ctx *MINContext) interface{} - - // Visit a parse tree produced by KuneiformParser#MAX. - VisitMAX(ctx *MAXContext) interface{} - - // Visit a parse tree produced by KuneiformParser#MIN_LEN. - VisitMIN_LEN(ctx *MIN_LENContext) interface{} - - // Visit a parse tree produced by KuneiformParser#MAX_LEN. - VisitMAX_LEN(ctx *MAX_LENContext) interface{} - - // Visit a parse tree produced by KuneiformParser#NOT_NULL. - VisitNOT_NULL(ctx *NOT_NULLContext) interface{} - - // Visit a parse tree produced by KuneiformParser#PRIMARY_KEY. - VisitPRIMARY_KEY(ctx *PRIMARY_KEYContext) interface{} - - // Visit a parse tree produced by KuneiformParser#DEFAULT. - VisitDEFAULT(ctx *DEFAULTContext) interface{} - - // Visit a parse tree produced by KuneiformParser#UNIQUE. - VisitUNIQUE(ctx *UNIQUEContext) interface{} - - // Visit a parse tree produced by KuneiformParser#action_declaration. - VisitAction_declaration(ctx *Action_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#procedure_declaration. - VisitProcedure_declaration(ctx *Procedure_declarationContext) interface{} - - // Visit a parse tree produced by KuneiformParser#stmt_return. - VisitStmt_return(ctx *Stmt_returnContext) interface{} - - // Visit a parse tree produced by KuneiformParser#stmt_typed_param_list. - VisitStmt_typed_param_list(ctx *Stmt_typed_param_listContext) interface{} - - // Visit a parse tree produced by KuneiformParser#stmt_type_selector. - VisitStmt_type_selector(ctx *Stmt_type_selectorContext) interface{} -} diff --git a/parse/kuneiform/grammar/KuneiformLexer.g4 b/parse/kuneiform/grammar/KuneiformLexer.g4 deleted file mode 100644 index 850040648..000000000 --- a/parse/kuneiform/grammar/KuneiformLexer.g4 +++ /dev/null @@ -1,141 +0,0 @@ -/* - * A ANTLR4 grammar for Kuneiform. - * Developed by the Kuneiform team. -*/ - -lexer grammar KuneiformLexer; - -options { caseInsensitive = true; } - -// symbols -LBRACE: '{'; -RBRACE: '}'; -LBRACKET: '['; -RBRACKET: ']'; -COL: ':'; -SCOL: ';'; -LPAREN: '('; -RPAREN: ')'; -COMMA: ','; -AT: '@'; -PERIOD: '.'; -EQUALS: '='; - - -// keywords -DATABASE: 'database'; -USE: 'use'; -IMPORT: 'import'; -AS: 'as'; -//// column attrs -MIN: 'min'; -MAX: 'max'; -MIN_LEN: 'minlen'; -MAX_LEN: 'maxlen'; -NOT_NULL: 'not' WSNL? 'null'; -PRIMARY: 'primary' ('_'|WSNL)? 'key'?; -DEFAULT: 'default'; -UNIQUE: 'unique'; -INDEX: 'index'; -TABLE: 'table'; -TYPE: 'type'; -RETURNS: 'returns'; -//// foreign key -FOREIGN_KEY: 'foreign' ('_'|WSNL) 'key'|'fk'; -FOREIGN_PROCEDURE: 'foreign' WSNL 'procedure'; -REFERENCES: 'references'|'ref'; -ON_UPDATE: 'on' ('_'|WSNL) 'update'; -ON_DELETE: 'on' ('_'|WSNL) 'delete'; -DO_NO_ACTION: 'no' ('_'|WSNL) 'action'; -DO_CASCADE: 'cascade'; -DO_SET_NULL: 'set' ('_'|WSNL) 'null'; -DO_SET_DEFAULT: 'set' ('_'|WSNL) 'default'; -DO_RESTRICT: 'restrict'; -DO: 'do'; - -START_ACTION: 'action' -> pushMode(STMT_MODE); -START_PROCEDURE: 'procedure' -> pushMode(STMT_MODE); - -// literals -NUMERIC_LITERAL: - ('+'|'-')?[0-9]+ -; - -TEXT_LITERAL: - '\'' ( ~['\r\n\\] | ('\\' .) )* '\'' -; - -BOOLEAN_LITERAL: - 'true' - | 'false' -; - -BLOB_LITERAL: - '0x' [0-9a-f]+ -; - -VAR: - '$' IDENTIFIER -; - -INDEX_NAME: - '#' IDENTIFIER -; - -IDENTIFIER: - [a-z] [a-z_0-9]* -; - -ANNOTATION: - '@' ~[\n]+ -; - -WS: [ \t\r\n] -> channel(HIDDEN); -TERMINATOR: [\r\n]+ -> channel(HIDDEN); -BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); -LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); - -// fragments -fragment WSNL: [ \t\r\n]+; // whitespace with new line -fragment DIGIT: [0-9]; - -// STMT_MODE captures actions and procedures. -// it is used to allow us to correctly parse action / procedure bodies -mode STMT_MODE; - COMMENT: ( '//' ~[\r\n]* '\r'? '\n' - | '/*' .*? '*/' - ) -> skip - ; - - // STMT_BODY captures everything between two curly braces. - // It is defined recusively to only exit on the final curly brace. - STMT_BODY: LBRACE ( COMMENT | ANY | STMT_BODY | TEXT )* RBRACE -> popMode; - - // we don't make TEXT fragmented because we want anything - // textual to be ignore and not tokenized. - TEXT: '\'' ( '\\' '\'' | ~('\'' | '\\') )* '\''; - - - - STMT_LPAREN: LPAREN; - STMT_RPAREN: RPAREN; - STMT_COMMA: COMMA; - STMT_PERIOD: PERIOD; - STMT_RETURNS: RETURNS; - STMT_TABLE: TABLE; - STMT_ARRAY: LBRACKET RBRACKET; - STMT_VAR: '$' IDENTIFIER; - STMT_ACCESS: 'public'|'private'|'view'|'owner'; - - // keep IDENTIFIER last - STMT_IDENTIFIER: IDENTIFIER; - - // RECUR tokenizes braces recusively, allowing us to - // only exit the mode once enough right braces have been - // used - - STMT_WS: WS -> channel(HIDDEN); - STMT_TERMINATOR: TERMINATOR -> channel(HIDDEN); - - // fragment text to not tokenize braces in text literals - fragment ANY: ~[{}'/]+; diff --git a/parse/kuneiform/grammar/KuneiformParser.g4 b/parse/kuneiform/grammar/KuneiformParser.g4 deleted file mode 100644 index 3ad654d15..000000000 --- a/parse/kuneiform/grammar/KuneiformParser.g4 +++ /dev/null @@ -1,136 +0,0 @@ -/* - * A ANTLR4 grammar for Kuneiform. - * Developed by the Kuneiform team. -*/ - -parser grammar KuneiformParser; - -options { - tokenVocab=KuneiformLexer; -} - -// program is the parser entrypoint -program: - database_declaration - (use_declaration | table_declaration - | stmt_mode | foreign_declaration - )* EOF -; - -stmt_mode: - ANNOTATION* - (action_declaration|procedure_declaration) -; - -database_declaration: - DATABASE IDENTIFIER SCOL -; - -use_declaration: - USE extension_name=IDENTIFIER - (LBRACE IDENTIFIER COL literal (COMMA IDENTIFIER COL literal)? RBRACE)? - AS alias=IDENTIFIER SCOL -; - -foreign_declaration: - FOREIGN_PROCEDURE name=IDENTIFIER - LPAREN (unnamed_params=type_selector_list|named_params=typed_variable_list)? RPAREN - (RETURNS (TABLE? LPAREN return_columns=named_type_list RPAREN - | LPAREN unnamed_return_types=type_selector_list RPAREN))? -; - -table_declaration: - TABLE IDENTIFIER LBRACE - column_def (COMMA (column_def | index_def | foreign_key_def))* - RBRACE - ; - -column_def: - name=IDENTIFIER type=type_selector constraint* -; - -index_def: - INDEX_NAME - (UNIQUE | INDEX | PRIMARY) - LPAREN columns=identifier_list RPAREN -; - -foreign_key_def: - FOREIGN_KEY - LPAREN child_keys=identifier_list RPAREN - REFERENCES parent_table=IDENTIFIER LPAREN parent_keys=identifier_list RPAREN - foreign_key_action* -; - -foreign_key_action: - (ON_UPDATE|ON_DELETE) DO? (DO_NO_ACTION|DO_CASCADE|DO_SET_NULL|DO_SET_DEFAULT|DO_RESTRICT) -; - -identifier_list: - IDENTIFIER (COMMA IDENTIFIER)* -; - -literal: - NUMERIC_LITERAL - | BLOB_LITERAL - | TEXT_LITERAL - | BOOLEAN_LITERAL -; - -type_selector: - type=IDENTIFIER - (LBRACKET RBRACKET)? -; - -type_selector_list: - type_selector (COMMA type_selector)* -; - -named_type_list: - IDENTIFIER type_selector (COMMA IDENTIFIER type_selector)* -; - -typed_variable_list: - VAR type_selector (COMMA VAR type_selector)* -; - -constraint: - MIN LPAREN NUMERIC_LITERAL RPAREN # MIN - | MAX LPAREN NUMERIC_LITERAL RPAREN # MAX - | MIN_LEN LPAREN NUMERIC_LITERAL RPAREN # MIN_LEN - | MAX_LEN LPAREN NUMERIC_LITERAL RPAREN # MAX_LEN - | NOT_NULL # NOT_NULL - | PRIMARY # PRIMARY_KEY - | DEFAULT LPAREN literal RPAREN # DEFAULT - | UNIQUE # UNIQUE -; - -// STMT_MODE parsing: - -action_declaration: - START_ACTION STMT_IDENTIFIER - STMT_LPAREN (STMT_VAR (STMT_COMMA STMT_VAR)*)? STMT_RPAREN - STMT_ACCESS+ - STMT_BODY -; - -procedure_declaration: - START_PROCEDURE procedure_name=STMT_IDENTIFIER - STMT_LPAREN stmt_typed_param_list? STMT_RPAREN - STMT_ACCESS+ - (STMT_RETURNS stmt_return)? - STMT_BODY -; - -stmt_return: - STMT_TABLE? STMT_LPAREN STMT_IDENTIFIER stmt_type_selector (STMT_COMMA STMT_IDENTIFIER stmt_type_selector)* STMT_RPAREN -; - -stmt_typed_param_list: - STMT_VAR stmt_type_selector (STMT_COMMA STMT_VAR stmt_type_selector)* -; - -stmt_type_selector: - type=STMT_IDENTIFIER - (STMT_ARRAY)? -; \ No newline at end of file diff --git a/parse/kuneiform/parser.go b/parse/kuneiform/parser.go deleted file mode 100644 index fdaf24be9..000000000 --- a/parse/kuneiform/parser.go +++ /dev/null @@ -1,635 +0,0 @@ -package kuneiform - -import ( - "errors" - "fmt" - "runtime" - "strings" - - "github.com/antlr4-go/antlr/v4" - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/kuneiform/gen" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// Parse parses a Kuneiform file and returns the parsed schema. -// It will also parse the SQL to perform validity checks. -func Parse(kf string) (schema *types.Schema, info *parseTypes.SchemaInfo, parseErrs parseTypes.ParseErrors, err error) { - errorListener := parseTypes.NewErrorListener() - - visitor := &kfVisitor{ - registeredNames: make(map[string]struct{}), - schemaInfo: &parseTypes.SchemaInfo{Blocks: make(map[string]*parseTypes.Block)}, - errs: errorListener, - } - - stream := antlr.NewInputStream(kf) - lexer := gen.NewKuneiformLexer(stream) - - // remove default error listener - lexer.RemoveErrorListeners() - lexer.AddErrorListener(errorListener) - - tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) - p := gen.NewKuneiformParser(tokenStream) - - // remove default error listener - p.RemoveErrorListeners() - p.AddErrorListener(errorListener) - - p.BuildParseTrees = true - - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("panic: %v", e) - } - - // if there is a panic, it is likely due to a syntax error - // check for parse errors and return them first - if errorListener.Err() != nil { - // if there is an error listener error, we should swallow the panic - // If the issue persists until after the user has fixed the parse errors, - // the panic will be returned in the else block. - err = nil - parseErrs = errorListener.Errs - } else { - // if there are no parse errors, then there is a bug. - // we should return the panic with a stack trace. - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - - err = fmt.Errorf("%w\n\n%s", err, buf[:stackSize]) - } - } - }() - - schema, ok := p.Program().Accept(visitor).(*types.Schema) - if !ok { - return nil, nil, nil, fmt.Errorf("unexpected result type: %T", schema) - } - - return schema, visitor.schemaInfo, errorListener.Errs, nil -} - -type kfVisitor struct { - *gen.BaseKuneiformParserVisitor - // registeredNames tracks the names of all tables, columns, and indexes - registeredNames map[string]struct{} - schemaInfo *parseTypes.SchemaInfo - errs parseTypes.AntlrErrorListener -} - -// registerBlock registers a new block (table, action, procedure, etc.) -// it checks that the name is unique and panics if it is not. -func (k *kfVisitor) registerBlock(ctx antlr.ParserRuleContext, name string) { - lower := strings.ToLower(name) - if _, ok := k.registeredNames[lower]; ok { - k.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSemantic, fmt.Errorf("conflicting name: "+name)) - return - } - - k.registeredNames[lower] = struct{}{} - - node := &parseTypes.Node{} - node.Set(ctx) - k.schemaInfo.Blocks[lower] = &parseTypes.Block{ - Node: *node, - AbsStart: ctx.GetStart().GetStart(), - AbsEnd: ctx.GetStop().GetStop(), - } -} - -var _ gen.KuneiformParserVisitor = &kfVisitor{} - -func (k *kfVisitor) VisitProgram(ctx *gen.ProgramContext) any { - schema := &types.Schema{ - Name: ctx.Database_declaration().Accept(k).(string), - Tables: arr[*types.Table](len(ctx.AllTable_declaration())), - Extensions: arr[*types.Extension](len(ctx.AllUse_declaration())), - ForeignProcedures: arr[*types.ForeignProcedure](len(ctx.AllForeign_declaration())), - } - - for i, tbl := range ctx.AllTable_declaration() { - schema.Tables[i] = tbl.Accept(k).(*types.Table) - k.registeredNames[schema.Tables[i].Name] = struct{}{} - } - - for i, ext := range ctx.AllUse_declaration() { - schema.Extensions[i] = ext.Accept(k).(*types.Extension) - } - - for _, stmt := range ctx.AllStmt_mode() { - switch { - case stmt.Action_declaration() != nil: - act := stmt.Accept(k).(*types.Action) - schema.Actions = append(schema.Actions, act) - case stmt.Procedure_declaration() != nil: - proc := stmt.Accept(k).(*types.Procedure) - schema.Procedures = append(schema.Procedures, proc) - default: - panic("unexpected stmt mode") - } - } - - for i, foreign := range ctx.AllForeign_declaration() { - schema.ForeignProcedures[i] = foreign.Accept(k).(*types.ForeignProcedure) - } - - return schema -} - -// START OF Table Declaration Parsing: - -func (k *kfVisitor) VisitTable_declaration(ctx *gen.Table_declarationContext) any { - tbl := &types.Table{ - Name: ctx.IDENTIFIER().GetText(), - Columns: arr[*types.Column](len(ctx.AllColumn_def())), - Indexes: arr[*types.Index](len(ctx.AllIndex_def())), - ForeignKeys: arr[*types.ForeignKey](len(ctx.AllForeign_key_def())), - } - - k.registerBlock(ctx, tbl.Name) - - for i, col := range ctx.AllColumn_def() { - tbl.Columns[i] = col.Accept(k).(*types.Column) - } - - for i, idx := range ctx.AllIndex_def() { - tbl.Indexes[i] = idx.Accept(k).(*types.Index) - } - - for i, fk := range ctx.AllForeign_key_def() { - tbl.ForeignKeys[i] = fk.Accept(k).(*types.ForeignKey) - } - - return tbl -} - -func (k *kfVisitor) VisitIndex_def(ctx *gen.Index_defContext) any { - idx := &types.Index{ - Name: ctx.INDEX_NAME().GetText()[1:], // trim off the leading # - } - - switch { - case ctx.PRIMARY() != nil: - idx.Type = types.PRIMARY - case ctx.UNIQUE() != nil: - idx.Type = types.UNIQUE_BTREE - case ctx.INDEX() != nil: - idx.Type = types.BTREE - default: - panic("unexpected index type") - } - - idx.Columns = ctx.GetColumns().Accept(k).([]string) - - return idx -} - -func (k *kfVisitor) VisitForeign_key_def(ctx *gen.Foreign_key_defContext) any { - fk := &types.ForeignKey{ - ChildKeys: ctx.GetChild_keys().Accept(k).([]string), - ParentKeys: ctx.GetParent_keys().Accept(k).([]string), - ParentTable: ctx.GetParent_table().GetText(), - Actions: arr[*types.ForeignKeyAction](len(ctx.AllForeign_key_action())), - } - - for i, act := range ctx.AllForeign_key_action() { - fk.Actions[i] = act.Accept(k).(*types.ForeignKeyAction) - } - - return fk -} - -func (k *kfVisitor) VisitForeign_key_action(ctx *gen.Foreign_key_actionContext) any { - act := &types.ForeignKeyAction{} - - switch { - case ctx.ON_UPDATE() != nil: - act.On = types.ON_UPDATE - case ctx.ON_DELETE() != nil: - act.On = types.ON_DELETE - default: - panic("unexpected foreign key action on type") - } - - switch { - case ctx.DO_CASCADE() != nil: - act.Do = types.DO_CASCADE - case ctx.DO_SET_NULL() != nil: - act.Do = types.DO_SET_NULL - case ctx.DO_SET_DEFAULT() != nil: - act.Do = types.DO_SET_DEFAULT - case ctx.DO_NO_ACTION() != nil: - act.Do = types.DO_NO_ACTION - case ctx.DO_RESTRICT() != nil: - act.Do = types.DO_RESTRICT - default: - panic("unexpected foreign key action do type") - } - - return act -} - -func (k *kfVisitor) VisitColumn_def(ctx *gen.Column_defContext) any { - col := &types.Column{ - Name: ctx.IDENTIFIER().GetText(), - Type: ctx.GetType_().Accept(k).(*types.DataType), - } - - constraints := arr[*types.Attribute](len(ctx.AllConstraint())) - for i, c := range ctx.AllConstraint() { - constraints[i] = c.Accept(k).(*types.Attribute) - } - - col.Attributes = constraints - - return col -} - -func (k *kfVisitor) VisitDEFAULT(ctx *gen.DEFAULTContext) any { - val := ctx.Literal().Accept(k).(string) - - return &types.Attribute{ - Type: types.DEFAULT, - Value: val, - } -} - -func (k *kfVisitor) VisitMAX(ctx *gen.MAXContext) any { - return &types.Attribute{ - Type: types.MAX, - Value: ctx.NUMERIC_LITERAL().GetText(), - } -} - -func (k *kfVisitor) VisitMAX_LEN(ctx *gen.MAX_LENContext) any { - return &types.Attribute{ - Type: types.MAX_LENGTH, - Value: ctx.NUMERIC_LITERAL().GetText(), - } -} - -func (k *kfVisitor) VisitMIN(ctx *gen.MINContext) any { - return &types.Attribute{ - Type: types.MIN, - Value: ctx.NUMERIC_LITERAL().GetText(), - } -} - -func (k *kfVisitor) VisitMIN_LEN(ctx *gen.MIN_LENContext) any { - return &types.Attribute{ - Type: types.MIN_LENGTH, - Value: ctx.NUMERIC_LITERAL().GetText(), - } -} - -func (k *kfVisitor) VisitNOT_NULL(ctx *gen.NOT_NULLContext) any { - return &types.Attribute{ - Type: types.NOT_NULL, - } -} - -func (k *kfVisitor) VisitPRIMARY_KEY(ctx *gen.PRIMARY_KEYContext) any { - return &types.Attribute{ - Type: types.PRIMARY_KEY, - } -} - -func (k *kfVisitor) VisitUNIQUE(ctx *gen.UNIQUEContext) any { - return &types.Attribute{ - Type: types.UNIQUE, - } -} - -// END OF Table Declaration Parsing - -func (k *kfVisitor) VisitDatabase_declaration(ctx *gen.Database_declarationContext) any { - return ctx.IDENTIFIER().GetText() -} - -func (k *kfVisitor) VisitIdentifier_list(ctx *gen.Identifier_listContext) any { - idents := arr[string](len(ctx.AllIDENTIFIER())) - for i, ident := range ctx.AllIDENTIFIER() { - idents[i] = ident.GetText() - } - - return idents -} - -func (k *kfVisitor) VisitLiteral(ctx *gen.LiteralContext) any { - switch { - case ctx.NUMERIC_LITERAL() != nil: - return ctx.NUMERIC_LITERAL().GetText() - case ctx.TEXT_LITERAL() != nil: - // we do not trim the quotes, and will leeave it to - // the backend to handle it - return ctx.TEXT_LITERAL().GetText() - case ctx.BOOLEAN_LITERAL() != nil: - return ctx.BOOLEAN_LITERAL().GetText() - case ctx.BLOB_LITERAL() != nil: - return ctx.BLOB_LITERAL().GetText() - default: - panic("unexpected literal") - } -} - -func (k *kfVisitor) VisitType_selector(ctx *gen.Type_selectorContext) any { - c := &types.DataType{} - - c.Name = ctx.GetType_().GetText() - - if ctx.LBRACKET() != nil { - c.IsArray = true - } - - err := c.Clean() - if err != nil { - panic(err) - } - - return c -} - -func (k *kfVisitor) VisitUse_declaration(ctx *gen.Use_declarationContext) any { - c := &types.Extension{} - for i, ident := range ctx.AllIDENTIFIER() { - // the first identifier is the extension name, - // the last identifier is the alias name, - // all of the in-between identifiers are keys - // for the extension config - if i == 0 { - c.Name = ident.GetText() - continue - } - if i == len(ctx.AllIDENTIFIER())-1 { - c.Alias = ident.GetText() - k.registerBlock(ctx, c.Alias) - continue - } - - value := ctx.Literal(i - 1).Accept(k).(string) - c.Initialization = append(c.Initialization, &types.ExtensionConfig{ - Key: ident.GetText(), - Value: value, - }) - } - - return c -} - -// action/procedure parsing: - -// returns either *types.Action or *types.Procedure -func (k *kfVisitor) VisitStmt_mode(ctx *gen.Stmt_modeContext) any { - annotations := arr[string](len(ctx.AllANNOTATION())) - for i, a := range ctx.AllANNOTATION() { - annotations[i] = a.GetText() - } - - switch { - case ctx.Action_declaration() != nil: - act := ctx.Action_declaration().Accept(k).(*types.Action) - act.Annotations = annotations - - return act - case ctx.Procedure_declaration() != nil: - proc := ctx.Procedure_declaration().Accept(k).(*types.Procedure) - proc.Annotations = annotations - - return proc - default: - panic("unexpected stmt mode") - } -} - -// returns *types.Action -func (k *kfVisitor) VisitAction_declaration(ctx *gen.Action_declarationContext) any { - name := ctx.STMT_IDENTIFIER().GetText() - - k.registerBlock(ctx, name) - - act := &types.Action{ - Name: name, - Annotations: arr[string](0), - Parameters: arr[string](len(ctx.AllSTMT_VAR())), - Body: parseBody(ctx.STMT_BODY().GetText()), - } - - for i, v := range ctx.AllSTMT_VAR() { - act.Parameters[i] = v.GetText() - } - - var hasPubOrPriv bool - act.Modifiers, act.Public, hasPubOrPriv = k.getAccessModifiers(ctx.AllSTMT_ACCESS()) - if !hasPubOrPriv { - k.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSemantic, errors.New("missing public or private modifier")) - } - - return act -} - -func (k *kfVisitor) VisitProcedure_declaration(ctx *gen.Procedure_declarationContext) any { - name := ctx.GetProcedure_name().GetText() - - k.registerBlock(ctx, name) - - proc := &types.Procedure{ - Name: name, - Annotations: arr[string](0), - Body: parseBody(ctx.STMT_BODY().GetText()), - } - - if ctx.Stmt_typed_param_list() != nil { - proc.Parameters = ctx.Stmt_typed_param_list().Accept(k).([]*types.ProcedureParameter) - } - - var hasPubOrPriv bool - proc.Modifiers, proc.Public, hasPubOrPriv = k.getAccessModifiers(ctx.AllSTMT_ACCESS()) - if !hasPubOrPriv { - k.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSemantic, errors.New("missing public or private modifier")) - } - - if ctx.Stmt_return() != nil { - proc.Returns = ctx.Stmt_return().Accept(k).(*types.ProcedureReturn) - } - - return proc -} - -func (k *kfVisitor) VisitStmt_return(ctx *gen.Stmt_returnContext) any { - r := &types.ProcedureReturn{ - IsTable: ctx.STMT_TABLE() != nil, - Fields: arr[*types.NamedType](len(ctx.AllSTMT_IDENTIFIER())), - } - - for i, c := range ctx.AllSTMT_IDENTIFIER() { - r.Fields[i] = &types.NamedType{ - Name: c.GetText(), - Type: ctx.Stmt_type_selector(i).Accept(k).(*types.DataType), - } - } - - return r -} - -// parseBody will parse the body of a procedure or action, removing -// leading and traily braces and whitespace. -func parseBody(b string) string { - b = strings.TrimPrefix(b, "{") - b = strings.TrimSuffix(b, "}") - return b -} - -func (k *kfVisitor) VisitStmt_typed_param_list(ctx *gen.Stmt_typed_param_listContext) any { - params := arr[*types.ProcedureParameter](len(ctx.AllSTMT_VAR())) - - for i, v := range ctx.AllSTMT_VAR() { - params[i] = &types.ProcedureParameter{ - Name: v.GetText(), - Type: ctx.Stmt_type_selector(i).Accept(k).(*types.DataType), - } - } - - return params -} - -func (k *kfVisitor) VisitStmt_type_selector(ctx *gen.Stmt_type_selectorContext) any { - c := &types.DataType{} - - c.Name = ctx.GetType_().GetText() - - if ctx.STMT_ARRAY() != nil { - c.IsArray = true - } - - err := c.Clean() - if err != nil { - panic(err) - } - - return c -} - -func (k *kfVisitor) VisitForeign_declaration(ctx *gen.Foreign_declarationContext) interface { -} { - foreign := &types.ForeignProcedure{ - Name: ctx.GetName().GetText(), - } - - // can either be unnamed_params or named_params. - // regardless, we can throw away the name; it is just for consistency wit other - // parts of the language. - if p := ctx.GetUnnamed_params(); p != nil { - foreign.Parameters = p.Accept(k).([]*types.DataType) - } else if p := ctx.GetNamed_params(); p != nil { - named := p.Accept(k).([]*types.NamedType) - foreign.Parameters = make([]*types.DataType, len(named)) - for i, n := range named { - foreign.Parameters[i] = n.Type - } - } - - // there can be three cases for the return: - // 1. "returns table(id int, name text)" - // 2. "returns (id int, name text)" - // 3. "returns (int, text)" - - if ctx.GetReturn_columns() != nil { - // this will be not nil if either 1 or 2 is chosen - foreign.Returns = &types.ProcedureReturn{ - IsTable: ctx.TABLE() != nil, - Fields: ctx.GetReturn_columns().Accept(k).([]*types.NamedType), - } - } else if ctx.GetUnnamed_return_types() != nil { - // this will be not nil if 3 is chosen - dataTypes := ctx.GetUnnamed_return_types().Accept(k).([]*types.DataType) - namedTypes := make([]*types.NamedType, len(dataTypes)) - for i, dt := range dataTypes { - namedTypes[i] = &types.NamedType{ - Name: fmt.Sprintf("col%d", i), // this gets thrown away anyways in this case - Type: dt, - } - } - - foreign.Returns = &types.ProcedureReturn{ - IsTable: false, - Fields: namedTypes, - } - } - - return foreign -} - -func (k *kfVisitor) VisitTyped_variable_list(ctx *gen.Typed_variable_listContext) interface { -} { - typs := arr[*types.NamedType](len(ctx.AllType_selector())) - for i, ts := range ctx.AllVAR() { - typs[i] = &types.NamedType{ - Name: ts.GetText(), - Type: ctx.Type_selector(i).Accept(k).(*types.DataType), - } - } - - return typs -} - -func (k *kfVisitor) VisitNamed_type_list(ctx *gen.Named_type_listContext) interface { -} { - typs := arr[*types.NamedType](len(ctx.AllIDENTIFIER())) - for i, ident := range ctx.AllIDENTIFIER() { - typs[i] = &types.NamedType{ - Name: ident.GetText(), - Type: ctx.Type_selector(i).Accept(k).(*types.DataType), - } - } - - return typs -} - -func (k *kfVisitor) VisitType_selector_list(ctx *gen.Type_selector_listContext) interface { -} { - typs := arr[*types.DataType](len(ctx.AllType_selector())) - for i, ts := range ctx.AllType_selector() { - typs[i] = ts.Accept(k).(*types.DataType) - } - - return typs -} - -// getAccessModifiers returns the access modifiers for the given context. -// It also returns whether or not the action/procedure is public or private. -// If it can't find public or private, it will return false -func (k *kfVisitor) getAccessModifiers(mods []antlr.TerminalNode) (modifiers []types.Modifier, public bool, foundPublicOrPrivate bool) { - for _, m := range mods { - switch strings.ToLower(m.GetText()) { - case "public": - public = true - foundPublicOrPrivate = true - case "private": - public = false - foundPublicOrPrivate = true - case "view": - modifiers = append(modifiers, types.ModifierView) - case "owner": - modifiers = append(modifiers, types.ModifierOwner) - default: - k.errs.TokenErr(m.GetSymbol(), parseTypes.ParseErrorTypeSemantic, - fmt.Errorf("unexpected modifier: %v", m.GetText())) - return - } - } - - return -} - -// arr will make an array of type A if the input is greater than 0 -func arr[A any](b int) []A { - if b > 0 { - return make([]A, b) - } - return nil -} diff --git a/parse/kuneiform/parser_test.go b/parse/kuneiform/parser_test.go deleted file mode 100644 index 593998b57..000000000 --- a/parse/kuneiform/parser_test.go +++ /dev/null @@ -1,647 +0,0 @@ -package kuneiform - -import ( - "testing" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/stretchr/testify/require" -) - -func Test_Parse(t *testing.T) { - type testCase struct { - name string - kf string - want *types.Schema - } - - tests := []testCase{ - { - name: "simple schema", - kf: ` - database mydb; - - table users { - id int primary key not null, - username text not null unique minlen(5) maxlen(32) - } - - action create_user ($id, $username) public { - insert into users (id, username) values ($id, $username); - } - - procedure get_username ($id int) public view RETURNS (name text) { - return select username from users where id = $id; // this is a comment - } - `, - want: &types.Schema{ - Name: "mydb", - Tables: []*types.Table{ - tblUsers, - }, - Actions: []*types.Action{ - { - Name: "create_user", - Parameters: []string{ - "$id", - "$username", - }, - Public: true, - Body: `insert into users (id, username) values ($id, $username);`, - }, - }, - Procedures: []*types.Procedure{ - { - Name: "get_username", - Parameters: []*types.ProcedureParameter{ - { - Name: "$id", - Type: types.IntType, - }, - }, - Public: true, - Modifiers: []types.Modifier{ - types.ModifierView, - }, - Body: `return select username from users where id = $id; // this is a comment`, - Returns: &types.ProcedureReturn{Fields: []*types.NamedType{ - { - Name: "name", - Type: types.TextType, - }, - }}, - }, - }, - }, - }, - { - name: "foreign key and index", - kf: ` - database mydb; - - table users { - id int primary key not null, - username text not null unique minlen(5) maxlen(32) - } - - table posts { - id int primary key, - author_id int not null, - foreign key (author_id) references users (id) on delete cascade on update cascade, - #idx index(author_id) - } - `, - want: &types.Schema{ - Name: "mydb", - Tables: []*types.Table{ - tblUsers, - { - Name: "posts", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "author_id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - }, - }, - }, - Indexes: []*types.Index{ - { - Name: "idx", - Type: types.BTREE, - Columns: []string{"author_id"}, - }, - }, - ForeignKeys: []*types.ForeignKey{ - { - ChildKeys: []string{"author_id"}, - ParentTable: "users", - ParentKeys: []string{"id"}, - Actions: []*types.ForeignKeyAction{ - { - On: types.ON_DELETE, - Do: types.DO_CASCADE, - }, - { - On: types.ON_UPDATE, - Do: types.DO_CASCADE, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "procedure returns table", - kf: ` - database mydb; - - procedure get_users() public view RETURNS table(id int) { - return select id from users; - } - `, - want: &types.Schema{ - Name: "mydb", - Procedures: []*types.Procedure{ - { - Name: "get_users", - Public: true, - Modifiers: []types.Modifier{ - types.ModifierView, - }, - Body: `return select id from users;`, - Returns: &types.ProcedureReturn{ - IsTable: true, - Fields: []*types.NamedType{ - { - Name: "id", - Type: types.IntType, - }, - }, - }, - }, - }, - }, - }, - { - name: "use", - kf: ` - database mydb; - - uSe myext AS db1; - use myext { - a: 'b', - c: 1 - } aS db2; - `, - want: &types.Schema{ - Name: "mydb", - Extensions: []*types.Extension{ - { - Name: "myext", - Alias: "db1", - }, - { - Name: "myext", - Initialization: []*types.ExtensionConfig{ - { - Key: "a", - Value: "'b'", - }, - { - Key: "c", - Value: "1", - }, - }, - Alias: "db2", - }, - }, - }, - }, - { - name: "annotations", - kf: ` - database mydb; - - @description("this is an annotation") - procedure get_users() public view {} - `, - want: &types.Schema{ - Name: "mydb", - Procedures: []*types.Procedure{ - { - Name: "get_users", - Public: true, - Modifiers: []types.Modifier{ - types.ModifierView, - }, - Annotations: []string{"@description(\"this is an annotation\")"}, - }, - }, - }, - }, - { - name: "all possible constraints", - kf: ` - database mydb; - - table other_users { - id int primary key, - username text not null unique minlen(5) maxlen(32), - age int max(100) min(18) default(18) - } - - table users { - id int primary key, - username text not null unique minlen(5) maxlen(32), - age int max(100) min(18) default(18), - bts blob default(0x00), - foreign key (id) references other_users (id) on delete cascade on update set null, - foreign key (username) references other_users (username) on delete set default on update no action, - foreign key (age) references other_users (age) on delete restrict - } - - table other_uses { - id int primary key, - username text unique, - age int unique - } - `, - want: &types.Schema{ - Name: "mydb", - Tables: []*types.Table{ - { - Name: "other_users", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "username", - Type: types.TextType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - { - Type: types.UNIQUE, - }, - { - Type: types.MIN_LENGTH, - Value: "5", - }, - { - Type: types.MAX_LENGTH, - Value: "32", - }, - }, - }, - { - Name: "age", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.MAX, - Value: "100", - }, - { - Type: types.MIN, - Value: "18", - }, - { - Type: types.DEFAULT, - Value: "18", - }, - }, - }, - }, - }, - { - Name: "users", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "username", - Type: types.TextType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - { - Type: types.UNIQUE, - }, - { - Type: types.MIN_LENGTH, - Value: "5", - }, - { - Type: types.MAX_LENGTH, - Value: "32", - }, - }, - }, - { - Name: "age", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.MAX, - Value: "100", - }, - { - Type: types.MIN, - Value: "18", - }, - { - Type: types.DEFAULT, - Value: "18", - }, - }, - }, - { - Name: "bts", - Type: types.BlobType, - Attributes: []*types.Attribute{ - { - Type: types.DEFAULT, - Value: "0x00", - }, - }, - }, - }, - ForeignKeys: []*types.ForeignKey{ - { - ChildKeys: []string{"id"}, - ParentTable: "other_users", - ParentKeys: []string{"id"}, - Actions: []*types.ForeignKeyAction{ - { - On: types.ON_DELETE, - Do: types.DO_CASCADE, - }, - { - On: types.ON_UPDATE, - Do: types.DO_SET_NULL, - }, - }, - }, - { - ChildKeys: []string{"username"}, - ParentTable: "other_users", - ParentKeys: []string{"username"}, - Actions: []*types.ForeignKeyAction{ - { - On: types.ON_DELETE, - Do: types.DO_SET_DEFAULT, - }, - { - On: types.ON_UPDATE, - Do: types.DO_NO_ACTION, - }, - }, - }, - { - ChildKeys: []string{"age"}, - ParentTable: "other_users", - ParentKeys: []string{"age"}, - Actions: []*types.ForeignKeyAction{ - { - On: types.ON_DELETE, - Do: types.DO_RESTRICT, - }, - }, - }, - }, - }, - { - Name: "other_uses", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "username", - Type: types.TextType, - Attributes: []*types.Attribute{ - { - Type: types.UNIQUE, - }, - }, - }, - { - Name: "age", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.UNIQUE, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "foreign, no parameters, returns nothing", - kf: ` - database mydb; - - foreign procedure get_users() - `, - want: &types.Schema{ - Name: "mydb", - ForeignProcedures: []*types.ForeignProcedure{ - { - Name: "get_users", - }, - }, - }, - }, - { - name: "foreign, with parameters, returns unnamed types", - kf: ` - database mydb; - - foreign procedure get_users(int, text) RETURNS (int, text) - `, - want: &types.Schema{ - Name: "mydb", - ForeignProcedures: []*types.ForeignProcedure{ - { - Name: "get_users", - Parameters: []*types.DataType{ - types.IntType, - types.TextType, - }, - Returns: &types.ProcedureReturn{ - Fields: []*types.NamedType{ - { - Name: "col0", - Type: types.IntType, - }, - { - Name: "col1", - Type: types.TextType, - }, - }, - }, - }, - }, - }, - }, - { - name: "foreign, with parameters, returns named types", - kf: ` - database mydb; - - foreign procedure get_users() RETURNS (id int, name text) - `, - want: &types.Schema{ - Name: "mydb", - ForeignProcedures: []*types.ForeignProcedure{ - { - Name: "get_users", - Returns: &types.ProcedureReturn{ - Fields: []*types.NamedType{ - { - Name: "id", - Type: types.IntType, - }, - { - Name: "name", - Type: types.TextType, - }, - }, - }, - }, - }, - }, - }, - { - name: "foreign, returns table", - kf: ` - database mydb; - - foreign procedure get_users() RETURNS table(id int) - `, - want: &types.Schema{ - Name: "mydb", - ForeignProcedures: []*types.ForeignProcedure{ - { - Name: "get_users", - Returns: &types.ProcedureReturn{ - IsTable: true, - Fields: []*types.NamedType{ - { - Name: "id", - Type: types.IntType, - }, - }, - }, - }, - }, - }, - }, - { - name: "named foreign parameters", - kf: ` - database mydb; - - foreign procedure get_users($id int, $name text) returns (id int, name text) - `, - want: &types.Schema{ - Name: "mydb", - ForeignProcedures: []*types.ForeignProcedure{ - { - Name: "get_users", - Parameters: []*types.DataType{ - types.IntType, - types.TextType, - }, - Returns: &types.ProcedureReturn{ - Fields: []*types.NamedType{ - { - Name: "id", - Type: types.IntType, - }, - { - Name: "name", - Type: types.TextType, - }, - }, - }, - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, _, _, err := Parse(tt.kf) - if err != nil { - t.Fatalf("Parse() error = %v", err) - } - - err = got.Clean() - require.NoError(t, err) - - require.EqualValues(t, tt.want, got) - }) - } -} - -// some default tables for testing -var ( - tblUsers = &types.Table{ - Name: "users", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - { - Type: types.NOT_NULL, - }, - }, - }, - { - Name: "username", - Type: types.TextType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - { - Type: types.UNIQUE, - }, - { - Type: types.MIN_LENGTH, - Value: "5", - }, - { - Type: types.MAX_LENGTH, - Value: "32", - }, - }, - }, - }, - } -) diff --git a/parse/metadata/metadata.go b/parse/metadata/metadata.go deleted file mode 100644 index ed77bc537..000000000 --- a/parse/metadata/metadata.go +++ /dev/null @@ -1,38 +0,0 @@ -// package metadata includes important metadata for the database engine. -// This includes supported functions, contextual variables, and more. -package metadata - -import "github.com/kwilteam/kwil-db/core/types" - -var ( - // PgSessionPrefix is the prefix for all session variables. - // It is used in combination with Postgre's current_setting function - // to set contextual variables. - PgSessionPrefix = "ctx" - // caller is the session variable for the caller. - CallerVar = "caller" - // txid is the session variable for the transaction id. - TxidVar = "txid" - // signer is the session variable for the signer. - SignerVar = "signer" - // PgSessionVars are the session variables that are available in the engine. - // It maps the variable name to its type. - PgSessionVars = map[string]*types.DataType{ - CallerVar: types.TextType, - TxidVar: types.TextType, - SignerVar: types.BlobType, - } -) - -// GetSessionVariable checks if a variable is a session variable. -// If the input has an @, it will be removed. -func GetSessionVariable(name string) (*types.DataType, bool) { - if len(name) == 0 { - return nil, false - } - if name[0] == '@' { - name = name[1:] - } - t, ok := PgSessionVars[name] - return t, ok -} diff --git a/parse/parse.go b/parse/parse.go index 8b429ef31..985f8d8f1 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -4,76 +4,391 @@ package parse import ( "fmt" + "runtime" + "github.com/antlr4-go/antlr/v4" "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/actions" - "github.com/kwilteam/kwil-db/parse/kuneiform" - procedures "github.com/kwilteam/kwil-db/parse/procedures" - parseTypes "github.com/kwilteam/kwil-db/parse/types" + "github.com/kwilteam/kwil-db/parse/gen" ) -// ParseKuneiform parses a Kuneiform schema. It will also perform -// checks on the procedure and SQL syntax, such as syntax validation, -// type checking, and ensuring that all view procedures/actions do not modify state. -func ParseKuneiform(kf string) (*ParseResult, error) { - // we will return the schema on errors, since language servers will want to - // have the schema even if there are errors. - schema, info, errs, err := kuneiform.Parse(kf) +// SchemaParseResult is the result of parsing a schema. +// It returns the resulting schema, as well as any expected errors that occurred during parsing. +// Unexpected errors will not be returned here, but instead in the function returning this type. +type SchemaParseResult struct { + // Schema is the parsed schema. + // The schema can be nil if there are errors. + Schema *types.Schema `json:"schema"` + // ParseErrs is the error listener that contains all the errors that occurred during parsing. + ParseErrs ParseErrs `json:"parse_errs,omitempty"` + // SchemaInfo is the information about the schema. + SchemaInfo *SchemaInfo `json:"schema_info,omitempty"` + // ParsedActions is the ASTs of the parsed actions. + ParsedActions map[string][]ActionStmt `json:"parsed_actions,omitempty"` + // ParsedProcedures is the ASTs of the parsed procedures. + ParsedProcedures map[string][]ProcedureStmt `json:"parsed_procedures,omitempty"` +} + +func (r *SchemaParseResult) Err() error { + return r.ParseErrs.Err() +} + +// ParseAndValidate parses and validates an entire schema. +func ParseAndValidate(kf []byte) (*SchemaParseResult, error) { + res, err := ParseSchema(kf) if err != nil { - return nil, fmt.Errorf("unknown schema error: %w", err) + return nil, err + } + + if res.ParseErrs.Err() != nil { + return res, nil + } + + for _, proc := range res.Schema.Procedures { + ast := res.ParsedProcedures[proc.Name] + procRes, err := analyzeProcedureAST(proc, res.Schema, ast) + if err != nil { + return nil, err + } + + res.ParseErrs.Add(procRes.ParseErrs.Errors()...) + } + + for _, act := range res.Schema.Actions { + ast := res.ParsedActions[act.Name] + actRes, err := analyzeActionAST(act, res.Schema, ast) + if err != nil { + return nil, err + } + + res.ParseErrs.Add(actRes.ParseErrs.Errors()...) } - res := &ParseResult{ - Schema: schema, - Errs: errs, - SchemaInfo: info, + return res, nil +} + +// ParseSchema parses a Kuneiform schema. +// It will not perform validations on the actions and procedures. +// Most users should use ParseAndValidate instead. +func ParseSchema(kf []byte) (res *SchemaParseResult, err error) { + errLis, stream, parser, deferFn := setupParser(string(kf), "schema") + + res = &SchemaParseResult{ + ParseErrs: errLis, + ParsedActions: make(map[string][]ActionStmt), + ParsedProcedures: make(map[string][]ProcedureStmt), } - if res.Err() != nil { - if schema != nil { - // try to clean, but ignore errors since the failed parse - // may have left the schema in a bad state. - schema.Clean() + + visitor := newSchemaVisitor(stream, errLis) + visitor.actions = res.ParsedActions + visitor.procedures = res.ParsedProcedures + + defer func() { + err2 := deferFn(recover()) + if err2 != nil { + err = err2 } + }() + + schema, ok := parser.Schema().Accept(visitor).(*types.Schema) + if !ok { + err = fmt.Errorf("error parsing schema: could not detect return schema. this is likely a bug in the parser") + } + + res.Schema = schema + res.SchemaInfo = visitor.schemaInfo + if errLis.Err() != nil { return res, nil } - err = schema.Clean() - if err != nil { - return nil, err + return res, err +} + +// ProcedureParseResult is the result of parsing a procedure. +// It returns the procedure body AST, as well as any errors that occurred during parsing. +// Unexpected errors will not be returned here, but instead in the function returning this type. +type ProcedureParseResult struct { + // AST is the abstract syntax tree of the procedure. + AST []ProcedureStmt + // Errs are the errors that occurred during parsing and analysis. + // These include syntax errors, type errors, etc. + ParseErrs ParseErrs + // Variables are all variables that are used in the procedure. + Variables map[string]*types.DataType + // CompoundVariables are variables that are created in the procedure. + CompoundVariables map[string]struct{} + // AnonymousReceivers are the anonymous receivers that are used in the procedure, + // in the order they appear + AnonymousReceivers []*types.DataType +} + +// ParseProcedure parses a procedure. +// It takes the procedure definition, as well as the schema. +// It performs type and semantic checks on the procedure. +func ParseProcedure(proc *types.Procedure, schema *types.Schema) (res *ProcedureParseResult, err error) { + return analyzeProcedureAST(proc, schema, nil) +} + +// analyzeProcedureAST analyzes the AST of a procedure. +// If AST is nil, it will parse it from the provided body. This is useful because ASTs +// with custom error positions can be passed in. +func analyzeProcedureAST(proc *types.Procedure, schema *types.Schema, ast []ProcedureStmt) (res *ProcedureParseResult, err error) { + errLis, stream, parser, deferFn := setupParser(proc.Body, "procedure") + defer func() { + err2 := deferFn(recover()) + if err2 != nil { + err = err2 + } + }() + + res = &ProcedureParseResult{ + ParseErrs: errLis, + Variables: make(map[string]*types.DataType), + CompoundVariables: make(map[string]struct{}), } - _, actionErrs, err := actions.AnalyzeActions(schema, &actions.AnalyzeOpts{ - PGSchemaName: schema.DBID(), - SchemaInfo: info, - }) - if err != nil { - return nil, fmt.Errorf("error analyzing actions: %w", err) + if ast == nil { + schemaVisitor := newSchemaVisitor(stream, errLis) + // first parse the body, then visit it. + res.AST = parser.Procedure_block().Accept(schemaVisitor).([]ProcedureStmt) + } else { + res.AST = ast } - res.Errs.Add(actionErrs...) - _, procErrs, err := procedures.AnalyzeProcedures(schema, schema.DBID(), &procedures.AnalyzeOptions{ - SchemaInfo: info, - }) - if err != nil { - return nil, fmt.Errorf("error analyzing procedures: %w", err) + // set the parameters as the initial vars + vars := makeSessionVars() + for _, v := range proc.Parameters { + vars[v.Name] = v.Type } - res.Errs.Add(procErrs...) - return res, nil + visitor := &procedureAnalyzer{ + sqlAnalyzer: sqlAnalyzer{ + blockContext: blockContext{ + schema: schema, + variables: vars, + anonymousVariables: make(map[string]map[string]*types.DataType), + errs: errLis, + }, + sqlCtx: newSQLContext(), + }, + procCtx: newProcedureContext(proc), + procResult: struct { + allLoopReceivers []*loopTargetTracker + anonymousReceivers []*types.DataType + allVariables map[string]*types.DataType + }{ + allVariables: make(map[string]*types.DataType), + }, + } + + // if there are expected errors, return the parse errors. + if errLis.Err() != nil { + return res, nil + } + + // visit the AST + for _, stmt := range res.AST { + stmt.Accept(visitor) + } + + for k, v := range visitor.procResult.allVariables { + res.Variables[k] = v + } + + for _, v := range visitor.procResult.allLoopReceivers { + // if type is nil, it is a compound variable, and we add it to the loop variables + // if not nil, it is a value, and we add it to the other variables + if v.dataType == nil { + res.CompoundVariables[v.name.String()] = struct{}{} + } else { + res.Variables[v.name.String()] = v.dataType + } + } + + // we also need to add all input variables to the variables list + for _, v := range proc.Parameters { + res.Variables[v.Name] = v.Type + } + + res.AnonymousReceivers = visitor.procResult.anonymousReceivers + + return res, err +} + +// SQLParseResult is the result of parsing an SQL statement. +// It returns the SQL AST, as well as any errors that occurred during parsing. +// Unexpected errors will not be returned here, but instead in the function returning this type. +type SQLParseResult struct { + // AST is the abstract syntax tree of the SQL statement. + AST *SQLStatement + // Errs are the errors that occurred during parsing and analysis. + // These include syntax errors, type errors, etc. + ParseErrs ParseErrs + + // Mutative is true if the statement mutates state. + Mutative bool +} + +// ParseSQL parses an SQL statement. +// It requires a schema to be passed in, since SQL statements may reference +// schema objects. +func ParseSQL(sql string, schema *types.Schema) (res *SQLParseResult, err error) { + errLis, stream, parser, deferFn := setupParser(sql, "sql") + + res = &SQLParseResult{ + ParseErrs: errLis, + } + + visitor := &sqlAnalyzer{ + blockContext: blockContext{ + schema: schema, + variables: make(map[string]*types.DataType), // no variables exist for pure SQL calls + anonymousVariables: make(map[string]map[string]*types.DataType), + errs: errLis, + }, + sqlCtx: newSQLContext(), + } + + defer func() { + err2 := deferFn(recover()) + if err2 != nil { + err = err2 + } + }() + + schemaVisitor := newSchemaVisitor(stream, errLis) + + res.AST = parser.Sql().Accept(schemaVisitor).(*SQLStatement) + + if errLis.Err() != nil { + return res, nil + } + + res.AST.Accept(visitor) + res.Mutative = visitor.sqlResult.Mutative + + return res, err } -// ParseResult is the result of parsing a Kuneiform schema. -type ParseResult struct { - Schema *types.Schema `json:"schema"` - Errs parseTypes.ParseErrors `json:"errors,omitempty"` - SchemaInfo *parseTypes.SchemaInfo `json:"schema_info,omitempty"` +// ActionParseResult is the result of parsing an action. +// It returns the action body AST, as well as any errors that occurred during parsing. +// Unexpected errors will not be returned here, but instead in the function returning this type. +type ActionParseResult struct { + AST []ActionStmt + // Errs are the errors that occurred during parsing and analysis. + // These include syntax errors, type errors, etc. + ParseErrs ParseErrs } -// Err returns the first error in the parse result. -func (r *ParseResult) Err() error { - if r == nil { +// ParseAction parses a Kuneiform action. +// It requires a schema to be passed in, since actions may reference +// schema objects. +func ParseAction(action *types.Action, schema *types.Schema) (res *ActionParseResult, err error) { + return analyzeActionAST(action, schema, nil) +} + +// analyzeActionAST analyzes the AST of an action. +// If AST is nil, it will parse it from the provided body. This is useful because ASTs +// with custom error positions can be passed in. +func analyzeActionAST(action *types.Action, schema *types.Schema, ast []ActionStmt) (res *ActionParseResult, err error) { + errLis, stream, parser, deferFn := setupParser(action.Body, "action") + + res = &ActionParseResult{ + ParseErrs: errLis, + } + + defer func() { + err2 := deferFn(recover()) + if err2 != nil { + err = err2 + } + }() + + if ast == nil { + schemaVisitor := newSchemaVisitor(stream, errLis) + res.AST = parser.Action_block().Accept(schemaVisitor).([]ActionStmt) + } else { + res.AST = ast + } + + vars := makeSessionVars() + for _, v := range action.Parameters { + vars[v] = types.UnknownType + } + + visitor := &actionAnalyzer{ + sqlAnalyzer: sqlAnalyzer{ + blockContext: blockContext{ + schema: schema, + variables: vars, + anonymousVariables: make(map[string]map[string]*types.DataType), + errs: errLis, + }, + sqlCtx: newSQLContext(), + }, + schema: schema, + } + + if errLis.Err() != nil { + return res, nil + } + + for _, stmt := range res.AST { + stmt.Accept(visitor) + visitor.sqlAnalyzer.reset() + } + + return res, err +} + +// setupParser sets up the necessary antlr objects for parsing. +// It returns an error listener, an input stream, a parser, and a function that +// handles returned errors. The function should be called within deferred panic catch. +// The deferFn will decide whether errors should be swallowed based on the error listener. +func setupParser(inputStream string, errLisName string) (errLis *errorListener, + stream *antlr.InputStream, parser *gen.KuneiformParser, deferFn func(any) error) { + errLis = newErrorListener(errLisName) + stream = antlr.NewInputStream(inputStream) + + lexer := gen.NewKuneiformLexer(stream) + parser = gen.NewKuneiformParser(antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)) + + // remove defaults + lexer.RemoveErrorListeners() + parser.RemoveErrorListeners() + lexer.AddErrorListener(errLis) + parser.AddErrorListener(errLis) + + parser.BuildParseTrees = true + + deferFn = func(e any) (err error) { + if e != nil { + var ok bool + err, ok = e.(error) + if !ok { + err = fmt.Errorf("panic: %v", e) + } + } + + // if there is a panic, it may be due to a syntax error. + // therefore, we should check for syntax errors first and if + // any occur, swallow the panic and return the syntax errors. + // If the issue persists past syntax errors, the else block + // will return the error. + if errLis.Err() != nil { + return nil + } else if err != nil { + // stack trace since this + buf := make([]byte, 1<<16) + + stackSize := runtime.Stack(buf, false) + err = fmt.Errorf("%w\n\n%s", err, buf[:stackSize]) + + return err + } + return nil } - return r.Errs.Err() + + return errLis, stream, parser, deferFn } diff --git a/parse/parse_test.go b/parse/parse_test.go new file mode 100644 index 000000000..dde473c71 --- /dev/null +++ b/parse/parse_test.go @@ -0,0 +1,1594 @@ +package parse_test + +import ( + "encoding/json" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/kwilteam/kwil-db/core/types" + "github.com/kwilteam/kwil-db/core/utils/order" + "github.com/kwilteam/kwil-db/parse" + "github.com/stretchr/testify/require" +) + +// Test_Kuneiform tests the Kuneiform parser. +func Test_Kuneiform(t *testing.T) { + type testCase struct { + name string + kf string + want *types.Schema + } + + tests := []testCase{ + { + name: "simple schema", + kf: ` + database mydb; + + table users { + id int primary key not null, + username text not null unique minlen(5) maxlen(32) + } + + action create_user ($id, $username) public { + insert into users (id, username) values ($id, $username); + } + + procedure get_username ($id int) public view RETURNS (name text) { + return select username from users where id = $id; // this is a comment + } + `, + want: &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + tblUsers, + }, + Actions: []*types.Action{ + { + Name: "create_user", + Parameters: []string{ + "$id", + "$username", + }, + Public: true, + Body: `insert into users (id, username) values ($id, $username);`, + }, + }, + Procedures: []*types.Procedure{ + { + Name: "get_username", + Parameters: []*types.ProcedureParameter{ + { + Name: "$id", + Type: types.IntType, + }, + }, + Public: true, + Modifiers: []types.Modifier{ + types.ModifierView, + }, + Body: `return select username from users where id = $id;`, + Returns: &types.ProcedureReturn{Fields: []*types.NamedType{ + { + Name: "name", + Type: types.TextType, + }, + }}, + }, + }, + }, + }, + { + name: "foreign key and index", + kf: ` + database mydb; + + table users { + id int primary key not null, + username text not null unique minlen(5) maxlen(32) + } + + table posts { + id int primary key, + author_id int not null, + foreign key (author_id) references users (id) on delete cascade on update cascade, + #idx index(author_id) + } + `, + want: &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + tblUsers, + { + Name: "posts", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "author_id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + }, + }, + }, + Indexes: []*types.Index{ + { + Name: "idx", + Type: types.BTREE, + Columns: []string{"author_id"}, + }, + }, + ForeignKeys: []*types.ForeignKey{ + { + ChildKeys: []string{"author_id"}, + ParentTable: "users", + ParentKeys: []string{"id"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_CASCADE, + }, + { + On: types.ON_UPDATE, + Do: types.DO_CASCADE, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "procedure returns table", + kf: ` + database mydb; + + procedure get_users() public view RETURNS table(id int) { + return select id from users; + } + `, + want: &types.Schema{ + Name: "mydb", + Procedures: []*types.Procedure{ + { + Name: "get_users", + Public: true, + Modifiers: []types.Modifier{ + types.ModifierView, + }, + Body: `return select id from users;`, + Returns: &types.ProcedureReturn{ + IsTable: true, + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + }, + }, + }, + }, + }, + }, + { + name: "use", + kf: ` + database mydb; + + uSe myext AS db1; + use myext { + a: 'b', + c: 1 + } aS db2; + `, + want: &types.Schema{ + Name: "mydb", + Extensions: []*types.Extension{ + { + Name: "myext", + Alias: "db1", + }, + { + Name: "myext", + Initialization: []*types.ExtensionConfig{ + { + Key: "a", + Value: "'b'", + }, + { + Key: "c", + Value: "1", + }, + }, + Alias: "db2", + }, + }, + }, + }, + { + name: "annotations", + kf: ` + database mydb; + + @kgw(authn='true') + procedure get_users() public view {} + `, + want: &types.Schema{ + Name: "mydb", + Procedures: []*types.Procedure{ + { + Name: "get_users", + Public: true, + Modifiers: []types.Modifier{ + types.ModifierView, + }, + Annotations: []string{"@kgw(authn='true')"}, + }, + }, + }, + }, + { + name: "all possible constraints", + kf: ` + database mydb; + + table other_users { + id int primary key, + username text not null unique minlen(5) maxlen(32), + age int max(100) min(18) default(18) + } + + table users { + id int primary key, + username text not null unique minlen(5) maxlen(32), + age int max(100) min(18) default(18), + bts blob default(0x00), + foreign key (id) references other_users (id) on delete cascade on update set null, + foreign key (username) references other_users (username) on delete set default on update no action, + foreign key (age) references other_users (age) on delete restrict + } + + table other_uses { + id int primary key, + username text unique, + age int unique + } + `, + want: &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + { + Name: "other_users", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "username", + Type: types.TextType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + { + Type: types.UNIQUE, + }, + { + Type: types.MIN_LENGTH, + Value: "5", + }, + { + Type: types.MAX_LENGTH, + Value: "32", + }, + }, + }, + { + Name: "age", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.MAX, + Value: "100", + }, + { + Type: types.MIN, + Value: "18", + }, + { + Type: types.DEFAULT, + Value: "18", + }, + }, + }, + }, + }, + { + Name: "users", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "username", + Type: types.TextType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + { + Type: types.UNIQUE, + }, + { + Type: types.MIN_LENGTH, + Value: "5", + }, + { + Type: types.MAX_LENGTH, + Value: "32", + }, + }, + }, + { + Name: "age", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.MAX, + Value: "100", + }, + { + Type: types.MIN, + Value: "18", + }, + { + Type: types.DEFAULT, + Value: "18", + }, + }, + }, + { + Name: "bts", + Type: types.BlobType, + Attributes: []*types.Attribute{ + { + Type: types.DEFAULT, + Value: "0x00", + }, + }, + }, + }, + ForeignKeys: []*types.ForeignKey{ + { + ChildKeys: []string{"id"}, + ParentTable: "other_users", + ParentKeys: []string{"id"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_CASCADE, + }, + { + On: types.ON_UPDATE, + Do: types.DO_SET_NULL, + }, + }, + }, + { + ChildKeys: []string{"username"}, + ParentTable: "other_users", + ParentKeys: []string{"username"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_SET_DEFAULT, + }, + { + On: types.ON_UPDATE, + Do: types.DO_NO_ACTION, + }, + }, + }, + { + ChildKeys: []string{"age"}, + ParentTable: "other_users", + ParentKeys: []string{"age"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_RESTRICT, + }, + }, + }, + }, + }, + { + Name: "other_uses", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "username", + Type: types.TextType, + Attributes: []*types.Attribute{ + { + Type: types.UNIQUE, + }, + }, + }, + { + Name: "age", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.UNIQUE, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "foreign, no parameters, returns nothing", + kf: ` + database mydb; + + foreign procedure get_users() + `, + want: &types.Schema{ + Name: "mydb", + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_users", + }, + }, + }, + }, + { + name: "foreign, with parameters, returns unnamed types", + kf: ` + database mydb; + + foreign procedure get_users(int, text) RETURNS (int, text) + `, + want: &types.Schema{ + Name: "mydb", + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_users", + Parameters: []*types.DataType{ + types.IntType, + types.TextType, + }, + Returns: &types.ProcedureReturn{ + Fields: []*types.NamedType{ + { + Name: "col0", + Type: types.IntType, + }, + { + Name: "col1", + Type: types.TextType, + }, + }, + }, + }, + }, + }, + }, + { + name: "foreign, with parameters, returns named types", + kf: ` + database mydb; + + foreign procedure get_users() RETURNS (id int, name text) + `, + want: &types.Schema{ + Name: "mydb", + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_users", + Returns: &types.ProcedureReturn{ + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + { + Name: "name", + Type: types.TextType, + }, + }, + }, + }, + }, + }, + }, + { + name: "foreign, returns table", + kf: ` + database mydb; + + foreign procedure get_users() RETURNS table(id int) + `, + want: &types.Schema{ + Name: "mydb", + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_users", + Returns: &types.ProcedureReturn{ + IsTable: true, + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + }, + }, + }, + }, + }, + }, + { + name: "named foreign parameters", + kf: ` + database mydb; + + foreign procedure get_users($id int, $name text) returns (id int, name text) + `, + want: &types.Schema{ + Name: "mydb", + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_users", + Parameters: []*types.DataType{ + types.IntType, + types.TextType, + }, + Returns: &types.ProcedureReturn{ + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + { + Name: "name", + Type: types.TextType, + }, + }, + }, + }, + }, + }, + }, + { + // this test tries to break case sensitivity in every way possible + name: "case insensitive", + kf: ` + database myDB; + + table UsErS { + iD inT pRimaRy kEy nOt nUll + } + + table posts { + id int primary key, + author_id int not null, + ForEign key (author_ID) references usErs (Id) On delEte cAscade on Update cascadE, + #iDx inDex(author_iD) + } + + uSe myeXt As dB1; + + pRoceDure get_Users($nAme tExt) Public viEw ReTURNS tablE(iD iNt) { + return select id from users; // this wont actually get parsed in this test + } + + fOreign proceduRe get_othEr_Users($Id inT, $nAme Text) RETURNS table(iD inT, Name tExt) + + @kGw( autHn='tRue' ) + AcTion create_User ($Id, $usErname) Public { + insert into users (id, username) values ($id, $username); + } + `, + want: &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + { + Name: "users", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + { + Type: types.NOT_NULL, + }, + }, + }, + }, + }, + { + Name: "posts", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "author_id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + }, + }, + }, + Indexes: []*types.Index{ + { + Name: "idx", + Type: types.BTREE, + Columns: []string{"author_id"}, + }, + }, + ForeignKeys: []*types.ForeignKey{ + { + ChildKeys: []string{"author_id"}, + ParentTable: "users", + ParentKeys: []string{"id"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_CASCADE, + }, + { + On: types.ON_UPDATE, + Do: types.DO_CASCADE, + }, + }, + }, + }, + }, + }, + Extensions: []*types.Extension{ + { + Name: "myext", + Alias: "db1", + }, + }, + Procedures: []*types.Procedure{ + { + Name: "get_users", + Public: true, + Modifiers: []types.Modifier{ + types.ModifierView, + }, + Parameters: []*types.ProcedureParameter{ + { + Name: "$name", + Type: types.TextType, + }, + }, + Returns: &types.ProcedureReturn{ + IsTable: true, + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + }, + }, + Body: `return select id from users;`, // comments will not be parsed + }, + }, + ForeignProcedures: []*types.ForeignProcedure{ + { + Name: "get_other_users", + Parameters: []*types.DataType{ + types.IntType, + types.TextType, + }, + Returns: &types.ProcedureReturn{ + IsTable: true, + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + { + Name: "name", + Type: types.TextType, + }, + }, + }, + }, + }, + Actions: []*types.Action{ + { + Annotations: []string{"@kgw(authn='tRue')"}, + Name: "create_user", + Parameters: []string{ + "$id", + "$username", + }, + Public: true, + Body: `insert into users (id, username) values ($id, $username);`, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, err := parse.ParseSchema([]byte(tt.kf)) + require.NoError(t, err) + require.NoError(t, res.ParseErrs.Err()) + + require.EqualValues(t, tt.want, res.Schema) + + // we will also test that the schemas were properly cleaned. + // we test this by copying the schema to a new schema, cleaning the new schema, and comparing the two. + bts, err := json.Marshal(res.Schema) + require.NoError(t, err) + + var got2 types.Schema + err = json.Unmarshal(bts, &got2) + require.NoError(t, err) + + err = got2.Clean() + require.NoError(t, err) + + got2.Owner = nil // unmarshal sets Owner to empty array, so we need to set it to nil to compare + + require.EqualValues(t, res.Schema, &got2) + }) + } +} + +// some default tables and procedures for testing +var ( + tblUsers = &types.Table{ + Name: "users", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + { + Type: types.NOT_NULL, + }, + }, + }, + { + Name: "username", + Type: types.TextType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + { + Type: types.UNIQUE, + }, + { + Type: types.MIN_LENGTH, + Value: "5", + }, + { + Type: types.MAX_LENGTH, + Value: "32", + }, + }, + }, + }, + } + + tblPosts = &types.Table{ + Name: "posts", + Columns: []*types.Column{ + { + Name: "id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.PRIMARY_KEY, + }, + }, + }, + { + Name: "author_id", + Type: types.IntType, + Attributes: []*types.Attribute{ + { + Type: types.NOT_NULL, + }, + }, + }, + }, + Indexes: []*types.Index{ + { + Name: "idx", + Type: types.BTREE, + Columns: []string{"author_id"}, + }, + }, + ForeignKeys: []*types.ForeignKey{ + { + ChildKeys: []string{"author_id"}, + ParentTable: "users", + ParentKeys: []string{"id"}, + Actions: []*types.ForeignKeyAction{ + { + On: types.ON_DELETE, + Do: types.DO_CASCADE, + }, + { + On: types.ON_UPDATE, + Do: types.DO_CASCADE, + }, + }, + }, + }, + } + + procGetAllUserIds = &types.Procedure{ + Name: "get_all_user_ids", + Public: true, + Modifiers: []types.Modifier{ + types.ModifierView, + }, + Returns: &types.ProcedureReturn{ + IsTable: true, + Fields: []*types.NamedType{ + { + Name: "id", + Type: types.IntType, + }, + }, + }, + Body: `return select id from users;`, + } +) + +func Test_Procedure(t *testing.T) { + type testCase struct { + name string + proc string + // inputs should be a map of $var to type + inputs map[string]*types.DataType + // returns is the expected return type + // it can be left nil if there is no return type. + returns *types.ProcedureReturn + // want is the desired output. + // Errs should be left nil for this test, + // and passed in the test case. + // inputs will automatically be added + // to the expected output as variables. + want *parse.ProcedureParseResult + err error + } + + tests := []testCase{ + { + name: "simple procedure", + proc: `$a int := 1;`, + want: &parse.ProcedureParseResult{ + Variables: map[string]*types.DataType{ + "$a": types.IntType, + }, + AST: []parse.ProcedureStmt{ + &parse.ProcedureStmtAssign{ + Variable: exprVar("$a"), + Type: types.IntType, + Value: exprLit(1), + }, + }, + }, + }, + { + name: "for loop", + proc: ` + $found := false; + for $row in SELECT * FROM users { + $found := true; + INSERT INTO posts (id, author_id) VALUES ($row.id, $row.username::int); + } + if !$found { + error('no users found'); + } + `, + want: &parse.ProcedureParseResult{ + CompoundVariables: map[string]struct{}{ + "$row": {}, + }, + Variables: map[string]*types.DataType{ + "$found": types.BoolType, + }, + AST: []parse.ProcedureStmt{ + &parse.ProcedureStmtAssign{ + Variable: exprVar("$found"), + Value: exprLit(false), + }, + &parse.ProcedureStmtForLoop{ + Receiver: exprVar("$row"), + LoopTerm: &parse.LoopTermSQL{ + Statement: &parse.SQLStatement{ + SQL: &parse.SelectStatement{ + SelectCores: []*parse.SelectCore{ + { + Columns: []parse.ResultColumn{ + &parse.ResultColumnWildcard{}, + }, + From: &parse.RelationTable{ + Table: "users", + }, + }, + }, + // apply default ordering + Ordering: []*parse.OrderingTerm{ + { + Expression: &parse.ExpressionColumn{ + Table: "users", + Column: "id", + }, + }, + }, + }, + }, + }, + Body: []parse.ProcedureStmt{ + &parse.ProcedureStmtAssign{ + Variable: exprVar("$found"), + Value: exprLit(true), + }, + &parse.ProcedureStmtSQL{ + SQL: &parse.SQLStatement{ + SQL: &parse.InsertStatement{ + Table: "posts", + Columns: []string{"id", "author_id"}, + Values: [][]parse.Expression{ + { + &parse.ExpressionFieldAccess{ + Record: exprVar("$row"), + Field: "id", + }, + &parse.ExpressionFieldAccess{ + Record: exprVar("$row"), + Field: "username", + Typecastable: parse.Typecastable{ + TypeCast: types.IntType, + }, + }, + }, + }, + }, + }, + }, + }, + }, + &parse.ProcedureStmtIf{ + IfThens: []*parse.IfThen{ + { + If: &parse.ExpressionUnary{ + Operator: parse.UnaryOperatorNot, + Expression: exprVar("$found"), + }, + Then: []parse.ProcedureStmt{ + &parse.ProcedureStmtCall{ + Call: &parse.ExpressionFunctionCall{ + Name: "error", + Args: []parse.Expression{ + exprLit("no users found"), + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "arrays", + proc: ` + $arr2 := array_append($arr, 2); + $arr3 int[] := array_prepend(3, $arr2); + $arr4 := [4,5]; + + $arr5 := array_cat($arr3, $arr4); + `, + inputs: map[string]*types.DataType{ + "$arr": types.ArrayType(types.IntType), + }, + want: &parse.ProcedureParseResult{ + Variables: map[string]*types.DataType{ + "$arr2": types.ArrayType(types.IntType), + "$arr3": types.ArrayType(types.IntType), + "$arr4": types.ArrayType(types.IntType), + "$arr5": types.ArrayType(types.IntType), + }, + AST: []parse.ProcedureStmt{ + &parse.ProcedureStmtCall{ + Receivers: []*parse.ExpressionVariable{ + exprVar("$arr2"), + }, + Call: &parse.ExpressionFunctionCall{ + Name: "array_append", + Args: []parse.Expression{ + exprVar("$arr"), + exprLit(2), + }, + }, + }, + &parse.ProcedureStmtAssign{ + Variable: exprVar("$arr3"), + Type: types.ArrayType(types.IntType), + Value: &parse.ExpressionFunctionCall{ + Name: "array_prepend", + Args: []parse.Expression{ + exprLit(3), + exprVar("$arr2"), + }, + }, + }, + &parse.ProcedureStmtAssign{ + Variable: exprVar("$arr4"), + Value: &parse.ExpressionMakeArray{ + Values: []parse.Expression{ + exprLit(4), + exprLit(5), + }, + }, + }, + &parse.ProcedureStmtCall{ + Receivers: []*parse.ExpressionVariable{ + exprVar("$arr5"), + }, + Call: &parse.ExpressionFunctionCall{ + Name: "array_cat", + Args: []parse.Expression{ + exprVar("$arr3"), + exprVar("$arr4"), + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var params []*types.ProcedureParameter + for _, in := range order.OrderMap(tt.inputs) { + params = append(params, &types.ProcedureParameter{ + Name: in.Key, + Type: in.Value, + }) + } + + proc := &types.Procedure{ + Name: "test", + Parameters: params, + Public: true, + Returns: tt.returns, + Body: tt.proc, + } + + res, err := parse.ParseProcedure(proc, &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + tblUsers, + tblPosts, + }, + Procedures: []*types.Procedure{ + proc, + procGetAllUserIds, + }, + }) + require.NoError(t, err) + + if tt.err != nil { + require.Equal(t, tt.err, res.ParseErrs.Err()) + return + } + require.NoError(t, res.ParseErrs.Err()) + + // set res errs to nil to match test + res.ParseErrs = nil + + if tt.want.CompoundVariables == nil { + tt.want.CompoundVariables = make(map[string]struct{}) + } + if tt.want.Variables == nil { + tt.want.Variables = make(map[string]*types.DataType) + } + + // add the inputs to the expected output + for k, v := range tt.inputs { + tt.want.Variables[k] = v + } + + if !deepCompare(tt.want, res) { + t.Errorf("unexpected output: %s", diff(tt.want, res)) + } + }) + } +} + +// exprVar makes an ExpressionVariable. +func exprVar(n string) *parse.ExpressionVariable { + if n[0] != '$' && n[0] != '@' { + panic("TEST ERROR: variable name must start with $ or @") + } + pref := parse.VariablePrefix(n[0]) + + return &parse.ExpressionVariable{ + Name: n[1:], + Prefix: pref, + } +} + +// exprLit makes an ExpressionLiteral. +// it can only make strings and ints +func exprLit(v any) *parse.ExpressionLiteral { + switch t := v.(type) { + case int: + return &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(t), + } + case int64: + return &parse.ExpressionLiteral{ + Type: types.IntType, + Value: t, + } + case string: + return &parse.ExpressionLiteral{ + Type: types.TextType, + Value: t, + } + case bool: + return &parse.ExpressionLiteral{ + Type: types.BoolType, + Value: t, + } + default: + panic("TEST ERROR: invalid type for literal") + } +} + +func Test_SQL(t *testing.T) { + type testCase struct { + name string + sql string + want *parse.SQLStatement + err error + } + + tests := []testCase{ + { + name: "simple select", + sql: "select *, id i, length(username) as name_len from users u where u.id = 1;", + want: &parse.SQLStatement{ + SQL: &parse.SelectStatement{ + SelectCores: []*parse.SelectCore{ + { + Columns: []parse.ResultColumn{ + &parse.ResultColumnWildcard{}, + &parse.ResultColumnExpression{ + Expression: &parse.ExpressionColumn{ + Column: "id", + }, + Alias: "i", + }, + &parse.ResultColumnExpression{ + Expression: &parse.ExpressionFunctionCall{ + Name: "length", + Args: []parse.Expression{ + &parse.ExpressionColumn{ + Column: "username", + }, + }, + }, + Alias: "name_len", + }, + }, + From: &parse.RelationTable{ + Table: "users", + Alias: "u", + }, + Where: &parse.ExpressionComparison{ + Left: &parse.ExpressionColumn{ + Table: "u", + Column: "id", + }, + Operator: parse.ComparisonOperatorEqual, + Right: &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + }, + }, + }, + // apply default ordering + Ordering: []*parse.OrderingTerm{ + { + Expression: &parse.ExpressionColumn{ + Table: "u", + Column: "id", + }, + }, + }, + }, + }, + }, + { + name: "insert", + sql: `insert into posts (id, author_id) values (1, 1), + (2, (SELECT id from users where username = 'user2' LIMIT 1));`, + want: &parse.SQLStatement{ + SQL: &parse.InsertStatement{ + Table: "posts", + Columns: []string{"id", "author_id"}, + Values: [][]parse.Expression{ + { + &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + }, + { + &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(2), + }, + &parse.ExpressionSubquery{ + Subquery: &parse.SelectStatement{ + SelectCores: []*parse.SelectCore{ + { + Columns: []parse.ResultColumn{ + &parse.ResultColumnExpression{ + Expression: &parse.ExpressionColumn{ + Column: "id", + }, + }, + }, + From: &parse.RelationTable{ + Table: "users", + }, + Where: &parse.ExpressionComparison{ + Left: &parse.ExpressionColumn{ + Column: "username", + }, + Operator: parse.ComparisonOperatorEqual, + Right: &parse.ExpressionLiteral{ + Type: types.TextType, + Value: "user2", + }, + }, + }, + }, + Limit: &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + // apply default ordering + Ordering: []*parse.OrderingTerm{ + { + Expression: &parse.ExpressionColumn{ + Table: "users", + Column: "id", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "select join", + sql: `SELECT p.id as id, u.username as author FROM posts AS p + INNER JOIN users AS u ON p.author_id = u.id + WHERE u.username = 'satoshi' order by u.username DESC NULLS LAST;`, + want: &parse.SQLStatement{ + SQL: &parse.SelectStatement{ + SelectCores: []*parse.SelectCore{ + { + Columns: []parse.ResultColumn{ + &parse.ResultColumnExpression{ + Expression: &parse.ExpressionColumn{ + Column: "id", + Table: "p", + }, + Alias: "id", + }, + &parse.ResultColumnExpression{ + Expression: &parse.ExpressionColumn{ + Column: "username", + Table: "u", + }, + Alias: "author", + }, + }, + From: &parse.RelationTable{ + Table: "posts", + Alias: "p", + }, + Joins: []*parse.Join{ + { + Type: parse.JoinTypeInner, + Relation: &parse.RelationTable{ + Table: "users", + Alias: "u", + }, + On: &parse.ExpressionComparison{ + Left: &parse.ExpressionColumn{ + Column: "author_id", + Table: "p", + }, + Operator: parse.ComparisonOperatorEqual, + Right: &parse.ExpressionColumn{ + Column: "id", + Table: "u", + }, + }, + }, + }, + Where: &parse.ExpressionComparison{ + Left: &parse.ExpressionColumn{ + Column: "username", + Table: "u", + }, + Operator: parse.ComparisonOperatorEqual, + Right: &parse.ExpressionLiteral{ + Type: types.TextType, + Value: "satoshi", + }, + }, + }, + }, + + Ordering: []*parse.OrderingTerm{ + { + Expression: &parse.ExpressionColumn{ + Table: "u", + Column: "username", + }, + Order: parse.OrderTypeDesc, + Nulls: parse.NullOrderLast, + }, + // apply default ordering + { + Expression: &parse.ExpressionColumn{ + Table: "p", + Column: "id", + }, + }, + { + Expression: &parse.ExpressionColumn{ + Table: "u", + Column: "id", + }, + }, + }, + }, + }, + }, + { + name: "delete", + sql: "delete from users where id = 1;", + want: &parse.SQLStatement{ + SQL: &parse.DeleteStatement{ + Table: "users", + Where: &parse.ExpressionComparison{ + Left: &parse.ExpressionColumn{ + Column: "id", + }, + Operator: parse.ComparisonOperatorEqual, + Right: &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + }, + }, + }, + }, + { + name: "upsert with conflict - success", + sql: `INSERT INTO users (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = users.id + excluded.id;`, + want: &parse.SQLStatement{ + SQL: &parse.InsertStatement{ + Table: "users", + Columns: []string{"id"}, + Values: [][]parse.Expression{ + { + &parse.ExpressionLiteral{ + Type: types.IntType, + Value: int64(1), + }, + }, + }, + Upsert: &parse.UpsertClause{ + ConflictColumns: []string{"id"}, + DoUpdate: []*parse.UpdateSetClause{ + { + Column: "id", + Value: &parse.ExpressionArithmetic{ + Left: &parse.ExpressionColumn{ + Column: "id", + Table: "users", + }, + Operator: parse.ArithmeticOperatorAdd, + Right: &parse.ExpressionColumn{ + Column: "id", + Table: "excluded", + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "upsert with conflict - ambiguous error", + sql: `INSERT INTO users (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = id + 1;`, + err: parse.ErrAmbiguousConflictTable, + }, + { + name: "select against unnamed procedure", + sql: "select * from get_all_user_ids();", + want: &parse.SQLStatement{ + SQL: &parse.SelectStatement{ + SelectCores: []*parse.SelectCore{ + { + Columns: []parse.ResultColumn{ + &parse.ResultColumnWildcard{}, + }, + From: &parse.RelationFunctionCall{ + FunctionCall: &parse.ExpressionFunctionCall{ + Name: "get_all_user_ids", + }, + }, + }, + }, + // no ordering since the procedure implementation is ordered + }, + }, + }, + { + name: "select join with unnamed subquery", + sql: `SELECT p.id as id, u.username as author FROM posts AS p + INNER JOIN (SELECT id as uid FROM users WHERE id = 1) ON p.author_id = uid;`, + err: parse.ErrUnnamedJoin, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, err := parse.ParseSQL(tt.sql, &types.Schema{ + Name: "mydb", + Tables: []*types.Table{ + tblUsers, + tblPosts, + }, + Procedures: []*types.Procedure{ + procGetAllUserIds, + }, + }) + require.NoError(t, err) + + if res.ParseErrs.Err() != nil { + if tt.err == nil { + t.Errorf("unexpected error: %v", res.ParseErrs.Err()) + } else { + require.ErrorIs(t, res.ParseErrs.Err(), tt.err) + } + + return + } + + if !deepCompare(res.AST, tt.want) { + t.Errorf("unexpected AST:\n%s", diff(res.AST, tt.want)) + } + }) + } +} + +// deepCompare deep compares the values of two nodes. +// It ignores the parseTypes.Node field. +func deepCompare(node1, node2 any) bool { + // we return true for the parseTypes.Node field, + // we also need to ignore the unexported "schema" fields + return cmp.Equal(node1, node2, cmpOpts()...) +} + +// diff returns the diff between two nodes. +func diff(node1, node2 any) string { + return cmp.Diff(node1, node2, cmpOpts()...) +} + +func cmpOpts() []cmp.Option { + return []cmp.Option{ + cmp.AllowUnexported( + parse.ExpressionLiteral{}, + parse.ExpressionFunctionCall{}, + parse.ExpressionForeignCall{}, + parse.ExpressionVariable{}, + parse.ExpressionArrayAccess{}, + parse.ExpressionMakeArray{}, + parse.ExpressionFieldAccess{}, + parse.ExpressionParenthesized{}, + parse.ExpressionColumn{}, + parse.ExpressionSubquery{}, + parse.ProcedureStmtDeclaration{}, + parse.ProcedureStmtAssign{}, + parse.ProcedureStmtCall{}, + parse.ProcedureStmtForLoop{}, + parse.ProcedureStmtIf{}, + parse.ProcedureStmtSQL{}, + parse.ProcedureStmtBreak{}, + parse.ProcedureStmtReturn{}, + parse.ProcedureStmtReturnNext{}, + parse.LoopTermRange{}, + parse.LoopTermSQL{}, + parse.LoopTermVariable{}, + ), + cmp.Comparer(func(x, y parse.Position) bool { + return true + }), + } +} diff --git a/parse/sql/postgres/doc.go b/parse/postgres/doc.go similarity index 100% rename from parse/sql/postgres/doc.go rename to parse/postgres/doc.go diff --git a/parse/sql/postgres/parse.go b/parse/postgres/parse.go similarity index 100% rename from parse/sql/postgres/parse.go rename to parse/postgres/parse.go diff --git a/parse/sql/postgres/parse_cgo.go b/parse/postgres/parse_cgo.go similarity index 100% rename from parse/sql/postgres/parse_cgo.go rename to parse/postgres/parse_cgo.go diff --git a/parse/sql/postgres/parse_test.go b/parse/postgres/parse_test.go similarity index 84% rename from parse/sql/postgres/parse_test.go rename to parse/postgres/parse_test.go index 03bff270c..56d8c72d5 100644 --- a/parse/sql/postgres/parse_test.go +++ b/parse/postgres/parse_test.go @@ -3,7 +3,7 @@ package postgres_test import ( "testing" - "github.com/kwilteam/kwil-db/parse/sql/postgres" + "github.com/kwilteam/kwil-db/parse/postgres" "github.com/stretchr/testify/assert" ) diff --git a/parse/procedures/gen/procedure_lexer.go b/parse/procedures/gen/procedure_lexer.go deleted file mode 100644 index e486586cc..000000000 --- a/parse/procedures/gen/procedure_lexer.go +++ /dev/null @@ -1,320 +0,0 @@ -// Code generated from ProcedureLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen - -import ( - "fmt" - "github.com/antlr4-go/antlr/v4" - "sync" - "unicode" -) - -// Suppress unused import error -var _ = fmt.Printf -var _ = sync.Once{} -var _ = unicode.IsLetter - -type ProcedureLexer struct { - *antlr.BaseLexer - channelNames []string - modeNames []string - // TODO: EOF string -} - -var ProcedureLexerLexerStaticData struct { - once sync.Once - serializedATN []int32 - ChannelNames []string - ModeNames []string - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func procedurelexerLexerInit() { - staticData := &ProcedureLexerLexerStaticData - staticData.ChannelNames = []string{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN", - } - staticData.ModeNames = []string{ - "DEFAULT_MODE", - } - staticData.LiteralNames = []string{ - "", "';'", "'('", "')'", "'{'", "'}'", "','", "'::'", "':'", "'$'", - "'@'", "':='", "'.'", "'['", "']'", "'''", "'_'", "'+'", "'-'", "'*'", - "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'=='", "", "'for'", - "'in'", "'if'", "'elseif'", "'else'", "'to'", "'return'", "'break'", - "'next'", "", "", "", "", "'null'", - } - staticData.SymbolicNames = []string{ - "", "SEMICOLON", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "COMMA", "TYPE_CAST", - "COLON", "DOLLAR", "AT", "ASSIGN", "PERIOD", "LBRACKET", "RBRACKET", - "SINGLE_QUOTE", "UNDERSCORE", "PLUS", "MINUS", "MUL", "DIV", "MOD", - "LT", "LT_EQ", "GT", "GT_EQ", "NEQ", "EQ", "ANY_SQL", "FOR", "IN", "IF", - "ELSEIF", "ELSE", "TO", "RETURN", "BREAK", "NEXT", "BOOLEAN_LITERAL", - "INT_LITERAL", "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", - "VARIABLE", "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", - } - staticData.RuleNames = []string{ - "SEMICOLON", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "COMMA", "TYPE_CAST", - "COLON", "DOLLAR", "AT", "ASSIGN", "PERIOD", "LBRACKET", "RBRACKET", - "SINGLE_QUOTE", "UNDERSCORE", "PLUS", "MINUS", "MUL", "DIV", "MOD", - "LT", "LT_EQ", "GT", "GT_EQ", "NEQ", "EQ", "ANY_SQL", "FOR", "IN", "IF", - "ELSEIF", "ELSE", "TO", "RETURN", "BREAK", "NEXT", "BOOLEAN_LITERAL", - "INT_LITERAL", "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", - "VARIABLE", "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", "WSNL", - "SELECT_", "INSERT_", "UPDATE_", "DELETE_", "WITH_", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 0, 48, 352, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, - 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, - 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, - 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, - 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, - 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, - 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, - 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, - 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, - 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, - 52, 7, 52, 2, 53, 7, 53, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, - 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, - 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, - 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, - 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, - 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, - 1, 27, 1, 27, 1, 27, 3, 27, 175, 8, 27, 1, 27, 1, 27, 4, 27, 179, 8, 27, - 11, 27, 12, 27, 180, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, - 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, - 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, - 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, - 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, - 37, 1, 37, 1, 37, 3, 37, 235, 8, 37, 1, 38, 4, 38, 238, 8, 38, 11, 38, - 12, 38, 239, 1, 39, 1, 39, 1, 39, 1, 39, 4, 39, 246, 8, 39, 11, 39, 12, - 39, 247, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 254, 8, 40, 10, 40, 12, 40, - 257, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, - 42, 5, 42, 268, 8, 42, 10, 42, 12, 42, 271, 9, 42, 1, 43, 1, 43, 3, 43, - 275, 8, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 4, 45, 284, - 8, 45, 11, 45, 12, 45, 285, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 5, - 46, 294, 8, 46, 10, 46, 12, 46, 297, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, - 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 5, 47, 308, 8, 47, 10, 47, 12, 47, 311, - 9, 47, 1, 47, 1, 47, 1, 48, 4, 48, 316, 8, 48, 11, 48, 12, 48, 317, 1, - 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, - 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, - 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, - 1, 53, 1, 295, 0, 54, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, - 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, - 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, - 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, - 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, - 89, 45, 91, 46, 93, 47, 95, 48, 97, 0, 99, 0, 101, 0, 103, 0, 105, 0, 107, - 0, 1, 0, 27, 2, 0, 59, 59, 123, 123, 2, 0, 70, 70, 102, 102, 2, 0, 79, - 79, 111, 111, 2, 0, 82, 82, 114, 114, 2, 0, 73, 73, 105, 105, 2, 0, 78, - 78, 110, 110, 2, 0, 69, 69, 101, 101, 2, 0, 76, 76, 108, 108, 2, 0, 83, - 83, 115, 115, 2, 0, 84, 84, 116, 116, 2, 0, 85, 85, 117, 117, 2, 0, 66, - 66, 98, 98, 2, 0, 65, 65, 97, 97, 2, 0, 75, 75, 107, 107, 2, 0, 88, 88, - 120, 120, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 4, 0, 10, 10, 13, - 13, 39, 39, 92, 92, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, - 97, 122, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 67, 67, - 99, 99, 2, 0, 80, 80, 112, 112, 2, 0, 68, 68, 100, 100, 2, 0, 87, 87, 119, - 119, 2, 0, 72, 72, 104, 104, 361, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, - 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, - 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, - 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, - 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, - 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, - 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, - 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, - 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, - 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, - 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, - 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, - 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 1, 109, - 1, 0, 0, 0, 3, 111, 1, 0, 0, 0, 5, 113, 1, 0, 0, 0, 7, 115, 1, 0, 0, 0, - 9, 117, 1, 0, 0, 0, 11, 119, 1, 0, 0, 0, 13, 121, 1, 0, 0, 0, 15, 124, - 1, 0, 0, 0, 17, 126, 1, 0, 0, 0, 19, 128, 1, 0, 0, 0, 21, 130, 1, 0, 0, - 0, 23, 133, 1, 0, 0, 0, 25, 135, 1, 0, 0, 0, 27, 137, 1, 0, 0, 0, 29, 139, - 1, 0, 0, 0, 31, 141, 1, 0, 0, 0, 33, 143, 1, 0, 0, 0, 35, 145, 1, 0, 0, - 0, 37, 147, 1, 0, 0, 0, 39, 149, 1, 0, 0, 0, 41, 151, 1, 0, 0, 0, 43, 153, - 1, 0, 0, 0, 45, 155, 1, 0, 0, 0, 47, 158, 1, 0, 0, 0, 49, 160, 1, 0, 0, - 0, 51, 163, 1, 0, 0, 0, 53, 166, 1, 0, 0, 0, 55, 174, 1, 0, 0, 0, 57, 182, - 1, 0, 0, 0, 59, 186, 1, 0, 0, 0, 61, 189, 1, 0, 0, 0, 63, 192, 1, 0, 0, - 0, 65, 199, 1, 0, 0, 0, 67, 204, 1, 0, 0, 0, 69, 207, 1, 0, 0, 0, 71, 214, - 1, 0, 0, 0, 73, 220, 1, 0, 0, 0, 75, 234, 1, 0, 0, 0, 77, 237, 1, 0, 0, - 0, 79, 241, 1, 0, 0, 0, 81, 249, 1, 0, 0, 0, 83, 260, 1, 0, 0, 0, 85, 265, - 1, 0, 0, 0, 87, 274, 1, 0, 0, 0, 89, 278, 1, 0, 0, 0, 91, 283, 1, 0, 0, - 0, 93, 289, 1, 0, 0, 0, 95, 303, 1, 0, 0, 0, 97, 315, 1, 0, 0, 0, 99, 319, - 1, 0, 0, 0, 101, 326, 1, 0, 0, 0, 103, 333, 1, 0, 0, 0, 105, 340, 1, 0, - 0, 0, 107, 347, 1, 0, 0, 0, 109, 110, 5, 59, 0, 0, 110, 2, 1, 0, 0, 0, - 111, 112, 5, 40, 0, 0, 112, 4, 1, 0, 0, 0, 113, 114, 5, 41, 0, 0, 114, - 6, 1, 0, 0, 0, 115, 116, 5, 123, 0, 0, 116, 8, 1, 0, 0, 0, 117, 118, 5, - 125, 0, 0, 118, 10, 1, 0, 0, 0, 119, 120, 5, 44, 0, 0, 120, 12, 1, 0, 0, - 0, 121, 122, 5, 58, 0, 0, 122, 123, 5, 58, 0, 0, 123, 14, 1, 0, 0, 0, 124, - 125, 5, 58, 0, 0, 125, 16, 1, 0, 0, 0, 126, 127, 5, 36, 0, 0, 127, 18, - 1, 0, 0, 0, 128, 129, 5, 64, 0, 0, 129, 20, 1, 0, 0, 0, 130, 131, 5, 58, - 0, 0, 131, 132, 5, 61, 0, 0, 132, 22, 1, 0, 0, 0, 133, 134, 5, 46, 0, 0, - 134, 24, 1, 0, 0, 0, 135, 136, 5, 91, 0, 0, 136, 26, 1, 0, 0, 0, 137, 138, - 5, 93, 0, 0, 138, 28, 1, 0, 0, 0, 139, 140, 5, 39, 0, 0, 140, 30, 1, 0, - 0, 0, 141, 142, 5, 95, 0, 0, 142, 32, 1, 0, 0, 0, 143, 144, 5, 43, 0, 0, - 144, 34, 1, 0, 0, 0, 145, 146, 5, 45, 0, 0, 146, 36, 1, 0, 0, 0, 147, 148, - 5, 42, 0, 0, 148, 38, 1, 0, 0, 0, 149, 150, 5, 47, 0, 0, 150, 40, 1, 0, - 0, 0, 151, 152, 5, 37, 0, 0, 152, 42, 1, 0, 0, 0, 153, 154, 5, 60, 0, 0, - 154, 44, 1, 0, 0, 0, 155, 156, 5, 60, 0, 0, 156, 157, 5, 61, 0, 0, 157, - 46, 1, 0, 0, 0, 158, 159, 5, 62, 0, 0, 159, 48, 1, 0, 0, 0, 160, 161, 5, - 62, 0, 0, 161, 162, 5, 61, 0, 0, 162, 50, 1, 0, 0, 0, 163, 164, 5, 33, - 0, 0, 164, 165, 5, 61, 0, 0, 165, 52, 1, 0, 0, 0, 166, 167, 5, 61, 0, 0, - 167, 168, 5, 61, 0, 0, 168, 54, 1, 0, 0, 0, 169, 175, 3, 99, 49, 0, 170, - 175, 3, 101, 50, 0, 171, 175, 3, 103, 51, 0, 172, 175, 3, 105, 52, 0, 173, - 175, 3, 107, 53, 0, 174, 169, 1, 0, 0, 0, 174, 170, 1, 0, 0, 0, 174, 171, - 1, 0, 0, 0, 174, 172, 1, 0, 0, 0, 174, 173, 1, 0, 0, 0, 175, 176, 1, 0, - 0, 0, 176, 178, 3, 97, 48, 0, 177, 179, 8, 0, 0, 0, 178, 177, 1, 0, 0, - 0, 179, 180, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, - 56, 1, 0, 0, 0, 182, 183, 7, 1, 0, 0, 183, 184, 7, 2, 0, 0, 184, 185, 7, - 3, 0, 0, 185, 58, 1, 0, 0, 0, 186, 187, 7, 4, 0, 0, 187, 188, 7, 5, 0, - 0, 188, 60, 1, 0, 0, 0, 189, 190, 7, 4, 0, 0, 190, 191, 7, 1, 0, 0, 191, - 62, 1, 0, 0, 0, 192, 193, 7, 6, 0, 0, 193, 194, 7, 7, 0, 0, 194, 195, 7, - 8, 0, 0, 195, 196, 7, 6, 0, 0, 196, 197, 7, 4, 0, 0, 197, 198, 7, 1, 0, - 0, 198, 64, 1, 0, 0, 0, 199, 200, 7, 6, 0, 0, 200, 201, 7, 7, 0, 0, 201, - 202, 7, 8, 0, 0, 202, 203, 7, 6, 0, 0, 203, 66, 1, 0, 0, 0, 204, 205, 7, - 9, 0, 0, 205, 206, 7, 2, 0, 0, 206, 68, 1, 0, 0, 0, 207, 208, 7, 3, 0, - 0, 208, 209, 7, 6, 0, 0, 209, 210, 7, 9, 0, 0, 210, 211, 7, 10, 0, 0, 211, - 212, 7, 3, 0, 0, 212, 213, 7, 5, 0, 0, 213, 70, 1, 0, 0, 0, 214, 215, 7, - 11, 0, 0, 215, 216, 7, 3, 0, 0, 216, 217, 7, 6, 0, 0, 217, 218, 7, 12, - 0, 0, 218, 219, 7, 13, 0, 0, 219, 72, 1, 0, 0, 0, 220, 221, 7, 5, 0, 0, - 221, 222, 7, 6, 0, 0, 222, 223, 7, 14, 0, 0, 223, 224, 7, 9, 0, 0, 224, - 74, 1, 0, 0, 0, 225, 226, 7, 9, 0, 0, 226, 227, 7, 3, 0, 0, 227, 228, 7, - 10, 0, 0, 228, 235, 7, 6, 0, 0, 229, 230, 7, 1, 0, 0, 230, 231, 7, 12, - 0, 0, 231, 232, 7, 7, 0, 0, 232, 233, 7, 8, 0, 0, 233, 235, 7, 6, 0, 0, - 234, 225, 1, 0, 0, 0, 234, 229, 1, 0, 0, 0, 235, 76, 1, 0, 0, 0, 236, 238, - 7, 15, 0, 0, 237, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 237, 1, 0, - 0, 0, 239, 240, 1, 0, 0, 0, 240, 78, 1, 0, 0, 0, 241, 242, 5, 48, 0, 0, - 242, 243, 7, 14, 0, 0, 243, 245, 1, 0, 0, 0, 244, 246, 7, 16, 0, 0, 245, - 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 248, - 1, 0, 0, 0, 248, 80, 1, 0, 0, 0, 249, 255, 3, 29, 14, 0, 250, 254, 8, 17, - 0, 0, 251, 252, 5, 92, 0, 0, 252, 254, 9, 0, 0, 0, 253, 250, 1, 0, 0, 0, - 253, 251, 1, 0, 0, 0, 254, 257, 1, 0, 0, 0, 255, 253, 1, 0, 0, 0, 255, - 256, 1, 0, 0, 0, 256, 258, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 258, 259, - 3, 29, 14, 0, 259, 82, 1, 0, 0, 0, 260, 261, 7, 5, 0, 0, 261, 262, 7, 10, - 0, 0, 262, 263, 7, 7, 0, 0, 263, 264, 7, 7, 0, 0, 264, 84, 1, 0, 0, 0, - 265, 269, 7, 18, 0, 0, 266, 268, 7, 19, 0, 0, 267, 266, 1, 0, 0, 0, 268, - 271, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 86, 1, - 0, 0, 0, 271, 269, 1, 0, 0, 0, 272, 275, 3, 17, 8, 0, 273, 275, 3, 19, - 9, 0, 274, 272, 1, 0, 0, 0, 274, 273, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, - 276, 277, 3, 85, 42, 0, 277, 88, 1, 0, 0, 0, 278, 279, 3, 97, 48, 0, 279, - 280, 1, 0, 0, 0, 280, 281, 6, 44, 0, 0, 281, 90, 1, 0, 0, 0, 282, 284, - 7, 20, 0, 0, 283, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 283, 1, 0, - 0, 0, 285, 286, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 288, 6, 45, 0, 0, - 288, 92, 1, 0, 0, 0, 289, 290, 5, 47, 0, 0, 290, 291, 5, 42, 0, 0, 291, - 295, 1, 0, 0, 0, 292, 294, 9, 0, 0, 0, 293, 292, 1, 0, 0, 0, 294, 297, - 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 295, 293, 1, 0, 0, 0, 296, 298, 1, 0, - 0, 0, 297, 295, 1, 0, 0, 0, 298, 299, 5, 42, 0, 0, 299, 300, 5, 47, 0, - 0, 300, 301, 1, 0, 0, 0, 301, 302, 6, 46, 0, 0, 302, 94, 1, 0, 0, 0, 303, - 304, 5, 47, 0, 0, 304, 305, 5, 47, 0, 0, 305, 309, 1, 0, 0, 0, 306, 308, - 8, 20, 0, 0, 307, 306, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 307, 1, 0, - 0, 0, 309, 310, 1, 0, 0, 0, 310, 312, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, - 312, 313, 6, 47, 0, 0, 313, 96, 1, 0, 0, 0, 314, 316, 7, 21, 0, 0, 315, - 314, 1, 0, 0, 0, 316, 317, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 317, 318, - 1, 0, 0, 0, 318, 98, 1, 0, 0, 0, 319, 320, 7, 8, 0, 0, 320, 321, 7, 6, - 0, 0, 321, 322, 7, 7, 0, 0, 322, 323, 7, 6, 0, 0, 323, 324, 7, 22, 0, 0, - 324, 325, 7, 9, 0, 0, 325, 100, 1, 0, 0, 0, 326, 327, 7, 4, 0, 0, 327, - 328, 7, 5, 0, 0, 328, 329, 7, 8, 0, 0, 329, 330, 7, 6, 0, 0, 330, 331, - 7, 3, 0, 0, 331, 332, 7, 9, 0, 0, 332, 102, 1, 0, 0, 0, 333, 334, 7, 10, - 0, 0, 334, 335, 7, 23, 0, 0, 335, 336, 7, 24, 0, 0, 336, 337, 7, 12, 0, - 0, 337, 338, 7, 9, 0, 0, 338, 339, 7, 6, 0, 0, 339, 104, 1, 0, 0, 0, 340, - 341, 7, 24, 0, 0, 341, 342, 7, 6, 0, 0, 342, 343, 7, 7, 0, 0, 343, 344, - 7, 6, 0, 0, 344, 345, 7, 9, 0, 0, 345, 346, 7, 6, 0, 0, 346, 106, 1, 0, - 0, 0, 347, 348, 7, 25, 0, 0, 348, 349, 7, 4, 0, 0, 349, 350, 7, 9, 0, 0, - 350, 351, 7, 26, 0, 0, 351, 108, 1, 0, 0, 0, 14, 0, 174, 180, 234, 239, - 247, 253, 255, 269, 274, 285, 295, 309, 317, 1, 0, 1, 0, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// ProcedureLexerInit initializes any static state used to implement ProcedureLexer. By default the -// static state used to implement the lexer is lazily initialized during the first call to -// NewProcedureLexer(). You can call this function if you wish to initialize the static state ahead -// of time. -func ProcedureLexerInit() { - staticData := &ProcedureLexerLexerStaticData - staticData.once.Do(procedurelexerLexerInit) -} - -// NewProcedureLexer produces a new lexer instance for the optional input antlr.CharStream. -func NewProcedureLexer(input antlr.CharStream) *ProcedureLexer { - ProcedureLexerInit() - l := new(ProcedureLexer) - l.BaseLexer = antlr.NewBaseLexer(input) - staticData := &ProcedureLexerLexerStaticData - l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - l.channelNames = staticData.ChannelNames - l.modeNames = staticData.ModeNames - l.RuleNames = staticData.RuleNames - l.LiteralNames = staticData.LiteralNames - l.SymbolicNames = staticData.SymbolicNames - l.GrammarFileName = "ProcedureLexer.g4" - // TODO: l.EOF = antlr.TokenEOF - - return l -} - -// ProcedureLexer tokens. -const ( - ProcedureLexerSEMICOLON = 1 - ProcedureLexerLPAREN = 2 - ProcedureLexerRPAREN = 3 - ProcedureLexerLBRACE = 4 - ProcedureLexerRBRACE = 5 - ProcedureLexerCOMMA = 6 - ProcedureLexerTYPE_CAST = 7 - ProcedureLexerCOLON = 8 - ProcedureLexerDOLLAR = 9 - ProcedureLexerAT = 10 - ProcedureLexerASSIGN = 11 - ProcedureLexerPERIOD = 12 - ProcedureLexerLBRACKET = 13 - ProcedureLexerRBRACKET = 14 - ProcedureLexerSINGLE_QUOTE = 15 - ProcedureLexerUNDERSCORE = 16 - ProcedureLexerPLUS = 17 - ProcedureLexerMINUS = 18 - ProcedureLexerMUL = 19 - ProcedureLexerDIV = 20 - ProcedureLexerMOD = 21 - ProcedureLexerLT = 22 - ProcedureLexerLT_EQ = 23 - ProcedureLexerGT = 24 - ProcedureLexerGT_EQ = 25 - ProcedureLexerNEQ = 26 - ProcedureLexerEQ = 27 - ProcedureLexerANY_SQL = 28 - ProcedureLexerFOR = 29 - ProcedureLexerIN = 30 - ProcedureLexerIF = 31 - ProcedureLexerELSEIF = 32 - ProcedureLexerELSE = 33 - ProcedureLexerTO = 34 - ProcedureLexerRETURN = 35 - ProcedureLexerBREAK = 36 - ProcedureLexerNEXT = 37 - ProcedureLexerBOOLEAN_LITERAL = 38 - ProcedureLexerINT_LITERAL = 39 - ProcedureLexerBLOB_LITERAL = 40 - ProcedureLexerTEXT_LITERAL = 41 - ProcedureLexerNULL_LITERAL = 42 - ProcedureLexerIDENTIFIER = 43 - ProcedureLexerVARIABLE = 44 - ProcedureLexerWS = 45 - ProcedureLexerTERMINATOR = 46 - ProcedureLexerBLOCK_COMMENT = 47 - ProcedureLexerLINE_COMMENT = 48 -) diff --git a/parse/procedures/gen/procedure_parser.go b/parse/procedures/gen/procedure_parser.go deleted file mode 100644 index ebc1c2b1d..000000000 --- a/parse/procedures/gen/procedure_parser.go +++ /dev/null @@ -1,4526 +0,0 @@ -// Code generated from ProcedureParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // ProcedureParser -import ( - "fmt" - "strconv" - "sync" - - "github.com/antlr4-go/antlr/v4" -) - -// Suppress unused import errors -var _ = fmt.Printf -var _ = strconv.Itoa -var _ = sync.Once{} - -type ProcedureParser struct { - *antlr.BaseParser -} - -var ProcedureParserParserStaticData struct { - once sync.Once - serializedATN []int32 - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func procedureparserParserInit() { - staticData := &ProcedureParserParserStaticData - staticData.LiteralNames = []string{ - "", "';'", "'('", "')'", "'{'", "'}'", "','", "'::'", "':'", "'$'", - "'@'", "':='", "'.'", "'['", "']'", "'''", "'_'", "'+'", "'-'", "'*'", - "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'=='", "", "'for'", - "'in'", "'if'", "'elseif'", "'else'", "'to'", "'return'", "'break'", - "'next'", "", "", "", "", "'null'", - } - staticData.SymbolicNames = []string{ - "", "SEMICOLON", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "COMMA", "TYPE_CAST", - "COLON", "DOLLAR", "AT", "ASSIGN", "PERIOD", "LBRACKET", "RBRACKET", - "SINGLE_QUOTE", "UNDERSCORE", "PLUS", "MINUS", "MUL", "DIV", "MOD", - "LT", "LT_EQ", "GT", "GT_EQ", "NEQ", "EQ", "ANY_SQL", "FOR", "IN", "IF", - "ELSEIF", "ELSE", "TO", "RETURN", "BREAK", "NEXT", "BOOLEAN_LITERAL", - "INT_LITERAL", "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", - "VARIABLE", "WS", "TERMINATOR", "BLOCK_COMMENT", "LINE_COMMENT", - } - staticData.RuleNames = []string{ - "program", "statement", "variable_or_underscore", "type", "expression", - "type_cast", "expression_list", "expression_make_array", "call_expression", - "range", "if_then_block", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 1, 48, 244, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, - 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 1, 0, 5, 0, 24, 8, 0, 10, 0, 12, 0, 27, 9, 0, 1, 0, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 38, 8, 1, 10, 1, 12, 1, 41, 9, 1, - 1, 1, 1, 1, 3, 1, 45, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 68, 8, 1, 1, 1, 1, 1, 5, 1, 72, 8, 1, 10, 1, 12, 1, 75, - 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 82, 8, 1, 10, 1, 12, 1, 85, 9, - 1, 1, 1, 1, 1, 1, 1, 5, 1, 90, 8, 1, 10, 1, 12, 1, 93, 9, 1, 1, 1, 3, 1, - 96, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 105, 8, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 113, 8, 1, 1, 2, 1, 2, 1, 3, 1, - 3, 1, 3, 3, 3, 120, 8, 3, 1, 4, 1, 4, 1, 4, 3, 4, 125, 8, 4, 1, 4, 1, 4, - 3, 4, 129, 8, 4, 1, 4, 1, 4, 3, 4, 133, 8, 4, 1, 4, 1, 4, 3, 4, 137, 8, - 4, 1, 4, 1, 4, 3, 4, 141, 8, 4, 1, 4, 1, 4, 3, 4, 145, 8, 4, 1, 4, 1, 4, - 3, 4, 149, 8, 4, 1, 4, 1, 4, 3, 4, 153, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, - 4, 159, 8, 4, 3, 4, 161, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, - 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 177, 8, 4, 1, 4, 1, 4, - 1, 4, 1, 4, 3, 4, 183, 8, 4, 5, 4, 185, 8, 4, 10, 4, 12, 4, 188, 9, 4, - 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 194, 8, 5, 1, 6, 1, 6, 1, 6, 5, 6, 199, 8, - 6, 10, 6, 12, 6, 202, 9, 6, 1, 7, 1, 7, 3, 7, 206, 8, 7, 1, 7, 1, 7, 1, - 8, 1, 8, 1, 8, 3, 8, 213, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, - 8, 1, 8, 1, 8, 3, 8, 224, 8, 8, 1, 8, 1, 8, 3, 8, 228, 8, 8, 1, 9, 1, 9, - 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 5, 10, 237, 8, 10, 10, 10, 12, 10, 240, - 9, 10, 1, 10, 1, 10, 1, 10, 0, 1, 8, 11, 0, 2, 4, 6, 8, 10, 12, 14, 16, - 18, 20, 0, 4, 2, 0, 16, 16, 44, 44, 1, 0, 22, 27, 1, 0, 19, 21, 1, 0, 17, - 18, 284, 0, 25, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 4, 114, 1, 0, 0, 0, 6, - 116, 1, 0, 0, 0, 8, 160, 1, 0, 0, 0, 10, 189, 1, 0, 0, 0, 12, 195, 1, 0, - 0, 0, 14, 203, 1, 0, 0, 0, 16, 227, 1, 0, 0, 0, 18, 229, 1, 0, 0, 0, 20, - 233, 1, 0, 0, 0, 22, 24, 3, 2, 1, 0, 23, 22, 1, 0, 0, 0, 24, 27, 1, 0, - 0, 0, 25, 23, 1, 0, 0, 0, 25, 26, 1, 0, 0, 0, 26, 28, 1, 0, 0, 0, 27, 25, - 1, 0, 0, 0, 28, 29, 5, 0, 0, 1, 29, 1, 1, 0, 0, 0, 30, 31, 5, 44, 0, 0, - 31, 32, 3, 6, 3, 0, 32, 33, 5, 1, 0, 0, 33, 113, 1, 0, 0, 0, 34, 39, 3, - 4, 2, 0, 35, 36, 5, 6, 0, 0, 36, 38, 3, 4, 2, 0, 37, 35, 1, 0, 0, 0, 38, - 41, 1, 0, 0, 0, 39, 37, 1, 0, 0, 0, 39, 40, 1, 0, 0, 0, 40, 42, 1, 0, 0, - 0, 41, 39, 1, 0, 0, 0, 42, 43, 5, 11, 0, 0, 43, 45, 1, 0, 0, 0, 44, 34, - 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 47, 3, 16, 8, 0, - 47, 48, 5, 1, 0, 0, 48, 113, 1, 0, 0, 0, 49, 50, 5, 44, 0, 0, 50, 51, 5, - 11, 0, 0, 51, 52, 3, 8, 4, 0, 52, 53, 5, 1, 0, 0, 53, 113, 1, 0, 0, 0, - 54, 55, 5, 44, 0, 0, 55, 56, 3, 6, 3, 0, 56, 57, 5, 11, 0, 0, 57, 58, 3, - 8, 4, 0, 58, 59, 5, 1, 0, 0, 59, 113, 1, 0, 0, 0, 60, 61, 5, 29, 0, 0, - 61, 62, 5, 44, 0, 0, 62, 67, 5, 30, 0, 0, 63, 68, 3, 18, 9, 0, 64, 68, - 3, 16, 8, 0, 65, 68, 5, 44, 0, 0, 66, 68, 5, 28, 0, 0, 67, 63, 1, 0, 0, - 0, 67, 64, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 66, 1, 0, 0, 0, 68, 69, - 1, 0, 0, 0, 69, 73, 5, 4, 0, 0, 70, 72, 3, 2, 1, 0, 71, 70, 1, 0, 0, 0, - 72, 75, 1, 0, 0, 0, 73, 71, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 76, 1, - 0, 0, 0, 75, 73, 1, 0, 0, 0, 76, 113, 5, 5, 0, 0, 77, 78, 5, 31, 0, 0, - 78, 83, 3, 20, 10, 0, 79, 80, 5, 32, 0, 0, 80, 82, 3, 20, 10, 0, 81, 79, - 1, 0, 0, 0, 82, 85, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, - 84, 95, 1, 0, 0, 0, 85, 83, 1, 0, 0, 0, 86, 87, 5, 33, 0, 0, 87, 91, 5, - 4, 0, 0, 88, 90, 3, 2, 1, 0, 89, 88, 1, 0, 0, 0, 90, 93, 1, 0, 0, 0, 91, - 89, 1, 0, 0, 0, 91, 92, 1, 0, 0, 0, 92, 94, 1, 0, 0, 0, 93, 91, 1, 0, 0, - 0, 94, 96, 5, 5, 0, 0, 95, 86, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 113, - 1, 0, 0, 0, 97, 98, 5, 28, 0, 0, 98, 113, 5, 1, 0, 0, 99, 100, 5, 36, 0, - 0, 100, 113, 5, 1, 0, 0, 101, 104, 5, 35, 0, 0, 102, 105, 3, 12, 6, 0, - 103, 105, 5, 28, 0, 0, 104, 102, 1, 0, 0, 0, 104, 103, 1, 0, 0, 0, 105, - 106, 1, 0, 0, 0, 106, 113, 5, 1, 0, 0, 107, 108, 5, 35, 0, 0, 108, 109, - 5, 37, 0, 0, 109, 110, 3, 12, 6, 0, 110, 111, 5, 1, 0, 0, 111, 113, 1, - 0, 0, 0, 112, 30, 1, 0, 0, 0, 112, 44, 1, 0, 0, 0, 112, 49, 1, 0, 0, 0, - 112, 54, 1, 0, 0, 0, 112, 60, 1, 0, 0, 0, 112, 77, 1, 0, 0, 0, 112, 97, - 1, 0, 0, 0, 112, 99, 1, 0, 0, 0, 112, 101, 1, 0, 0, 0, 112, 107, 1, 0, - 0, 0, 113, 3, 1, 0, 0, 0, 114, 115, 7, 0, 0, 0, 115, 5, 1, 0, 0, 0, 116, - 119, 5, 43, 0, 0, 117, 118, 5, 13, 0, 0, 118, 120, 5, 14, 0, 0, 119, 117, - 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 7, 1, 0, 0, 0, 121, 122, 6, 4, -1, - 0, 122, 124, 5, 41, 0, 0, 123, 125, 3, 10, 5, 0, 124, 123, 1, 0, 0, 0, - 124, 125, 1, 0, 0, 0, 125, 161, 1, 0, 0, 0, 126, 128, 5, 38, 0, 0, 127, - 129, 3, 10, 5, 0, 128, 127, 1, 0, 0, 0, 128, 129, 1, 0, 0, 0, 129, 161, - 1, 0, 0, 0, 130, 132, 5, 39, 0, 0, 131, 133, 3, 10, 5, 0, 132, 131, 1, - 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 161, 1, 0, 0, 0, 134, 136, 5, 42, 0, - 0, 135, 137, 3, 10, 5, 0, 136, 135, 1, 0, 0, 0, 136, 137, 1, 0, 0, 0, 137, - 161, 1, 0, 0, 0, 138, 140, 5, 40, 0, 0, 139, 141, 3, 10, 5, 0, 140, 139, - 1, 0, 0, 0, 140, 141, 1, 0, 0, 0, 141, 161, 1, 0, 0, 0, 142, 144, 3, 14, - 7, 0, 143, 145, 3, 10, 5, 0, 144, 143, 1, 0, 0, 0, 144, 145, 1, 0, 0, 0, - 145, 161, 1, 0, 0, 0, 146, 148, 3, 16, 8, 0, 147, 149, 3, 10, 5, 0, 148, - 147, 1, 0, 0, 0, 148, 149, 1, 0, 0, 0, 149, 161, 1, 0, 0, 0, 150, 152, - 5, 44, 0, 0, 151, 153, 3, 10, 5, 0, 152, 151, 1, 0, 0, 0, 152, 153, 1, - 0, 0, 0, 153, 161, 1, 0, 0, 0, 154, 155, 5, 2, 0, 0, 155, 156, 3, 8, 4, - 0, 156, 158, 5, 3, 0, 0, 157, 159, 3, 10, 5, 0, 158, 157, 1, 0, 0, 0, 158, - 159, 1, 0, 0, 0, 159, 161, 1, 0, 0, 0, 160, 121, 1, 0, 0, 0, 160, 126, - 1, 0, 0, 0, 160, 130, 1, 0, 0, 0, 160, 134, 1, 0, 0, 0, 160, 138, 1, 0, - 0, 0, 160, 142, 1, 0, 0, 0, 160, 146, 1, 0, 0, 0, 160, 150, 1, 0, 0, 0, - 160, 154, 1, 0, 0, 0, 161, 186, 1, 0, 0, 0, 162, 163, 10, 3, 0, 0, 163, - 164, 7, 1, 0, 0, 164, 185, 3, 8, 4, 4, 165, 166, 10, 2, 0, 0, 166, 167, - 7, 2, 0, 0, 167, 185, 3, 8, 4, 3, 168, 169, 10, 1, 0, 0, 169, 170, 7, 3, - 0, 0, 170, 185, 3, 8, 4, 2, 171, 172, 10, 6, 0, 0, 172, 173, 5, 13, 0, - 0, 173, 174, 3, 8, 4, 0, 174, 176, 5, 14, 0, 0, 175, 177, 3, 10, 5, 0, - 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 185, 1, 0, 0, 0, 178, - 179, 10, 5, 0, 0, 179, 180, 5, 12, 0, 0, 180, 182, 5, 43, 0, 0, 181, 183, - 3, 10, 5, 0, 182, 181, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 185, 1, 0, - 0, 0, 184, 162, 1, 0, 0, 0, 184, 165, 1, 0, 0, 0, 184, 168, 1, 0, 0, 0, - 184, 171, 1, 0, 0, 0, 184, 178, 1, 0, 0, 0, 185, 188, 1, 0, 0, 0, 186, - 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 9, 1, 0, 0, 0, 188, 186, 1, - 0, 0, 0, 189, 190, 5, 7, 0, 0, 190, 193, 5, 43, 0, 0, 191, 192, 5, 13, - 0, 0, 192, 194, 5, 14, 0, 0, 193, 191, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, - 194, 11, 1, 0, 0, 0, 195, 200, 3, 8, 4, 0, 196, 197, 5, 6, 0, 0, 197, 199, - 3, 8, 4, 0, 198, 196, 1, 0, 0, 0, 199, 202, 1, 0, 0, 0, 200, 198, 1, 0, - 0, 0, 200, 201, 1, 0, 0, 0, 201, 13, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, - 203, 205, 5, 13, 0, 0, 204, 206, 3, 12, 6, 0, 205, 204, 1, 0, 0, 0, 205, - 206, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 5, 14, 0, 0, 208, 15, - 1, 0, 0, 0, 209, 210, 5, 43, 0, 0, 210, 212, 5, 2, 0, 0, 211, 213, 3, 12, - 6, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, - 214, 228, 5, 3, 0, 0, 215, 216, 5, 43, 0, 0, 216, 217, 5, 13, 0, 0, 217, - 218, 3, 8, 4, 0, 218, 219, 5, 6, 0, 0, 219, 220, 3, 8, 4, 0, 220, 221, - 5, 14, 0, 0, 221, 223, 5, 2, 0, 0, 222, 224, 3, 12, 6, 0, 223, 222, 1, - 0, 0, 0, 223, 224, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 226, 5, 3, 0, - 0, 226, 228, 1, 0, 0, 0, 227, 209, 1, 0, 0, 0, 227, 215, 1, 0, 0, 0, 228, - 17, 1, 0, 0, 0, 229, 230, 3, 8, 4, 0, 230, 231, 5, 8, 0, 0, 231, 232, 3, - 8, 4, 0, 232, 19, 1, 0, 0, 0, 233, 234, 3, 8, 4, 0, 234, 238, 5, 4, 0, - 0, 235, 237, 3, 2, 1, 0, 236, 235, 1, 0, 0, 0, 237, 240, 1, 0, 0, 0, 238, - 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 241, 1, 0, 0, 0, 240, 238, - 1, 0, 0, 0, 241, 242, 5, 5, 0, 0, 242, 21, 1, 0, 0, 0, 32, 25, 39, 44, - 67, 73, 83, 91, 95, 104, 112, 119, 124, 128, 132, 136, 140, 144, 148, 152, - 158, 160, 176, 182, 184, 186, 193, 200, 205, 212, 223, 227, 238, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// ProcedureParserInit initializes any static state used to implement ProcedureParser. By default the -// static state used to implement the parser is lazily initialized during the first call to -// NewProcedureParser(). You can call this function if you wish to initialize the static state ahead -// of time. -func ProcedureParserInit() { - staticData := &ProcedureParserParserStaticData - staticData.once.Do(procedureparserParserInit) -} - -// NewProcedureParser produces a new parser instance for the optional input antlr.TokenStream. -func NewProcedureParser(input antlr.TokenStream) *ProcedureParser { - ProcedureParserInit() - this := new(ProcedureParser) - this.BaseParser = antlr.NewBaseParser(input) - staticData := &ProcedureParserParserStaticData - this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - this.RuleNames = staticData.RuleNames - this.LiteralNames = staticData.LiteralNames - this.SymbolicNames = staticData.SymbolicNames - this.GrammarFileName = "ProcedureParser.g4" - - return this -} - -// ProcedureParser tokens. -const ( - ProcedureParserEOF = antlr.TokenEOF - ProcedureParserSEMICOLON = 1 - ProcedureParserLPAREN = 2 - ProcedureParserRPAREN = 3 - ProcedureParserLBRACE = 4 - ProcedureParserRBRACE = 5 - ProcedureParserCOMMA = 6 - ProcedureParserTYPE_CAST = 7 - ProcedureParserCOLON = 8 - ProcedureParserDOLLAR = 9 - ProcedureParserAT = 10 - ProcedureParserASSIGN = 11 - ProcedureParserPERIOD = 12 - ProcedureParserLBRACKET = 13 - ProcedureParserRBRACKET = 14 - ProcedureParserSINGLE_QUOTE = 15 - ProcedureParserUNDERSCORE = 16 - ProcedureParserPLUS = 17 - ProcedureParserMINUS = 18 - ProcedureParserMUL = 19 - ProcedureParserDIV = 20 - ProcedureParserMOD = 21 - ProcedureParserLT = 22 - ProcedureParserLT_EQ = 23 - ProcedureParserGT = 24 - ProcedureParserGT_EQ = 25 - ProcedureParserNEQ = 26 - ProcedureParserEQ = 27 - ProcedureParserANY_SQL = 28 - ProcedureParserFOR = 29 - ProcedureParserIN = 30 - ProcedureParserIF = 31 - ProcedureParserELSEIF = 32 - ProcedureParserELSE = 33 - ProcedureParserTO = 34 - ProcedureParserRETURN = 35 - ProcedureParserBREAK = 36 - ProcedureParserNEXT = 37 - ProcedureParserBOOLEAN_LITERAL = 38 - ProcedureParserINT_LITERAL = 39 - ProcedureParserBLOB_LITERAL = 40 - ProcedureParserTEXT_LITERAL = 41 - ProcedureParserNULL_LITERAL = 42 - ProcedureParserIDENTIFIER = 43 - ProcedureParserVARIABLE = 44 - ProcedureParserWS = 45 - ProcedureParserTERMINATOR = 46 - ProcedureParserBLOCK_COMMENT = 47 - ProcedureParserLINE_COMMENT = 48 -) - -// ProcedureParser rules. -const ( - ProcedureParserRULE_program = 0 - ProcedureParserRULE_statement = 1 - ProcedureParserRULE_variable_or_underscore = 2 - ProcedureParserRULE_type = 3 - ProcedureParserRULE_expression = 4 - ProcedureParserRULE_type_cast = 5 - ProcedureParserRULE_expression_list = 6 - ProcedureParserRULE_expression_make_array = 7 - ProcedureParserRULE_call_expression = 8 - ProcedureParserRULE_range = 9 - ProcedureParserRULE_if_then_block = 10 -) - -// IProgramContext is an interface to support dynamic dispatch. -type IProgramContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - EOF() antlr.TerminalNode - AllStatement() []IStatementContext - Statement(i int) IStatementContext - - // IsProgramContext differentiates from other interfaces. - IsProgramContext() -} - -type ProgramContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyProgramContext() *ProgramContext { - var p = new(ProgramContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_program - return p -} - -func InitEmptyProgramContext(p *ProgramContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_program -} - -func (*ProgramContext) IsProgramContext() {} - -func NewProgramContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProgramContext { - var p = new(ProgramContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_program - - return p -} - -func (s *ProgramContext) GetParser() antlr.Parser { return s.parser } - -func (s *ProgramContext) EOF() antlr.TerminalNode { - return s.GetToken(ProcedureParserEOF, 0) -} - -func (s *ProgramContext) AllStatement() []IStatementContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStatementContext); ok { - len++ - } - } - - tst := make([]IStatementContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStatementContext); ok { - tst[i] = t.(IStatementContext) - i++ - } - } - - return tst -} - -func (s *ProgramContext) Statement(i int) IStatementContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStatementContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStatementContext) -} - -func (s *ProgramContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ProgramContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *ProgramContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitProgram(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Program() (localctx IProgramContext) { - localctx = NewProgramContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 0, ProcedureParserRULE_program) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(25) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&26494311137280) != 0 { - { - p.SetState(22) - p.Statement() - } - - p.SetState(27) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(28) - p.Match(ProcedureParserEOF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IStatementContext is an interface to support dynamic dispatch. -type IStatementContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsStatementContext differentiates from other interfaces. - IsStatementContext() -} - -type StatementContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStatementContext() *StatementContext { - var p = new(StatementContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_statement - return p -} - -func InitEmptyStatementContext(p *StatementContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_statement -} - -func (*StatementContext) IsStatementContext() {} - -func NewStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StatementContext { - var p = new(StatementContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_statement - - return p -} - -func (s *StatementContext) GetParser() antlr.Parser { return s.parser } - -func (s *StatementContext) CopyAll(ctx *StatementContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *StatementContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *StatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type Stmt_ifContext struct { - StatementContext -} - -func NewStmt_ifContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_ifContext { - var p = new(Stmt_ifContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_ifContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_ifContext) IF() antlr.TerminalNode { - return s.GetToken(ProcedureParserIF, 0) -} - -func (s *Stmt_ifContext) AllIf_then_block() []IIf_then_blockContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IIf_then_blockContext); ok { - len++ - } - } - - tst := make([]IIf_then_blockContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IIf_then_blockContext); ok { - tst[i] = t.(IIf_then_blockContext) - i++ - } - } - - return tst -} - -func (s *Stmt_ifContext) If_then_block(i int) IIf_then_blockContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IIf_then_blockContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IIf_then_blockContext) -} - -func (s *Stmt_ifContext) AllELSEIF() []antlr.TerminalNode { - return s.GetTokens(ProcedureParserELSEIF) -} - -func (s *Stmt_ifContext) ELSEIF(i int) antlr.TerminalNode { - return s.GetToken(ProcedureParserELSEIF, i) -} - -func (s *Stmt_ifContext) ELSE() antlr.TerminalNode { - return s.GetToken(ProcedureParserELSE, 0) -} - -func (s *Stmt_ifContext) LBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACE, 0) -} - -func (s *Stmt_ifContext) RBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACE, 0) -} - -func (s *Stmt_ifContext) AllStatement() []IStatementContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStatementContext); ok { - len++ - } - } - - tst := make([]IStatementContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStatementContext); ok { - tst[i] = t.(IStatementContext) - i++ - } - } - - return tst -} - -func (s *Stmt_ifContext) Statement(i int) IStatementContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStatementContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStatementContext) -} - -func (s *Stmt_ifContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_if(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_breakContext struct { - StatementContext -} - -func NewStmt_breakContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_breakContext { - var p = new(Stmt_breakContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_breakContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_breakContext) BREAK() antlr.TerminalNode { - return s.GetToken(ProcedureParserBREAK, 0) -} - -func (s *Stmt_breakContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_breakContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_break(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_variable_assignment_with_declarationContext struct { - StatementContext -} - -func NewStmt_variable_assignment_with_declarationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_variable_assignment_with_declarationContext { - var p = new(Stmt_variable_assignment_with_declarationContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_variable_assignment_with_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_variable_assignment_with_declarationContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, 0) -} - -func (s *Stmt_variable_assignment_with_declarationContext) Type_() ITypeContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITypeContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITypeContext) -} - -func (s *Stmt_variable_assignment_with_declarationContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(ProcedureParserASSIGN, 0) -} - -func (s *Stmt_variable_assignment_with_declarationContext) Expression() IExpressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Stmt_variable_assignment_with_declarationContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_variable_assignment_with_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_variable_assignment_with_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_variable_declarationContext struct { - StatementContext -} - -func NewStmt_variable_declarationContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_variable_declarationContext { - var p = new(Stmt_variable_declarationContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_variable_declarationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_variable_declarationContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, 0) -} - -func (s *Stmt_variable_declarationContext) Type_() ITypeContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITypeContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITypeContext) -} - -func (s *Stmt_variable_declarationContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_variable_declarationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_variable_declaration(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_return_nextContext struct { - StatementContext -} - -func NewStmt_return_nextContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_return_nextContext { - var p = new(Stmt_return_nextContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_return_nextContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_return_nextContext) RETURN() antlr.TerminalNode { - return s.GetToken(ProcedureParserRETURN, 0) -} - -func (s *Stmt_return_nextContext) NEXT() antlr.TerminalNode { - return s.GetToken(ProcedureParserNEXT, 0) -} - -func (s *Stmt_return_nextContext) Expression_list() IExpression_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_listContext) -} - -func (s *Stmt_return_nextContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_return_nextContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_return_next(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_for_loopContext struct { - StatementContext -} - -func NewStmt_for_loopContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_for_loopContext { - var p = new(Stmt_for_loopContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_for_loopContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_for_loopContext) FOR() antlr.TerminalNode { - return s.GetToken(ProcedureParserFOR, 0) -} - -func (s *Stmt_for_loopContext) AllVARIABLE() []antlr.TerminalNode { - return s.GetTokens(ProcedureParserVARIABLE) -} - -func (s *Stmt_for_loopContext) VARIABLE(i int) antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, i) -} - -func (s *Stmt_for_loopContext) IN() antlr.TerminalNode { - return s.GetToken(ProcedureParserIN, 0) -} - -func (s *Stmt_for_loopContext) LBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACE, 0) -} - -func (s *Stmt_for_loopContext) RBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACE, 0) -} - -func (s *Stmt_for_loopContext) Range_() IRangeContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IRangeContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IRangeContext) -} - -func (s *Stmt_for_loopContext) Call_expression() ICall_expressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_expressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_expressionContext) -} - -func (s *Stmt_for_loopContext) ANY_SQL() antlr.TerminalNode { - return s.GetToken(ProcedureParserANY_SQL, 0) -} - -func (s *Stmt_for_loopContext) AllStatement() []IStatementContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStatementContext); ok { - len++ - } - } - - tst := make([]IStatementContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStatementContext); ok { - tst[i] = t.(IStatementContext) - i++ - } - } - - return tst -} - -func (s *Stmt_for_loopContext) Statement(i int) IStatementContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStatementContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStatementContext) -} - -func (s *Stmt_for_loopContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_for_loop(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_returnContext struct { - StatementContext -} - -func NewStmt_returnContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_returnContext { - var p = new(Stmt_returnContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_returnContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_returnContext) RETURN() antlr.TerminalNode { - return s.GetToken(ProcedureParserRETURN, 0) -} - -func (s *Stmt_returnContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_returnContext) Expression_list() IExpression_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_listContext) -} - -func (s *Stmt_returnContext) ANY_SQL() antlr.TerminalNode { - return s.GetToken(ProcedureParserANY_SQL, 0) -} - -func (s *Stmt_returnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_return(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_procedure_callContext struct { - StatementContext -} - -func NewStmt_procedure_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_procedure_callContext { - var p = new(Stmt_procedure_callContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_procedure_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_procedure_callContext) Call_expression() ICall_expressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_expressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_expressionContext) -} - -func (s *Stmt_procedure_callContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_procedure_callContext) AllVariable_or_underscore() []IVariable_or_underscoreContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IVariable_or_underscoreContext); ok { - len++ - } - } - - tst := make([]IVariable_or_underscoreContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IVariable_or_underscoreContext); ok { - tst[i] = t.(IVariable_or_underscoreContext) - i++ - } - } - - return tst -} - -func (s *Stmt_procedure_callContext) Variable_or_underscore(i int) IVariable_or_underscoreContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IVariable_or_underscoreContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IVariable_or_underscoreContext) -} - -func (s *Stmt_procedure_callContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(ProcedureParserASSIGN, 0) -} - -func (s *Stmt_procedure_callContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(ProcedureParserCOMMA) -} - -func (s *Stmt_procedure_callContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(ProcedureParserCOMMA, i) -} - -func (s *Stmt_procedure_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_procedure_call(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_variable_assignmentContext struct { - StatementContext -} - -func NewStmt_variable_assignmentContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_variable_assignmentContext { - var p = new(Stmt_variable_assignmentContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_variable_assignmentContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_variable_assignmentContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, 0) -} - -func (s *Stmt_variable_assignmentContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(ProcedureParserASSIGN, 0) -} - -func (s *Stmt_variable_assignmentContext) Expression() IExpressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Stmt_variable_assignmentContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_variable_assignmentContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_variable_assignment(s) - - default: - return t.VisitChildren(s) - } -} - -type Stmt_sqlContext struct { - StatementContext -} - -func NewStmt_sqlContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Stmt_sqlContext { - var p = new(Stmt_sqlContext) - - InitEmptyStatementContext(&p.StatementContext) - p.parser = parser - p.CopyAll(ctx.(*StatementContext)) - - return p -} - -func (s *Stmt_sqlContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Stmt_sqlContext) ANY_SQL() antlr.TerminalNode { - return s.GetToken(ProcedureParserANY_SQL, 0) -} - -func (s *Stmt_sqlContext) SEMICOLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserSEMICOLON, 0) -} - -func (s *Stmt_sqlContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitStmt_sql(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Statement() (localctx IStatementContext) { - localctx = NewStatementContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 2, ProcedureParserRULE_statement) - var _la int - - p.SetState(112) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) { - case 1: - localctx = NewStmt_variable_declarationContext(p, localctx) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(30) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(31) - p.Type_() - } - { - p.SetState(32) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 2: - localctx = NewStmt_procedure_callContext(p, localctx) - p.EnterOuterAlt(localctx, 2) - p.SetState(44) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == ProcedureParserUNDERSCORE || _la == ProcedureParserVARIABLE { - { - p.SetState(34) - p.Variable_or_underscore() - } - p.SetState(39) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ProcedureParserCOMMA { - { - p.SetState(35) - p.Match(ProcedureParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(36) - p.Variable_or_underscore() - } - - p.SetState(41) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(42) - p.Match(ProcedureParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(46) - p.Call_expression() - } - { - p.SetState(47) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 3: - localctx = NewStmt_variable_assignmentContext(p, localctx) - p.EnterOuterAlt(localctx, 3) - { - p.SetState(49) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(50) - p.Match(ProcedureParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(51) - p.expression(0) - } - { - p.SetState(52) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 4: - localctx = NewStmt_variable_assignment_with_declarationContext(p, localctx) - p.EnterOuterAlt(localctx, 4) - { - p.SetState(54) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(55) - p.Type_() - } - { - p.SetState(56) - p.Match(ProcedureParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(57) - p.expression(0) - } - { - p.SetState(58) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 5: - localctx = NewStmt_for_loopContext(p, localctx) - p.EnterOuterAlt(localctx, 5) - { - p.SetState(60) - p.Match(ProcedureParserFOR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(61) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(62) - p.Match(ProcedureParserIN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(67) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) { - case 1: - { - p.SetState(63) - p.Range_() - } - - case 2: - { - p.SetState(64) - p.Call_expression() - } - - case 3: - { - p.SetState(65) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 4: - { - p.SetState(66) - p.Match(ProcedureParserANY_SQL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - { - p.SetState(69) - p.Match(ProcedureParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(73) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&26494311137280) != 0 { - { - p.SetState(70) - p.Statement() - } - - p.SetState(75) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(76) - p.Match(ProcedureParserRBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 6: - localctx = NewStmt_ifContext(p, localctx) - p.EnterOuterAlt(localctx, 6) - { - p.SetState(77) - p.Match(ProcedureParserIF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(78) - p.If_then_block() - } - p.SetState(83) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ProcedureParserELSEIF { - { - p.SetState(79) - p.Match(ProcedureParserELSEIF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(80) - p.If_then_block() - } - - p.SetState(85) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(95) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == ProcedureParserELSE { - { - p.SetState(86) - p.Match(ProcedureParserELSE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(87) - p.Match(ProcedureParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(91) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&26494311137280) != 0 { - { - p.SetState(88) - p.Statement() - } - - p.SetState(93) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(94) - p.Match(ProcedureParserRBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - - case 7: - localctx = NewStmt_sqlContext(p, localctx) - p.EnterOuterAlt(localctx, 7) - { - p.SetState(97) - p.Match(ProcedureParserANY_SQL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(98) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 8: - localctx = NewStmt_breakContext(p, localctx) - p.EnterOuterAlt(localctx, 8) - { - p.SetState(99) - p.Match(ProcedureParserBREAK) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(100) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 9: - localctx = NewStmt_returnContext(p, localctx) - p.EnterOuterAlt(localctx, 9) - { - p.SetState(101) - p.Match(ProcedureParserRETURN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(104) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case ProcedureParserLPAREN, ProcedureParserLBRACKET, ProcedureParserBOOLEAN_LITERAL, ProcedureParserINT_LITERAL, ProcedureParserBLOB_LITERAL, ProcedureParserTEXT_LITERAL, ProcedureParserNULL_LITERAL, ProcedureParserIDENTIFIER, ProcedureParserVARIABLE: - { - p.SetState(102) - p.Expression_list() - } - - case ProcedureParserANY_SQL: - { - p.SetState(103) - p.Match(ProcedureParserANY_SQL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - { - p.SetState(106) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 10: - localctx = NewStmt_return_nextContext(p, localctx) - p.EnterOuterAlt(localctx, 10) - { - p.SetState(107) - p.Match(ProcedureParserRETURN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(108) - p.Match(ProcedureParserNEXT) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(109) - p.Expression_list() - } - { - p.SetState(110) - p.Match(ProcedureParserSEMICOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IVariable_or_underscoreContext is an interface to support dynamic dispatch. -type IVariable_or_underscoreContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - VARIABLE() antlr.TerminalNode - UNDERSCORE() antlr.TerminalNode - - // IsVariable_or_underscoreContext differentiates from other interfaces. - IsVariable_or_underscoreContext() -} - -type Variable_or_underscoreContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyVariable_or_underscoreContext() *Variable_or_underscoreContext { - var p = new(Variable_or_underscoreContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_variable_or_underscore - return p -} - -func InitEmptyVariable_or_underscoreContext(p *Variable_or_underscoreContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_variable_or_underscore -} - -func (*Variable_or_underscoreContext) IsVariable_or_underscoreContext() {} - -func NewVariable_or_underscoreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Variable_or_underscoreContext { - var p = new(Variable_or_underscoreContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_variable_or_underscore - - return p -} - -func (s *Variable_or_underscoreContext) GetParser() antlr.Parser { return s.parser } - -func (s *Variable_or_underscoreContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, 0) -} - -func (s *Variable_or_underscoreContext) UNDERSCORE() antlr.TerminalNode { - return s.GetToken(ProcedureParserUNDERSCORE, 0) -} - -func (s *Variable_or_underscoreContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Variable_or_underscoreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Variable_or_underscoreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitVariable_or_underscore(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Variable_or_underscore() (localctx IVariable_or_underscoreContext) { - localctx = NewVariable_or_underscoreContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 4, ProcedureParserRULE_variable_or_underscore) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(114) - _la = p.GetTokenStream().LA(1) - - if !(_la == ProcedureParserUNDERSCORE || _la == ProcedureParserVARIABLE) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITypeContext is an interface to support dynamic dispatch. -type ITypeContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - LBRACKET() antlr.TerminalNode - RBRACKET() antlr.TerminalNode - - // IsTypeContext differentiates from other interfaces. - IsTypeContext() -} - -type TypeContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTypeContext() *TypeContext { - var p = new(TypeContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_type - return p -} - -func InitEmptyTypeContext(p *TypeContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_type -} - -func (*TypeContext) IsTypeContext() {} - -func NewTypeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeContext { - var p = new(TypeContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_type - - return p -} - -func (s *TypeContext) GetParser() antlr.Parser { return s.parser } - -func (s *TypeContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ProcedureParserIDENTIFIER, 0) -} - -func (s *TypeContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACKET, 0) -} - -func (s *TypeContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACKET, 0) -} - -func (s *TypeContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *TypeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *TypeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitType(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Type_() (localctx ITypeContext) { - localctx = NewTypeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 6, ProcedureParserRULE_type) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(116) - p.Match(ProcedureParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(119) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == ProcedureParserLBRACKET { - { - p.SetState(117) - p.Match(ProcedureParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(118) - p.Match(ProcedureParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExpressionContext is an interface to support dynamic dispatch. -type IExpressionContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsExpressionContext differentiates from other interfaces. - IsExpressionContext() -} - -type ExpressionContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExpressionContext() *ExpressionContext { - var p = new(ExpressionContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression - return p -} - -func InitEmptyExpressionContext(p *ExpressionContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression -} - -func (*ExpressionContext) IsExpressionContext() {} - -func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext { - var p = new(ExpressionContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_expression - - return p -} - -func (s *ExpressionContext) GetParser() antlr.Parser { return s.parser } - -func (s *ExpressionContext) CopyAll(ctx *ExpressionContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *ExpressionContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type Expr_array_accessContext struct { - ExpressionContext -} - -func NewExpr_array_accessContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_array_accessContext { - var p = new(Expr_array_accessContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_array_accessContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_array_accessContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *Expr_array_accessContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expr_array_accessContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACKET, 0) -} - -func (s *Expr_array_accessContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACKET, 0) -} - -func (s *Expr_array_accessContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_array_accessContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_array_access(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_arithmeticContext struct { - ExpressionContext -} - -func NewExpr_arithmeticContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_arithmeticContext { - var p = new(Expr_arithmeticContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_arithmeticContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_arithmeticContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *Expr_arithmeticContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expr_arithmeticContext) MUL() antlr.TerminalNode { - return s.GetToken(ProcedureParserMUL, 0) -} - -func (s *Expr_arithmeticContext) DIV() antlr.TerminalNode { - return s.GetToken(ProcedureParserDIV, 0) -} - -func (s *Expr_arithmeticContext) MOD() antlr.TerminalNode { - return s.GetToken(ProcedureParserMOD, 0) -} - -func (s *Expr_arithmeticContext) PLUS() antlr.TerminalNode { - return s.GetToken(ProcedureParserPLUS, 0) -} - -func (s *Expr_arithmeticContext) MINUS() antlr.TerminalNode { - return s.GetToken(ProcedureParserMINUS, 0) -} - -func (s *Expr_arithmeticContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_arithmetic(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_variableContext struct { - ExpressionContext -} - -func NewExpr_variableContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_variableContext { - var p = new(Expr_variableContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_variableContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_variableContext) VARIABLE() antlr.TerminalNode { - return s.GetToken(ProcedureParserVARIABLE, 0) -} - -func (s *Expr_variableContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_variableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_variable(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_null_literalContext struct { - ExpressionContext -} - -func NewExpr_null_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_null_literalContext { - var p = new(Expr_null_literalContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_null_literalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_null_literalContext) NULL_LITERAL() antlr.TerminalNode { - return s.GetToken(ProcedureParserNULL_LITERAL, 0) -} - -func (s *Expr_null_literalContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_null_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_null_literal(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_blob_literalContext struct { - ExpressionContext -} - -func NewExpr_blob_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_blob_literalContext { - var p = new(Expr_blob_literalContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_blob_literalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_blob_literalContext) BLOB_LITERAL() antlr.TerminalNode { - return s.GetToken(ProcedureParserBLOB_LITERAL, 0) -} - -func (s *Expr_blob_literalContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_blob_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_blob_literal(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_comparisonContext struct { - ExpressionContext - left IExpressionContext - operator antlr.Token - right IExpressionContext -} - -func NewExpr_comparisonContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_comparisonContext { - var p = new(Expr_comparisonContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_comparisonContext) GetOperator() antlr.Token { return s.operator } - -func (s *Expr_comparisonContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Expr_comparisonContext) GetLeft() IExpressionContext { return s.left } - -func (s *Expr_comparisonContext) GetRight() IExpressionContext { return s.right } - -func (s *Expr_comparisonContext) SetLeft(v IExpressionContext) { s.left = v } - -func (s *Expr_comparisonContext) SetRight(v IExpressionContext) { s.right = v } - -func (s *Expr_comparisonContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_comparisonContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *Expr_comparisonContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expr_comparisonContext) LT() antlr.TerminalNode { - return s.GetToken(ProcedureParserLT, 0) -} - -func (s *Expr_comparisonContext) LT_EQ() antlr.TerminalNode { - return s.GetToken(ProcedureParserLT_EQ, 0) -} - -func (s *Expr_comparisonContext) GT() antlr.TerminalNode { - return s.GetToken(ProcedureParserGT, 0) -} - -func (s *Expr_comparisonContext) GT_EQ() antlr.TerminalNode { - return s.GetToken(ProcedureParserGT_EQ, 0) -} - -func (s *Expr_comparisonContext) NEQ() antlr.TerminalNode { - return s.GetToken(ProcedureParserNEQ, 0) -} - -func (s *Expr_comparisonContext) EQ() antlr.TerminalNode { - return s.GetToken(ProcedureParserEQ, 0) -} - -func (s *Expr_comparisonContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_comparison(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_boolean_literalContext struct { - ExpressionContext -} - -func NewExpr_boolean_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_boolean_literalContext { - var p = new(Expr_boolean_literalContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_boolean_literalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_boolean_literalContext) BOOLEAN_LITERAL() antlr.TerminalNode { - return s.GetToken(ProcedureParserBOOLEAN_LITERAL, 0) -} - -func (s *Expr_boolean_literalContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_boolean_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_boolean_literal(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_callContext struct { - ExpressionContext -} - -func NewExpr_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_callContext { - var p = new(Expr_callContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_callContext) Call_expression() ICall_expressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICall_expressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICall_expressionContext) -} - -func (s *Expr_callContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_call(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_make_arrayContext struct { - ExpressionContext -} - -func NewExpr_make_arrayContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_make_arrayContext { - var p = new(Expr_make_arrayContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_make_arrayContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_make_arrayContext) Expression_make_array() IExpression_make_arrayContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_make_arrayContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_make_arrayContext) -} - -func (s *Expr_make_arrayContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_make_arrayContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_make_array(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_field_accessContext struct { - ExpressionContext -} - -func NewExpr_field_accessContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_field_accessContext { - var p = new(Expr_field_accessContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_field_accessContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_field_accessContext) Expression() IExpressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expr_field_accessContext) PERIOD() antlr.TerminalNode { - return s.GetToken(ProcedureParserPERIOD, 0) -} - -func (s *Expr_field_accessContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ProcedureParserIDENTIFIER, 0) -} - -func (s *Expr_field_accessContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_field_accessContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_field_access(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_int_literalContext struct { - ExpressionContext -} - -func NewExpr_int_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_int_literalContext { - var p = new(Expr_int_literalContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_int_literalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_int_literalContext) INT_LITERAL() antlr.TerminalNode { - return s.GetToken(ProcedureParserINT_LITERAL, 0) -} - -func (s *Expr_int_literalContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_int_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_int_literal(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_text_literalContext struct { - ExpressionContext -} - -func NewExpr_text_literalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_text_literalContext { - var p = new(Expr_text_literalContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_text_literalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_text_literalContext) TEXT_LITERAL() antlr.TerminalNode { - return s.GetToken(ProcedureParserTEXT_LITERAL, 0) -} - -func (s *Expr_text_literalContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_text_literalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_text_literal(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_parenthesizedContext struct { - ExpressionContext -} - -func NewExpr_parenthesizedContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_parenthesizedContext { - var p = new(Expr_parenthesizedContext) - - InitEmptyExpressionContext(&p.ExpressionContext) - p.parser = parser - p.CopyAll(ctx.(*ExpressionContext)) - - return p -} - -func (s *Expr_parenthesizedContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_parenthesizedContext) LPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserLPAREN, 0) -} - -func (s *Expr_parenthesizedContext) Expression() IExpressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expr_parenthesizedContext) RPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserRPAREN, 0) -} - -func (s *Expr_parenthesizedContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Expr_parenthesizedContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpr_parenthesized(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Expression() (localctx IExpressionContext) { - return p.expression(0) -} - -func (p *ProcedureParser) expression(_p int) (localctx IExpressionContext) { - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() - - _parentState := p.GetState() - localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState) - var _prevctx IExpressionContext = localctx - var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. - _startState := 8 - p.EnterRecursionRule(localctx, 8, ProcedureParserRULE_expression, _p) - var _la int - - var _alt int - - p.EnterOuterAlt(localctx, 1) - p.SetState(160) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case ProcedureParserTEXT_LITERAL: - localctx = NewExpr_text_literalContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - - { - p.SetState(122) - p.Match(ProcedureParserTEXT_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(124) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 11, p.GetParserRuleContext()) == 1 { - { - p.SetState(123) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserBOOLEAN_LITERAL: - localctx = NewExpr_boolean_literalContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(126) - p.Match(ProcedureParserBOOLEAN_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(128) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 12, p.GetParserRuleContext()) == 1 { - { - p.SetState(127) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserINT_LITERAL: - localctx = NewExpr_int_literalContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(130) - p.Match(ProcedureParserINT_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(132) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 13, p.GetParserRuleContext()) == 1 { - { - p.SetState(131) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserNULL_LITERAL: - localctx = NewExpr_null_literalContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(134) - p.Match(ProcedureParserNULL_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(136) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 14, p.GetParserRuleContext()) == 1 { - { - p.SetState(135) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserBLOB_LITERAL: - localctx = NewExpr_blob_literalContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(138) - p.Match(ProcedureParserBLOB_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(140) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 15, p.GetParserRuleContext()) == 1 { - { - p.SetState(139) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserLBRACKET: - localctx = NewExpr_make_arrayContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(142) - p.Expression_make_array() - } - p.SetState(144) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 16, p.GetParserRuleContext()) == 1 { - { - p.SetState(143) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserIDENTIFIER: - localctx = NewExpr_callContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(146) - p.Call_expression() - } - p.SetState(148) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 17, p.GetParserRuleContext()) == 1 { - { - p.SetState(147) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserVARIABLE: - localctx = NewExpr_variableContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(150) - p.Match(ProcedureParserVARIABLE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(152) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 18, p.GetParserRuleContext()) == 1 { - { - p.SetState(151) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case ProcedureParserLPAREN: - localctx = NewExpr_parenthesizedContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(154) - p.Match(ProcedureParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(155) - p.expression(0) - } - { - p.SetState(156) - p.Match(ProcedureParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(158) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 19, p.GetParserRuleContext()) == 1 { - { - p.SetState(157) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(186) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - if p.GetParseListeners() != nil { - p.TriggerExitRuleEvent() - } - _prevctx = localctx - p.SetState(184) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 23, p.GetParserRuleContext()) { - case 1: - localctx = NewExpr_comparisonContext(p, NewExpressionContext(p, _parentctx, _parentState)) - localctx.(*Expr_comparisonContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, ProcedureParserRULE_expression) - p.SetState(162) - - if !(p.Precpred(p.GetParserRuleContext(), 3)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) - goto errorExit - } - { - p.SetState(163) - - var _lt = p.GetTokenStream().LT(1) - - localctx.(*Expr_comparisonContext).operator = _lt - - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&264241152) != 0) { - var _ri = p.GetErrorHandler().RecoverInline(p) - - localctx.(*Expr_comparisonContext).operator = _ri - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(164) - - var _x = p.expression(4) - - localctx.(*Expr_comparisonContext).right = _x - } - - case 2: - localctx = NewExpr_arithmeticContext(p, NewExpressionContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, ProcedureParserRULE_expression) - p.SetState(165) - - if !(p.Precpred(p.GetParserRuleContext(), 2)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) - goto errorExit - } - { - p.SetState(166) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&3670016) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(167) - p.expression(3) - } - - case 3: - localctx = NewExpr_arithmeticContext(p, NewExpressionContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, ProcedureParserRULE_expression) - p.SetState(168) - - if !(p.Precpred(p.GetParserRuleContext(), 1)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) - goto errorExit - } - { - p.SetState(169) - _la = p.GetTokenStream().LA(1) - - if !(_la == ProcedureParserPLUS || _la == ProcedureParserMINUS) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(170) - p.expression(2) - } - - case 4: - localctx = NewExpr_array_accessContext(p, NewExpressionContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, ProcedureParserRULE_expression) - p.SetState(171) - - if !(p.Precpred(p.GetParserRuleContext(), 6)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) - goto errorExit - } - { - p.SetState(172) - p.Match(ProcedureParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(173) - p.expression(0) - } - { - p.SetState(174) - p.Match(ProcedureParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(176) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 21, p.GetParserRuleContext()) == 1 { - { - p.SetState(175) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 5: - localctx = NewExpr_field_accessContext(p, NewExpressionContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, ProcedureParserRULE_expression) - p.SetState(178) - - if !(p.Precpred(p.GetParserRuleContext(), 5)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) - goto errorExit - } - { - p.SetState(179) - p.Match(ProcedureParserPERIOD) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(180) - p.Match(ProcedureParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(182) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 22, p.GetParserRuleContext()) == 1 { - { - p.SetState(181) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - - } - p.SetState(188) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.UnrollRecursionContexts(_parentctx) - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IType_castContext is an interface to support dynamic dispatch. -type IType_castContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - TYPE_CAST() antlr.TerminalNode - IDENTIFIER() antlr.TerminalNode - LBRACKET() antlr.TerminalNode - RBRACKET() antlr.TerminalNode - - // IsType_castContext differentiates from other interfaces. - IsType_castContext() -} - -type Type_castContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyType_castContext() *Type_castContext { - var p = new(Type_castContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_type_cast - return p -} - -func InitEmptyType_castContext(p *Type_castContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_type_cast -} - -func (*Type_castContext) IsType_castContext() {} - -func NewType_castContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_castContext { - var p = new(Type_castContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_type_cast - - return p -} - -func (s *Type_castContext) GetParser() antlr.Parser { return s.parser } - -func (s *Type_castContext) TYPE_CAST() antlr.TerminalNode { - return s.GetToken(ProcedureParserTYPE_CAST, 0) -} - -func (s *Type_castContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ProcedureParserIDENTIFIER, 0) -} - -func (s *Type_castContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACKET, 0) -} - -func (s *Type_castContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACKET, 0) -} - -func (s *Type_castContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Type_castContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Type_castContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitType_cast(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Type_cast() (localctx IType_castContext) { - localctx = NewType_castContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 10, ProcedureParserRULE_type_cast) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(189) - p.Match(ProcedureParserTYPE_CAST) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(190) - p.Match(ProcedureParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(193) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 25, p.GetParserRuleContext()) == 1 { - { - p.SetState(191) - p.Match(ProcedureParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(192) - p.Match(ProcedureParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } else if p.HasError() { // JIM - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExpression_listContext is an interface to support dynamic dispatch. -type IExpression_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllExpression() []IExpressionContext - Expression(i int) IExpressionContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsExpression_listContext differentiates from other interfaces. - IsExpression_listContext() -} - -type Expression_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExpression_listContext() *Expression_listContext { - var p = new(Expression_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression_list - return p -} - -func InitEmptyExpression_listContext(p *Expression_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression_list -} - -func (*Expression_listContext) IsExpression_listContext() {} - -func NewExpression_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Expression_listContext { - var p = new(Expression_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_expression_list - - return p -} - -func (s *Expression_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Expression_listContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *Expression_listContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Expression_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(ProcedureParserCOMMA) -} - -func (s *Expression_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(ProcedureParserCOMMA, i) -} - -func (s *Expression_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expression_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Expression_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpression_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Expression_list() (localctx IExpression_listContext) { - localctx = NewExpression_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 12, ProcedureParserRULE_expression_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(195) - p.expression(0) - } - p.SetState(200) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == ProcedureParserCOMMA { - { - p.SetState(196) - p.Match(ProcedureParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(197) - p.expression(0) - } - - p.SetState(202) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExpression_make_arrayContext is an interface to support dynamic dispatch. -type IExpression_make_arrayContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - LBRACKET() antlr.TerminalNode - RBRACKET() antlr.TerminalNode - Expression_list() IExpression_listContext - - // IsExpression_make_arrayContext differentiates from other interfaces. - IsExpression_make_arrayContext() -} - -type Expression_make_arrayContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExpression_make_arrayContext() *Expression_make_arrayContext { - var p = new(Expression_make_arrayContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression_make_array - return p -} - -func InitEmptyExpression_make_arrayContext(p *Expression_make_arrayContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_expression_make_array -} - -func (*Expression_make_arrayContext) IsExpression_make_arrayContext() {} - -func NewExpression_make_arrayContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Expression_make_arrayContext { - var p = new(Expression_make_arrayContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_expression_make_array - - return p -} - -func (s *Expression_make_arrayContext) GetParser() antlr.Parser { return s.parser } - -func (s *Expression_make_arrayContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACKET, 0) -} - -func (s *Expression_make_arrayContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACKET, 0) -} - -func (s *Expression_make_arrayContext) Expression_list() IExpression_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_listContext) -} - -func (s *Expression_make_arrayContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expression_make_arrayContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Expression_make_arrayContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitExpression_make_array(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Expression_make_array() (localctx IExpression_make_arrayContext) { - localctx = NewExpression_make_arrayContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 14, ProcedureParserRULE_expression_make_array) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(203) - p.Match(ProcedureParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(205) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&34909494190084) != 0 { - { - p.SetState(204) - p.Expression_list() - } - - } - { - p.SetState(207) - p.Match(ProcedureParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICall_expressionContext is an interface to support dynamic dispatch. -type ICall_expressionContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsCall_expressionContext differentiates from other interfaces. - IsCall_expressionContext() -} - -type Call_expressionContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCall_expressionContext() *Call_expressionContext { - var p = new(Call_expressionContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_call_expression - return p -} - -func InitEmptyCall_expressionContext(p *Call_expressionContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_call_expression -} - -func (*Call_expressionContext) IsCall_expressionContext() {} - -func NewCall_expressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Call_expressionContext { - var p = new(Call_expressionContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_call_expression - - return p -} - -func (s *Call_expressionContext) GetParser() antlr.Parser { return s.parser } - -func (s *Call_expressionContext) CopyAll(ctx *Call_expressionContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *Call_expressionContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Call_expressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type Normal_callContext struct { - Call_expressionContext -} - -func NewNormal_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Normal_callContext { - var p = new(Normal_callContext) - - InitEmptyCall_expressionContext(&p.Call_expressionContext) - p.parser = parser - p.CopyAll(ctx.(*Call_expressionContext)) - - return p -} - -func (s *Normal_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Normal_callContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ProcedureParserIDENTIFIER, 0) -} - -func (s *Normal_callContext) LPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserLPAREN, 0) -} - -func (s *Normal_callContext) RPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserRPAREN, 0) -} - -func (s *Normal_callContext) Expression_list() IExpression_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_listContext) -} - -func (s *Normal_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitNormal_call(s) - - default: - return t.VisitChildren(s) - } -} - -type Foreign_callContext struct { - Call_expressionContext - dbid IExpressionContext - procedure IExpressionContext -} - -func NewForeign_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Foreign_callContext { - var p = new(Foreign_callContext) - - InitEmptyCall_expressionContext(&p.Call_expressionContext) - p.parser = parser - p.CopyAll(ctx.(*Call_expressionContext)) - - return p -} - -func (s *Foreign_callContext) GetDbid() IExpressionContext { return s.dbid } - -func (s *Foreign_callContext) GetProcedure() IExpressionContext { return s.procedure } - -func (s *Foreign_callContext) SetDbid(v IExpressionContext) { s.dbid = v } - -func (s *Foreign_callContext) SetProcedure(v IExpressionContext) { s.procedure = v } - -func (s *Foreign_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Foreign_callContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(ProcedureParserIDENTIFIER, 0) -} - -func (s *Foreign_callContext) LBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACKET, 0) -} - -func (s *Foreign_callContext) COMMA() antlr.TerminalNode { - return s.GetToken(ProcedureParserCOMMA, 0) -} - -func (s *Foreign_callContext) RBRACKET() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACKET, 0) -} - -func (s *Foreign_callContext) LPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserLPAREN, 0) -} - -func (s *Foreign_callContext) RPAREN() antlr.TerminalNode { - return s.GetToken(ProcedureParserRPAREN, 0) -} - -func (s *Foreign_callContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *Foreign_callContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *Foreign_callContext) Expression_list() IExpression_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpression_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpression_listContext) -} - -func (s *Foreign_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitForeign_call(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Call_expression() (localctx ICall_expressionContext) { - localctx = NewCall_expressionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 16, ProcedureParserRULE_call_expression) - var _la int - - p.SetState(227) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 30, p.GetParserRuleContext()) { - case 1: - localctx = NewNormal_callContext(p, localctx) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(209) - p.Match(ProcedureParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(210) - p.Match(ProcedureParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(212) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&34909494190084) != 0 { - { - p.SetState(211) - p.Expression_list() - } - - } - { - p.SetState(214) - p.Match(ProcedureParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 2: - localctx = NewForeign_callContext(p, localctx) - p.EnterOuterAlt(localctx, 2) - { - p.SetState(215) - p.Match(ProcedureParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(216) - p.Match(ProcedureParserLBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(217) - - var _x = p.expression(0) - - localctx.(*Foreign_callContext).dbid = _x - } - { - p.SetState(218) - p.Match(ProcedureParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(219) - - var _x = p.expression(0) - - localctx.(*Foreign_callContext).procedure = _x - } - { - p.SetState(220) - p.Match(ProcedureParserRBRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(221) - p.Match(ProcedureParserLPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(223) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&34909494190084) != 0 { - { - p.SetState(222) - p.Expression_list() - } - - } - { - p.SetState(225) - p.Match(ProcedureParserRPAREN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IRangeContext is an interface to support dynamic dispatch. -type IRangeContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllExpression() []IExpressionContext - Expression(i int) IExpressionContext - COLON() antlr.TerminalNode - - // IsRangeContext differentiates from other interfaces. - IsRangeContext() -} - -type RangeContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyRangeContext() *RangeContext { - var p = new(RangeContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_range - return p -} - -func InitEmptyRangeContext(p *RangeContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_range -} - -func (*RangeContext) IsRangeContext() {} - -func NewRangeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RangeContext { - var p = new(RangeContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_range - - return p -} - -func (s *RangeContext) GetParser() antlr.Parser { return s.parser } - -func (s *RangeContext) AllExpression() []IExpressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExpressionContext); ok { - len++ - } - } - - tst := make([]IExpressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExpressionContext); ok { - tst[i] = t.(IExpressionContext) - i++ - } - } - - return tst -} - -func (s *RangeContext) Expression(i int) IExpressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *RangeContext) COLON() antlr.TerminalNode { - return s.GetToken(ProcedureParserCOLON, 0) -} - -func (s *RangeContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *RangeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *RangeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitRange(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) Range_() (localctx IRangeContext) { - localctx = NewRangeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 18, ProcedureParserRULE_range) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(229) - p.expression(0) - } - { - p.SetState(230) - p.Match(ProcedureParserCOLON) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(231) - p.expression(0) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IIf_then_blockContext is an interface to support dynamic dispatch. -type IIf_then_blockContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Expression() IExpressionContext - LBRACE() antlr.TerminalNode - RBRACE() antlr.TerminalNode - AllStatement() []IStatementContext - Statement(i int) IStatementContext - - // IsIf_then_blockContext differentiates from other interfaces. - IsIf_then_blockContext() -} - -type If_then_blockContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyIf_then_blockContext() *If_then_blockContext { - var p = new(If_then_blockContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_if_then_block - return p -} - -func InitEmptyIf_then_blockContext(p *If_then_blockContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = ProcedureParserRULE_if_then_block -} - -func (*If_then_blockContext) IsIf_then_blockContext() {} - -func NewIf_then_blockContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *If_then_blockContext { - var p = new(If_then_blockContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = ProcedureParserRULE_if_then_block - - return p -} - -func (s *If_then_blockContext) GetParser() antlr.Parser { return s.parser } - -func (s *If_then_blockContext) Expression() IExpressionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpressionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpressionContext) -} - -func (s *If_then_blockContext) LBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserLBRACE, 0) -} - -func (s *If_then_blockContext) RBRACE() antlr.TerminalNode { - return s.GetToken(ProcedureParserRBRACE, 0) -} - -func (s *If_then_blockContext) AllStatement() []IStatementContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IStatementContext); ok { - len++ - } - } - - tst := make([]IStatementContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IStatementContext); ok { - tst[i] = t.(IStatementContext) - i++ - } - } - - return tst -} - -func (s *If_then_blockContext) Statement(i int) IStatementContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IStatementContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IStatementContext) -} - -func (s *If_then_blockContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *If_then_blockContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *If_then_blockContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case ProcedureParserVisitor: - return t.VisitIf_then_block(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *ProcedureParser) If_then_block() (localctx IIf_then_blockContext) { - localctx = NewIf_then_blockContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 20, ProcedureParserRULE_if_then_block) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(233) - p.expression(0) - } - { - p.SetState(234) - p.Match(ProcedureParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(238) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&26494311137280) != 0 { - { - p.SetState(235) - p.Statement() - } - - p.SetState(240) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(241) - p.Match(ProcedureParserRBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -func (p *ProcedureParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { - switch ruleIndex { - case 4: - var t *ExpressionContext = nil - if localctx != nil { - t = localctx.(*ExpressionContext) - } - return p.Expression_Sempred(t, predIndex) - - default: - panic("No predicate with index: " + fmt.Sprint(ruleIndex)) - } -} - -func (p *ProcedureParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool { - switch predIndex { - case 0: - return p.Precpred(p.GetParserRuleContext(), 3) - - case 1: - return p.Precpred(p.GetParserRuleContext(), 2) - - case 2: - return p.Precpred(p.GetParserRuleContext(), 1) - - case 3: - return p.Precpred(p.GetParserRuleContext(), 6) - - case 4: - return p.Precpred(p.GetParserRuleContext(), 5) - - default: - panic("No predicate with index: " + fmt.Sprint(predIndex)) - } -} diff --git a/parse/procedures/gen/procedureparser_base_visitor.go b/parse/procedures/gen/procedureparser_base_visitor.go deleted file mode 100644 index 4c92f597d..000000000 --- a/parse/procedures/gen/procedureparser_base_visitor.go +++ /dev/null @@ -1,140 +0,0 @@ -// Code generated from ProcedureParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // ProcedureParser -import "github.com/antlr4-go/antlr/v4" - -type BaseProcedureParserVisitor struct { - *antlr.BaseParseTreeVisitor -} - -func (v *BaseProcedureParserVisitor) VisitProgram(ctx *ProgramContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_variable_declaration(ctx *Stmt_variable_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_procedure_call(ctx *Stmt_procedure_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_variable_assignment(ctx *Stmt_variable_assignmentContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_variable_assignment_with_declaration(ctx *Stmt_variable_assignment_with_declarationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_for_loop(ctx *Stmt_for_loopContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_if(ctx *Stmt_ifContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_sql(ctx *Stmt_sqlContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_break(ctx *Stmt_breakContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_return(ctx *Stmt_returnContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitStmt_return_next(ctx *Stmt_return_nextContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitVariable_or_underscore(ctx *Variable_or_underscoreContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitType(ctx *TypeContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_array_access(ctx *Expr_array_accessContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_arithmetic(ctx *Expr_arithmeticContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_variable(ctx *Expr_variableContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_null_literal(ctx *Expr_null_literalContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_blob_literal(ctx *Expr_blob_literalContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_comparison(ctx *Expr_comparisonContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_boolean_literal(ctx *Expr_boolean_literalContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_call(ctx *Expr_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_make_array(ctx *Expr_make_arrayContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_field_access(ctx *Expr_field_accessContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_int_literal(ctx *Expr_int_literalContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_text_literal(ctx *Expr_text_literalContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpr_parenthesized(ctx *Expr_parenthesizedContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitType_cast(ctx *Type_castContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpression_list(ctx *Expression_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitExpression_make_array(ctx *Expression_make_arrayContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitNormal_call(ctx *Normal_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitForeign_call(ctx *Foreign_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitRange(ctx *RangeContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseProcedureParserVisitor) VisitIf_then_block(ctx *If_then_blockContext) interface{} { - return v.VisitChildren(ctx) -} diff --git a/parse/procedures/gen/procedureparser_visitor.go b/parse/procedures/gen/procedureparser_visitor.go deleted file mode 100644 index 502bd2c7d..000000000 --- a/parse/procedures/gen/procedureparser_visitor.go +++ /dev/null @@ -1,108 +0,0 @@ -// Code generated from ProcedureParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package gen // ProcedureParser -import "github.com/antlr4-go/antlr/v4" - -// A complete Visitor for a parse tree produced by ProcedureParser. -type ProcedureParserVisitor interface { - antlr.ParseTreeVisitor - - // Visit a parse tree produced by ProcedureParser#program. - VisitProgram(ctx *ProgramContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_variable_declaration. - VisitStmt_variable_declaration(ctx *Stmt_variable_declarationContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_procedure_call. - VisitStmt_procedure_call(ctx *Stmt_procedure_callContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_variable_assignment. - VisitStmt_variable_assignment(ctx *Stmt_variable_assignmentContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_variable_assignment_with_declaration. - VisitStmt_variable_assignment_with_declaration(ctx *Stmt_variable_assignment_with_declarationContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_for_loop. - VisitStmt_for_loop(ctx *Stmt_for_loopContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_if. - VisitStmt_if(ctx *Stmt_ifContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_sql. - VisitStmt_sql(ctx *Stmt_sqlContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_break. - VisitStmt_break(ctx *Stmt_breakContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_return. - VisitStmt_return(ctx *Stmt_returnContext) interface{} - - // Visit a parse tree produced by ProcedureParser#stmt_return_next. - VisitStmt_return_next(ctx *Stmt_return_nextContext) interface{} - - // Visit a parse tree produced by ProcedureParser#variable_or_underscore. - VisitVariable_or_underscore(ctx *Variable_or_underscoreContext) interface{} - - // Visit a parse tree produced by ProcedureParser#type. - VisitType(ctx *TypeContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_array_access. - VisitExpr_array_access(ctx *Expr_array_accessContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_arithmetic. - VisitExpr_arithmetic(ctx *Expr_arithmeticContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_variable. - VisitExpr_variable(ctx *Expr_variableContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_null_literal. - VisitExpr_null_literal(ctx *Expr_null_literalContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_blob_literal. - VisitExpr_blob_literal(ctx *Expr_blob_literalContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_comparison. - VisitExpr_comparison(ctx *Expr_comparisonContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_boolean_literal. - VisitExpr_boolean_literal(ctx *Expr_boolean_literalContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_call. - VisitExpr_call(ctx *Expr_callContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_make_array. - VisitExpr_make_array(ctx *Expr_make_arrayContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_field_access. - VisitExpr_field_access(ctx *Expr_field_accessContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_int_literal. - VisitExpr_int_literal(ctx *Expr_int_literalContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_text_literal. - VisitExpr_text_literal(ctx *Expr_text_literalContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expr_parenthesized. - VisitExpr_parenthesized(ctx *Expr_parenthesizedContext) interface{} - - // Visit a parse tree produced by ProcedureParser#type_cast. - VisitType_cast(ctx *Type_castContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expression_list. - VisitExpression_list(ctx *Expression_listContext) interface{} - - // Visit a parse tree produced by ProcedureParser#expression_make_array. - VisitExpression_make_array(ctx *Expression_make_arrayContext) interface{} - - // Visit a parse tree produced by ProcedureParser#normal_call. - VisitNormal_call(ctx *Normal_callContext) interface{} - - // Visit a parse tree produced by ProcedureParser#foreign_call. - VisitForeign_call(ctx *Foreign_callContext) interface{} - - // Visit a parse tree produced by ProcedureParser#range. - VisitRange(ctx *RangeContext) interface{} - - // Visit a parse tree produced by ProcedureParser#if_then_block. - VisitIf_then_block(ctx *If_then_blockContext) interface{} -} diff --git a/parse/procedures/grammar/ProcedureLexer.g4 b/parse/procedures/grammar/ProcedureLexer.g4 deleted file mode 100644 index 3906cf021..000000000 --- a/parse/procedures/grammar/ProcedureLexer.g4 +++ /dev/null @@ -1,90 +0,0 @@ -lexer grammar ProcedureLexer; - -options { caseInsensitive = true; } - -// symbols -SEMICOLON: ';'; -LPAREN: '('; -RPAREN: ')'; -LBRACE: '{'; -RBRACE: '}'; -COMMA: ','; -TYPE_CAST: '::'; -COLON: ':'; -DOLLAR: '$'; -AT: '@'; -ASSIGN: ':='; -PERIOD: '.'; -LBRACKET : '['; -RBRACKET : ']'; -SINGLE_QUOTE: '\''; -UNDERSCORE: '_'; - -// arithmetic operators -PLUS: '+'; -MINUS: '-'; -MUL: '*'; -DIV: '/'; -MOD: '%'; - -// comparison operators -LT: '<'; -LT_EQ: '<='; -GT: '>'; -GT_EQ: '>='; -NEQ: '!='; -EQ: '=='; - -// we only need sql statement as a whole, sql-parser will parse it -ANY_SQL: (SELECT_ | INSERT_ | UPDATE_ | DELETE_ | WITH_) WSNL ~[;{]+; - -// Keywords -FOR: 'for'; -IN: 'in'; -IF: 'if'; -ELSEIF: 'elseif'; -ELSE: 'else'; -TO: 'to'; -RETURN: 'return'; -BREAK: 'break'; -NEXT: 'next'; - -// literals - -BOOLEAN_LITERAL: - 'true' | 'false' -; - -INT_LITERAL: - [0-9]+ -; - -BLOB_LITERAL: - '0x' [0-9a-f]+ -; - -TEXT_LITERAL: - SINGLE_QUOTE (~['\r\n\\] | ('\\' .))* SINGLE_QUOTE -; - -NULL_LITERAL: 'null'; - -// vars -IDENTIFIER: - [a-z] [a-z_0-9]* -; - -VARIABLE: (DOLLAR|AT) IDENTIFIER; - -WS: WSNL -> channel(HIDDEN); -TERMINATOR: [\r\n]+ -> channel(HIDDEN); -BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); -LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); - -// fragments -fragment WSNL: [ \t\r\n]+; // whitespace with new line -fragment SELECT_: 'select'; -fragment INSERT_: 'insert'; -fragment UPDATE_: 'update'; -fragment DELETE_: 'delete'; -fragment WITH_: 'with'; \ No newline at end of file diff --git a/parse/procedures/grammar/ProcedureParser.g4 b/parse/procedures/grammar/ProcedureParser.g4 deleted file mode 100644 index 6a4557929..000000000 --- a/parse/procedures/grammar/ProcedureParser.g4 +++ /dev/null @@ -1,79 +0,0 @@ -parser grammar ProcedureParser; - -options { - tokenVocab=ProcedureLexer; -} - -// top-level rule -program: - statement* EOF -; - -statement: - VARIABLE type SEMICOLON # stmt_variable_declaration - // stmt_procedure_call must go above stmt_variable_assignment - | (variable_or_underscore (COMMA variable_or_underscore)* ASSIGN)? call_expression SEMICOLON # stmt_procedure_call - | VARIABLE ASSIGN expression SEMICOLON # stmt_variable_assignment - | VARIABLE type ASSIGN expression SEMICOLON # stmt_variable_assignment_with_declaration - | FOR VARIABLE IN (range|call_expression|VARIABLE|ANY_SQL) LBRACE statement* RBRACE # stmt_for_loop - | IF if_then_block (ELSEIF if_then_block)* (ELSE LBRACE statement* RBRACE)? # stmt_if - | ANY_SQL SEMICOLON # stmt_sql - | BREAK SEMICOLON # stmt_break - | RETURN (expression_list|ANY_SQL) SEMICOLON # stmt_return - | RETURN NEXT expression_list SEMICOLON # stmt_return_next -; - -variable_or_underscore: - (VARIABLE|UNDERSCORE) -; - -type: - IDENTIFIER (LBRACKET RBRACKET)? // Handles arrays of any type, including nested arrays -; - -// expressions -expression: - TEXT_LITERAL type_cast? # expr_text_literal - | BOOLEAN_LITERAL type_cast? # expr_boolean_literal - | INT_LITERAL type_cast? # expr_int_literal - | NULL_LITERAL type_cast? # expr_null_literal - | BLOB_LITERAL type_cast? # expr_blob_literal - | expression_make_array type_cast? # expr_make_array - | call_expression type_cast? # expr_call - | VARIABLE type_cast? # expr_variable - | expression LBRACKET expression RBRACKET type_cast? # expr_array_access - | expression PERIOD IDENTIFIER type_cast? # expr_field_access - | LPAREN expression RPAREN type_cast? # expr_parenthesized - // the below do not have type casts, but can be wrapped in parens - // which can be type casted - | left=expression operator=(LT|LT_EQ|GT|GT_EQ|NEQ|EQ) right=expression # expr_comparison - // logical operators, separated for precedence - | expression (MUL|DIV|MOD) expression # expr_arithmetic - | expression (PLUS|MINUS) expression # expr_arithmetic -; - -type_cast: - TYPE_CAST IDENTIFIER (LBRACKET RBRACKET)? -; - -expression_list: - expression (COMMA expression)* -; - -expression_make_array: - LBRACKET (expression_list)? RBRACKET -; - -call_expression: - IDENTIFIER LPAREN (expression_list)? RPAREN #normal_call - | IDENTIFIER LBRACKET dbid=expression COMMA procedure=expression RBRACKET LPAREN (expression_list)? RPAREN #foreign_call -; - -// range used for for loops -range: - expression COLON expression -; - -if_then_block: - expression LBRACE statement* RBRACE -; \ No newline at end of file diff --git a/parse/procedures/grammar/generate.sh b/parse/procedures/grammar/generate.sh deleted file mode 100755 index eac0328a5..000000000 --- a/parse/procedures/grammar/generate.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -set -e - -cd "$(dirname "$0")" - -target=${1:-Go} -output_dir=${2:-../gen} - -rm -rf .antlr -rm -rf "${output_dir}" - -antlr_bin=antlr-4.13.1-complete.jar - -if [ ! -f $antlr_bin ]; then - echo "Downloading antlr4 jar file..." - curl -O https://www.antlr.org/download/${antlr_bin} -fi - -alias antlr4='java -Xmx500M -cp "./${antlr_bin}:$CLASSPATH" org.antlr.v4.Tool' -antlr4 -Dlanguage="${target}" -visitor -no-listener -package gen -o "${output_dir}" *.g4 \ No newline at end of file diff --git a/parse/procedures/parser/parser.go b/parse/procedures/parser/parser.go deleted file mode 100644 index 2d743bd1a..000000000 --- a/parse/procedures/parser/parser.go +++ /dev/null @@ -1,88 +0,0 @@ -package parser - -import ( - "fmt" - "runtime" - - "github.com/antlr4-go/antlr/v4" - "github.com/kwilteam/kwil-db/parse/procedures/gen" - "github.com/kwilteam/kwil-db/parse/types" -) - -// Parse should only be used when the caller does not care about getting -// in-depth error information. -func Parse(stmt string) ([]Statement, error) { - errLis := types.NewErrorListener() - res, err := ParseWithErrorListener(stmt, errLis) - if err != nil { - return nil, err - } - if errLis.Err() != nil { - return nil, errLis.Err() - } - - return res, nil -} - -// ParseOpts are options for parsing a procedural language statement. -type ParseOpts struct { - // ErrorListener is the error listener to use when parsing the statement. - // If not provided, it will default to a new error listener, and all - // parsing errors will be returned as an error. - ErrorListener types.AntlrErrorListener -} - -// ParseWithErrorListener parses a procedural language statement and returns the AST. -func ParseWithErrorListener(stmt string, errorListener types.AntlrErrorListener) (clauses []Statement, err error) { - visitor := &proceduralLangVisitor{ - errs: errorListener, - } - - stream := antlr.NewInputStream(stmt) - lexer := gen.NewProcedureLexer(stream) - tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) - p := gen.NewProcedureParser(tokenStream) - - // remove default error listeners - lexer.RemoveErrorListeners() - lexer.AddErrorListener(errorListener) - p.RemoveErrorListeners() - p.AddErrorListener(errorListener) - - p.BuildParseTrees = true - - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("panic: %v", e) - } - - // if there is a panic, it is likely due to a syntax error - // check for parse errors and return them first - if errorListener.Err() != nil { - // if there is an error listener error, we should swallow the panic - // If the issue persists until after the user has fixed the parse errors, - // the panic will be returned in the else block. - err = nil - } else { - // if there are no parse errors, then there is a bug. - // we should return the panic with a stack trace. - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - - err = fmt.Errorf("%w\n\n%s", err, buf[:stackSize]) - } - } - }() - - result := visitor.Visit(p.Program()) - - res, ok := result.([]Statement) - if !ok { - return nil, fmt.Errorf("unexpected result type: %T", result) - } - - return res, nil -} diff --git a/parse/procedures/parser/parser_test.go b/parse/procedures/parser/parser_test.go deleted file mode 100644 index 0586f5ac8..000000000 --- a/parse/procedures/parser/parser_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package parser_test - -import ( - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/kwilteam/kwil-db/core/types" - parser "github.com/kwilteam/kwil-db/parse/procedures/parser" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -func Test_Parser(t *testing.T) { - type testcase struct { - name string - stmt string - want []parser.Statement - } - - tests := []testcase{ - { - name: "basic declaration", - stmt: "$a int;", - want: []parser.Statement{ - &parser.StatementVariableDeclaration{ - Name: "$a", - Type: &types.DataType{ - Name: "int", - }, - }, - }, - }, - { - name: "declaration with assignment", - stmt: "$a int := 1;", - want: []parser.Statement{ - &parser.StatementVariableAssignmentWithDeclaration{ - Name: "$a", - Type: &types.DataType{ - Name: "int", - }, - Value: &parser.ExpressionIntLiteral{ - Value: 1, - }, - }, - }, - }, - { - name: "declare, then assign", - stmt: "$a int; $a := 1;", - want: []parser.Statement{ - &parser.StatementVariableDeclaration{ - Name: "$a", - Type: &types.DataType{ - Name: "int", - }, - }, - &parser.StatementVariableAssignment{ - Name: "$a", - Value: &parser.ExpressionIntLiteral{ - Value: 1, - }, - }, - }, - }, - { - name: "call procedure", - stmt: "$res int := my_procedure();", - want: []parser.Statement{ - &parser.StatementVariableAssignmentWithDeclaration{ - Name: "$res", - Type: types.IntType, - Value: &parser.ExpressionCall{ - Name: "my_procedure", - }, - }, - }, - }, - { - name: "foreign call", - stmt: "other_procedure[$dbid, 'procedure']($arg);", - want: []parser.Statement{ - &parser.StatementProcedureCall{ - Call: &parser.ExpressionForeignCall{ - Name: "other_procedure", - ContextArgs: []parser.Expression{ - &parser.ExpressionVariable{ - Name: "$dbid", - }, - &parser.ExpressionTextLiteral{ - Value: "procedure", - }, - }, - Arguments: []parser.Expression{ - &parser.ExpressionVariable{ - Name: "$arg", - }, - }, - }, - }, - }, - }, - } - - for _, tt := range tests { - res, err := parser.Parse(tt.stmt) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if len(res) != len(tt.want) { - t.Errorf("unexpected result length: got %d, want %d", len(res), len(tt.want)) - return - } - - for i, r := range res { - if !deepCompare(r, tt.want[i]) { - t.Errorf("unexpected result: got %v, want %v", r, tt.want[i]) - } - } - } -} - -// deepCompare deep compares the values of two nodes. -// It ignores the parseTypes.Node field. -func deepCompare(node1, node2 any) bool { - // we return true for the parseTypes.Node field, - // we also need to ignore the unexported "schema" fields - return cmp.Equal(node1, node2, cmp.Comparer(func(x, y parseTypes.Node) bool { - return true - }), cmpopts.IgnoreUnexported( - parser.StatementVariableDeclaration{}, - parser.StatementVariableAssignment{}, - parser.StatementVariableAssignmentWithDeclaration{}, - parser.StatementProcedureCall{}, - parser.StatementForLoop{}, - parser.StatementIf{}, - parser.StatementSQL{}, - parser.StatementReturn{}, - parser.StatementReturnNext{}, - parser.StatementBreak{}, - - parser.ExpressionTextLiteral{}, - parser.ExpressionBooleanLiteral{}, - parser.ExpressionIntLiteral{}, - parser.ExpressionNullLiteral{}, - parser.ExpressionBlobLiteral{}, - parser.ExpressionMakeArray{}, - parser.ExpressionCall{}, - parser.ExpressionForeignCall{}, - parser.ExpressionVariable{}, - parser.ExpressionArrayAccess{}, - parser.ExpressionFieldAccess{}, - parser.ExpressionParenthesized{}, - parser.ExpressionComparison{}, - parser.ExpressionArithmetic{}, - - parser.LoopTargetRange{}, - parser.LoopTargetCall{}, - parser.LoopTargetSQL{}, - parser.LoopTargetVariable{}, - - parser.IfThen{}, - )) -} diff --git a/parse/procedures/parser/tree.go b/parse/procedures/parser/tree.go deleted file mode 100644 index e962682a7..000000000 --- a/parse/procedures/parser/tree.go +++ /dev/null @@ -1,564 +0,0 @@ -package parser - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -type Accepter interface { - Accept(Visitor) interface{} - GetNode() *parseTypes.Node -} - -type Statement interface { - Accepter - statement() -} - -type baseStatement struct{} - -func (baseStatement) statement() {} -func (e *StatementVariableDeclaration) Accept(v Visitor) interface{} { - return v.VisitStatementVariableDeclaration(e) -} - -type StatementVariableDeclaration struct { - baseStatement - parseTypes.Node - // Name is the name of the variable. - // It is case-insensitive. - // It does include the $. - Name string - - // Type is the type of the variable. - // If it is a custom type, it is the name of the custom type. - // If it is a built-in type, it is the name of the type. - Type *types.DataType -} - -func (e *StatementVariableAssignment) Accept(v Visitor) interface{} { - return v.VisitStatementVariableAssignment(e) -} - -type StatementVariableAssignment struct { - baseStatement - parseTypes.Node - // Name is the name of the variable. - // It is case-insensitive. - // It does include the $. - Name string - // Value is the value to assign to the variable. - Value Expression -} - -func (e *StatementVariableAssignmentWithDeclaration) Accept(v Visitor) interface{} { - return v.VisitStatementVariableAssignmentWithDeclaration(e) -} - -type StatementVariableAssignmentWithDeclaration struct { - baseStatement - parseTypes.Node - // Name is the name of the variable. - // It is case-insensitive. - // It does include the $. - Name string - - // Type is the type of the variable. - // If it is a custom type, it is the name of the custom type. - // If it is a built-in type, it is the name of the type. - Type *types.DataType - - // Value is the value to assign to the variable. - Value Expression -} - -func (e *StatementProcedureCall) Accept(v Visitor) interface{} { - return v.VisitStatementProcedureCall(e) -} - -type StatementProcedureCall struct { - baseStatement - parseTypes.Node - // Variables holds the receivers that the procedure assigns to. - // It can be nil (e.g. $return1, _, $return3 := proc()) - Variables []*string - Call ICallExpression -} - -func (e *StatementForLoop) Accept(v Visitor) interface{} { - return v.VisitStatementForLoop(e) -} - -type StatementForLoop struct { - baseStatement - parseTypes.Node - // Variable is the variable to assign the value to. - Variable string - // Target is the target of the loop. - Target LoopTarget - - // Body is the body of the loop. - Body []Statement -} - -// LoopTarget is the target of the loop. -type LoopTarget interface { - Accepter - loopTarget() -} - -type baseLoopTarget struct{} - -func (baseLoopTarget) loopTarget() {} - -func (e *LoopTargetRange) Accept(v Visitor) interface{} { - return v.VisitLoopTargetRange(e) -} - -type LoopTargetRange struct { - baseLoopTarget - parseTypes.Node - // Start is the start of the range. - Start Expression - // End is the end of the range. - End Expression -} - -func (e *LoopTargetCall) Accept(v Visitor) interface{} { - return v.VisitLoopTargetCall(e) -} - -type LoopTargetCall struct { - baseLoopTarget - parseTypes.Node - // Call is the procedure call to loop through. - // It must return either an array or a table. - Call ICallExpression -} - -func (e *LoopTargetVariable) Accept(v Visitor) interface{} { - return v.VisitLoopTargetVariable(e) -} - -type LoopTargetSQL struct { - baseLoopTarget - parseTypes.Node - // Statement is the Statement statement to execute. - Statement tree.AstNode - // StatementLocation tracks the starting location of the statement. - StatementLocation *parseTypes.Node -} - -func (e *LoopTargetSQL) Accept(v Visitor) interface{} { - return v.VisitLoopTargetSQL(e) -} - -type LoopTargetVariable struct { - baseLoopTarget - parseTypes.Node - // Variable is the variable to loop through. - // It must be an array. - Variable *ExpressionVariable -} - -func (e *StatementIf) Accept(v Visitor) interface{} { - return v.VisitStatementIf(e) -} - -type StatementIf struct { - baseStatement - parseTypes.Node - // IfThens are the if statements. - // They are evaluated in order, as - // IF ... THEN ... ELSEIF ... THEN ... - IfThens []*IfThen - - // Else is the else statement. - // It is evaluated if none of the ifs are true. - // It is optional. - Else []Statement -} - -type IfThen struct { - parseTypes.Node - If Expression - Then []Statement -} - -func (e *StatementSQL) Accept(v Visitor) interface{} { - return v.VisitStatementSQL(e) -} - -type StatementSQL struct { - baseStatement - parseTypes.Node - // Statement is the SQL statement to execute. - Statement tree.AstNode - // StatementLocation tracks the starting location of the statement. - StatementLocation *parseTypes.Node -} - -func (e *StatementReturn) Accept(v Visitor) interface{} { - return v.VisitStatementReturn(e) -} - -type StatementReturn struct { - baseStatement - parseTypes.Node - // Values is the value to return. - // It can be nil. - Values []Expression - - // SQL is the SQL statement to execute. - // If this is not nil, Value must be nil. - SQL tree.AstNode - // SQLLocation tracks the starting location of the statement. - SQLLocation *parseTypes.Node -} - -func (e *StatementReturnNext) Accept(v Visitor) interface{} { - return v.VisitStatementReturnNext(e) -} - -type StatementReturnNext struct { - baseStatement - parseTypes.Node - // Returns are the values to return. - // There must be the same number of values as the procedure returns. - Returns []Expression -} - -func (e *StatementBreak) Accept(v Visitor) interface{} { - return v.VisitStatementBreak(e) -} - -// StatementBreak is a statement that breaks out of a loop. -type StatementBreak struct { - baseStatement - parseTypes.Node -} - -type Expression interface { - Accepter - expression() -} - -type baseExpression struct{} - -func (baseExpression) expression() {} - -func (e *ExpressionTextLiteral) Accept(v Visitor) interface{} { - return v.VisitExpressionTextLiteral(e) -} - -type ExpressionTextLiteral struct { - baseExpression - parseTypes.Node - Value string - TypeCast *types.DataType -} - -func (e *ExpressionBooleanLiteral) Accept(v Visitor) interface{} { - return v.VisitExpressionBooleanLiteral(e) -} - -type ExpressionBooleanLiteral struct { - baseExpression - parseTypes.Node - Value bool - TypeCast *types.DataType -} - -func (e *ExpressionIntLiteral) Accept(v Visitor) interface{} { - return v.VisitExpressionIntLiteral(e) -} - -type ExpressionIntLiteral struct { - baseExpression - parseTypes.Node - Value int64 - TypeCast *types.DataType -} - -func (e *ExpressionNullLiteral) Accept(v Visitor) interface{} { - return v.VisitExpressionNullLiteral(e) -} - -type ExpressionNullLiteral struct { - baseExpression - parseTypes.Node - TypeCast *types.DataType -} - -func (e *ExpressionBlobLiteral) Accept(v Visitor) interface{} { - return v.VisitExpressionBlobLiteral(e) -} - -type ExpressionBlobLiteral struct { - baseExpression - parseTypes.Node - Value []byte - TypeCast *types.DataType -} - -func (e *ExpressionMakeArray) Accept(v Visitor) interface{} { - return v.VisitExpressionMakeArray(e) -} - -type ExpressionMakeArray struct { - baseExpression - parseTypes.Node - Values []Expression - TypeCast *types.DataType -} - -// ICallExpression is a procedure call. -// It is implemented by ExpressionCall and ExpressionForeignCall. -type ICallExpression interface { - Accepter - isCall() -} - -func (e *ExpressionCall) Accept(v Visitor) interface{} { - return v.VisitExpressionCall(e) -} - -func (e *ExpressionCall) isCall() {} - -type ExpressionCall struct { - baseExpression - parseTypes.Node - // Name is the name of the procedure. - // It should always be lower case. - Name string - // Arguments are the arguments to the procedure. - Arguments []Expression // can be nil - TypeCast *types.DataType -} - -func (e *ExpressionForeignCall) Accept(v Visitor) interface{} { - return v.VisitExpressionForeignCall(e) -} - -func (e *ExpressionForeignCall) isCall() {} - -type ExpressionForeignCall struct { - baseExpression - parseTypes.Node - // Name is the name of the procedure. - // It should always be lower case. - Name string - // Context args are extra arguments provided to ForeignCalls. - // There should be exactly two: 1. the dbid, 2. the procedure - ContextArgs []Expression - // Arguments are the arguments to the procedure. - Arguments []Expression // can be nil - TypeCast *types.DataType -} - -func (e *ExpressionVariable) Accept(v Visitor) interface{} { - return v.VisitExpressionVariable(e) -} - -type ExpressionVariable struct { - baseExpression - parseTypes.Node - // Name is the name of the variable. - // It is case-insensitive. - // It does include the $. - // It should include all fields, separated by dots. - Name string - TypeCast *types.DataType -} - -type VariablePrefix uint8 - -const ( - VariablePrefixDollar VariablePrefix = iota - VariablePrefixAt -) - -func (e *ExpressionArrayAccess) Accept(v Visitor) interface{} { - return v.VisitExpressionArrayAccess(e) -} - -type ExpressionArrayAccess struct { - baseExpression - parseTypes.Node - // Target is the array to access the index from. - Target Expression - // Index is the index to access. - Index Expression - TypeCast *types.DataType -} - -func (e *ExpressionFieldAccess) Accept(v Visitor) interface{} { - return v.VisitExpressionFieldAccess(e) -} - -type ExpressionFieldAccess struct { - baseExpression - parseTypes.Node - // Target is the object to access the field from. - Target Expression - // Field is the field to access. - Field string - TypeCast *types.DataType -} - -func (e *ExpressionParenthesized) Accept(v Visitor) interface{} { - return v.VisitExpressionParenthesized(e) -} - -type ExpressionParenthesized struct { - baseExpression - parseTypes.Node - // Expression is the expression inside the parentheses. - Expression Expression - TypeCast *types.DataType -} - -func (e *ExpressionComparison) Accept(v Visitor) interface{} { - return v.VisitExpressionComparison(e) -} - -type ExpressionComparison struct { - baseExpression - parseTypes.Node - Left Expression - Operator ComparisonOperator - Right Expression -} - -func (e *ExpressionArithmetic) Accept(v Visitor) interface{} { - return v.VisitExpressionArithmetic(e) -} - -type ExpressionArithmetic struct { - baseExpression - parseTypes.Node - Left Expression - Operator ArithmeticOperator - Right Expression -} - -type ArithmeticOperator string - -const ( - ArithmeticOperatorAdd ArithmeticOperator = "+" - ArithmeticOperatorSub ArithmeticOperator = "-" - ArithmeticOperatorMul ArithmeticOperator = "*" - ArithmeticOperatorDiv ArithmeticOperator = "/" - ArithmeticOperatorMod ArithmeticOperator = "%" -) - -func (a *ArithmeticOperator) Validate() error { - switch *a { - case ArithmeticOperatorAdd, ArithmeticOperatorSub, ArithmeticOperatorMul, ArithmeticOperatorDiv, ArithmeticOperatorMod: - return nil - default: - return fmt.Errorf("invalid arithmetic operator: %s", *a) - } -} - -type ComparisonOperator string - -const ( - ComparisonOperatorEqual ComparisonOperator = "=" - ComparisonOperatorNotEqual ComparisonOperator = "!=" - ComparisonOperatorGreaterThan ComparisonOperator = ">" - ComparisonOperatorLessThan ComparisonOperator = "<" - ComparisonOperatorGreaterThanOrEqual ComparisonOperator = ">=" - ComparisonOperatorLessThanOrEqual ComparisonOperator = "<=" -) - -func (c *ComparisonOperator) Validate() error { - switch *c { - case ComparisonOperatorEqual, ComparisonOperatorNotEqual, ComparisonOperatorGreaterThan, ComparisonOperatorLessThan, ComparisonOperatorGreaterThanOrEqual, ComparisonOperatorLessThanOrEqual: - return nil - default: - return fmt.Errorf("invalid comparison operator: %s", *c) - } -} - -type Visitor interface { - VisitStatementVariableDeclaration(*StatementVariableDeclaration) interface{} - VisitStatementVariableAssignment(*StatementVariableAssignment) interface{} - VisitStatementVariableAssignmentWithDeclaration(*StatementVariableAssignmentWithDeclaration) interface{} - VisitStatementProcedureCall(*StatementProcedureCall) interface{} - VisitStatementForLoop(*StatementForLoop) interface{} - VisitStatementIf(*StatementIf) interface{} - VisitStatementSQL(*StatementSQL) interface{} - VisitStatementReturn(*StatementReturn) interface{} - VisitStatementReturnNext(*StatementReturnNext) interface{} - VisitStatementBreak(*StatementBreak) interface{} - VisitExpressionTextLiteral(*ExpressionTextLiteral) interface{} - VisitExpressionBooleanLiteral(*ExpressionBooleanLiteral) interface{} - VisitExpressionIntLiteral(*ExpressionIntLiteral) interface{} - VisitExpressionNullLiteral(*ExpressionNullLiteral) interface{} - VisitExpressionBlobLiteral(*ExpressionBlobLiteral) interface{} - VisitExpressionMakeArray(*ExpressionMakeArray) interface{} - VisitExpressionCall(*ExpressionCall) interface{} - VisitExpressionForeignCall(*ExpressionForeignCall) interface{} - VisitExpressionVariable(*ExpressionVariable) interface{} - VisitExpressionArrayAccess(*ExpressionArrayAccess) interface{} - VisitExpressionFieldAccess(*ExpressionFieldAccess) interface{} - VisitExpressionParenthesized(*ExpressionParenthesized) interface{} - VisitExpressionComparison(*ExpressionComparison) interface{} - VisitExpressionArithmetic(*ExpressionArithmetic) interface{} - VisitLoopTargetRange(*LoopTargetRange) interface{} - VisitLoopTargetCall(*LoopTargetCall) interface{} - VisitLoopTargetVariable(*LoopTargetVariable) interface{} - VisitLoopTargetSQL(*LoopTargetSQL) interface{} -} - -// BaseVisitor is a base implementation of Visitor. -type BaseVisitor struct{} - -var _ Visitor = &BaseVisitor{} - -func (v *BaseVisitor) VisitStatementVariableDeclaration(s *StatementVariableDeclaration) interface{} { - return nil -} -func (v *BaseVisitor) VisitStatementVariableAssignment(*StatementVariableAssignment) interface{} { - return nil -} -func (v *BaseVisitor) VisitStatementVariableAssignmentWithDeclaration(*StatementVariableAssignmentWithDeclaration) interface{} { - return nil -} -func (v *BaseVisitor) VisitStatementProcedureCall(*StatementProcedureCall) interface{} { - return nil -} -func (v *BaseVisitor) VisitStatementForLoop(*StatementForLoop) interface{} { return nil } -func (v *BaseVisitor) VisitStatementIf(*StatementIf) interface{} { return nil } -func (v *BaseVisitor) VisitStatementSQL(*StatementSQL) interface{} { return nil } -func (v *BaseVisitor) VisitStatementReturn(*StatementReturn) interface{} { return nil } -func (v *BaseVisitor) VisitStatementReturnNext(*StatementReturnNext) interface{} { - return nil -} -func (v *BaseVisitor) VisitStatementBreak(*StatementBreak) interface{} { - return nil -} -func (v *BaseVisitor) VisitExpressionTextLiteral(*ExpressionTextLiteral) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionBooleanLiteral(*ExpressionBooleanLiteral) interface{} { - return nil -} -func (v *BaseVisitor) VisitExpressionIntLiteral(*ExpressionIntLiteral) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionNullLiteral(*ExpressionNullLiteral) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionBlobLiteral(*ExpressionBlobLiteral) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionMakeArray(*ExpressionMakeArray) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionCall(*ExpressionCall) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionForeignCall(*ExpressionForeignCall) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionVariable(*ExpressionVariable) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionArrayAccess(*ExpressionArrayAccess) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionFieldAccess(*ExpressionFieldAccess) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionParenthesized(*ExpressionParenthesized) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionComparison(*ExpressionComparison) interface{} { return nil } -func (v *BaseVisitor) VisitExpressionArithmetic(*ExpressionArithmetic) interface{} { return nil } -func (b *BaseVisitor) VisitLoopTargetCall(p0 *LoopTargetCall) interface{} { return nil } -func (b *BaseVisitor) VisitLoopTargetRange(p0 *LoopTargetRange) interface{} { return nil } -func (b *BaseVisitor) VisitLoopTargetVariable(p0 *LoopTargetVariable) interface{} { return nil } -func (b *BaseVisitor) VisitLoopTargetSQL(p0 *LoopTargetSQL) interface{} { return nil } diff --git a/parse/procedures/parser/visitor.go b/parse/procedures/parser/visitor.go deleted file mode 100644 index 5a9ae101d..000000000 --- a/parse/procedures/parser/visitor.go +++ /dev/null @@ -1,634 +0,0 @@ -package parser - -import ( - "encoding/hex" - "errors" - "fmt" - "strconv" - "strings" - - "github.com/antlr4-go/antlr/v4" - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/procedures/gen" - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -type proceduralLangVisitor struct { - *gen.BaseProcedureParserVisitor - errs parseTypes.AntlrErrorListener -} - -func (p *proceduralLangVisitor) Visit(tree antlr.ParseTree) interface{} { - return tree.Accept(p) -} - -func (p *proceduralLangVisitor) VisitNormal_call(ctx *gen.Normal_callContext) any { - e := &ExpressionCall{ - Name: ctx.IDENTIFIER().GetText(), - } - - if ctx.Expression_list() != nil { - e.Arguments = ctx.Expression_list().Accept(p).([]Expression) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitForeign_call(ctx *gen.Foreign_callContext) any { - e := &ExpressionForeignCall{ - Name: ctx.IDENTIFIER().GetText(), - } - - dbid := ctx.GetDbid() - if dbid == nil { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("missing dbid")) - } - - procedure := ctx.GetProcedure() - if procedure == nil { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("missing procedure")) - } - - e.ContextArgs = []Expression{dbid.Accept(p).(Expression), procedure.Accept(p).(Expression)} - - if ctx.Expression_list() != nil { - e.Arguments = ctx.Expression_list().Accept(p).([]Expression) - } - - e.Set(ctx) - - return e - -} - -func (p *proceduralLangVisitor) VisitExpr_arithmetic(ctx *gen.Expr_arithmeticContext) any { - expr := &ExpressionArithmetic{ - Left: p.Visit(ctx.Expression(0)).(Expression), - Right: p.Visit(ctx.Expression(1)).(Expression), - } - - switch { - case ctx.PLUS() != nil: - expr.Operator = ArithmeticOperatorAdd - case ctx.MINUS() != nil: - expr.Operator = ArithmeticOperatorSub - case ctx.MUL() != nil: - expr.Operator = ArithmeticOperatorMul - case ctx.DIV() != nil: - expr.Operator = ArithmeticOperatorDiv - case ctx.MOD() != nil: - expr.Operator = ArithmeticOperatorMod - default: - panic("invalid arithmetic operator") - } - - expr.Set(ctx) - - return expr -} - -func (p *proceduralLangVisitor) VisitExpr_array_access(ctx *gen.Expr_array_accessContext) any { - e := &ExpressionArrayAccess{ - Target: p.Visit(ctx.Expression(0)).(Expression), - Index: p.Visit(ctx.Expression(1)).(Expression), - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_blob_literal(ctx *gen.Expr_blob_literalContext) any { - b := ctx.BLOB_LITERAL().GetText() - // trim off beginning 0x - if b[:2] != "0x" { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("invalid blob literal")) - } - - b = b[2:] - - decoded, err := hex.DecodeString(b) - if err != nil { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("invalid blob literal")) - } - - e := &ExpressionBlobLiteral{ - Value: decoded, - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_boolean_literal(ctx *gen.Expr_boolean_literalContext) any { - e := &ExpressionBooleanLiteral{ - Value: strings.ToLower(ctx.GetText()) == "true", - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_call(ctx *gen.Expr_callContext) any { - e := p.Visit(ctx.Call_expression()) - - var tc *types.DataType - if ctx.Type_cast() != nil { - tc = ctx.Type_cast().Accept(p).(*types.DataType) - } - - switch v := e.(type) { - case *ExpressionCall: - v.Set(ctx) - v.TypeCast = tc - case *ExpressionForeignCall: - v.Set(ctx) - v.TypeCast = tc - default: - // should never happen - panic(fmt.Sprintf("invalid type cast for %T", e)) - } - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_comparison(ctx *gen.Expr_comparisonContext) any { - c := &ExpressionComparison{ - Left: p.Visit(ctx.Expression(0)).(Expression), - Right: p.Visit(ctx.Expression(1)).(Expression), - } - - switch { - case ctx.EQ() != nil: - c.Operator = ComparisonOperatorEqual - case ctx.NEQ() != nil: - c.Operator = ComparisonOperatorNotEqual - case ctx.LT() != nil: - c.Operator = ComparisonOperatorLessThan - case ctx.LT_EQ() != nil: - c.Operator = ComparisonOperatorLessThanOrEqual - case ctx.GT() != nil: - c.Operator = ComparisonOperatorGreaterThan - case ctx.GT_EQ() != nil: - c.Operator = ComparisonOperatorGreaterThanOrEqual - default: - panic("invalid comparison operator") - } - - c.Set(ctx) - - return c -} - -func (p *proceduralLangVisitor) VisitExpr_field_access(ctx *gen.Expr_field_accessContext) any { - e := &ExpressionFieldAccess{ - Target: p.Visit(ctx.Expression()).(Expression), - Field: ctx.IDENTIFIER().GetText(), - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_int_literal(ctx *gen.Expr_int_literalContext) any { - textVal := ctx.INT_LITERAL().GetText() - i, err := strconv.ParseInt(textVal, 10, 64) - if err != nil { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("invalid integer literal")) - } - - e := &ExpressionIntLiteral{ - Value: i, - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_make_array(ctx *gen.Expr_make_arrayContext) any { - e := p.Visit(ctx.Expression_make_array()) - - var tc *types.DataType - if ctx.Type_cast() != nil { - tc = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e2, ok := e.(*ExpressionMakeArray) - if !ok { - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeUnknown, errors.New("expected array literal")) - } - - e2.Set(ctx) - e2.TypeCast = tc - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_null_literal(ctx *gen.Expr_null_literalContext) any { - e := &ExpressionNullLiteral{} - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_parenthesized(ctx *gen.Expr_parenthesizedContext) any { - e := &ExpressionParenthesized{ - Expression: p.Visit(ctx.Expression()).(Expression), - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_text_literal(ctx *gen.Expr_text_literalContext) any { - - // parse out the quotes - if len(ctx.TEXT_LITERAL().GetText()) < 2 { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("invalid text literal")) - } - - if ctx.TEXT_LITERAL().GetText()[0] != '\'' || ctx.TEXT_LITERAL().GetText()[len(ctx.TEXT_LITERAL().GetText())-1] != '\'' { - // this should get caught by the parser - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("invalid text literal")) - } - - text := ctx.TEXT_LITERAL().GetText()[1 : len(ctx.TEXT_LITERAL().GetText())-1] - - e := &ExpressionTextLiteral{ - Value: text, - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpr_variable(ctx *gen.Expr_variableContext) any { - e := &ExpressionVariable{ - Name: getVariable(ctx.VARIABLE()), - } - - if ctx.Type_cast() != nil { - e.TypeCast = ctx.Type_cast().Accept(p).(*types.DataType) - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitExpression_list(ctx *gen.Expression_listContext) any { - exprs := make([]Expression, len(ctx.AllExpression())) - for i, expr := range ctx.AllExpression() { - exprs[i] = p.Visit(expr).(Expression) - } - - return exprs -} - -func (p *proceduralLangVisitor) VisitExpression_make_array(ctx *gen.Expression_make_arrayContext) any { - exprs := p.Visit(ctx.Expression_list()).([]Expression) - - e := &ExpressionMakeArray{ - Values: exprs, - } - - // we do not handle type casts here, they are handled in the parent - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitProgram(ctx *gen.ProgramContext) any { - var clauses []Statement - for _, statement := range ctx.AllStatement() { - res := p.Visit(statement) - if res != nil { - clauses = append(clauses, res.(Statement)) - } - } - - return clauses -} - -func (p *proceduralLangVisitor) VisitRange(ctx *gen.RangeContext) any { - e := &LoopTargetRange{ - Start: p.Visit(ctx.Expression(0)).(Expression), - End: p.Visit(ctx.Expression(1)).(Expression), - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitStmt_procedure_call(ctx *gen.Stmt_procedure_callContext) any { - s := &StatementProcedureCall{ - Call: ctx.Call_expression().Accept(p).(ICallExpression), - } - - if len(ctx.AllVariable_or_underscore()) > 0 { - s.Variables = make([]*string, len(ctx.AllVariable_or_underscore())) - } - for i, arg := range ctx.AllVariable_or_underscore() { - // can either be *string or nil - v := arg.Accept(p) - varStr, ok := v.(*string) - if ok { - s.Variables[i] = varStr - } else { - // check if it's nil - if v != nil { - // this would be a bug - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeUnknown, errors.New("invalid variable")) - } - s.Variables[i] = nil - } - } - - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitVariable_or_underscore(ctx *gen.Variable_or_underscoreContext) any { - if ctx.UNDERSCORE() != nil { - return nil - } - if ctx.VARIABLE() != nil { - v := getVariable(ctx.VARIABLE()) - return &v - } - - // this should never happen - p.errs.RuleErr(ctx, parseTypes.ParseErrorTypeUnknown, errors.New("invalid variable")) - return nil -} - -func (p *proceduralLangVisitor) VisitStmt_for_loop(ctx *gen.Stmt_for_loopContext) any { - forLoop := &StatementForLoop{ - Variable: getVariable(ctx.VARIABLE(0)), - } - - switch { - case ctx.Range_() != nil: - forLoop.Target = ctx.Range_().Accept(p).(*LoopTargetRange) - case ctx.Call_expression() != nil: - forLoop.Target = &LoopTargetCall{ - Call: ctx.Call_expression().Accept(p).(ICallExpression), - } - case len(ctx.AllVARIABLE()) > 1 && ctx.VARIABLE(1) != nil: - forLoop.Target = &LoopTargetVariable{ - Variable: &ExpressionVariable{ - Name: getVariable(ctx.VARIABLE(1)), - }, - } - case ctx.ANY_SQL() != nil: - sqlLoc := &parseTypes.Node{} - sqlLoc.SetToken(ctx.ANY_SQL().GetSymbol()) - forLoop.Target = &LoopTargetSQL{ - Statement: p.parseSQLToken(ctx.ANY_SQL()), - StatementLocation: sqlLoc, - } - } - - stmts := make([]Statement, len(ctx.AllStatement())) - for i, stmt := range ctx.AllStatement() { - stmts[i] = p.Visit(stmt).(Statement) - } - forLoop.Body = stmts - - forLoop.Set(ctx) - - return forLoop -} - -func (p *proceduralLangVisitor) VisitStmt_if(ctx *gen.Stmt_ifContext) any { - ifThens := ctx.AllIf_then_block() - ifClause := &StatementIf{ - IfThens: make([]*IfThen, len(ifThens)), - } - - for i, ifThen := range ifThens { - ifClause.IfThens[i] = p.Visit(ifThen).(*IfThen) - } - - if ctx.ELSE() != nil { - stmts := make([]Statement, len(ctx.AllStatement())) - for i, stmt := range ctx.AllStatement() { - stmts[i] = p.Visit(stmt).(Statement) - } - - ifClause.Else = stmts - } - - ifClause.Set(ctx) - - return ifClause -} - -func (p *proceduralLangVisitor) VisitIf_then_block(ctx *gen.If_then_blockContext) any { - - stmts := make([]Statement, len(ctx.AllStatement())) - for i, stmt := range ctx.AllStatement() { - stmts[i] = p.Visit(stmt).(Statement) - } - - e := &IfThen{ - If: p.Visit(ctx.Expression()).(Expression), - Then: stmts, - } - - e.Set(ctx) - - return e -} - -func (p *proceduralLangVisitor) VisitStmt_return(ctx *gen.Stmt_returnContext) any { - if ctx.Expression_list() != nil { - s := &StatementReturn{ - Values: ctx.Expression_list().Accept(p).([]Expression), - } - - s.Set(ctx) - - return s - } - - if ctx.ANY_SQL() != nil { - sqlLoc := &parseTypes.Node{} - sqlLoc.SetToken(ctx.ANY_SQL().GetSymbol()) - s := &StatementReturn{ - SQL: p.parseSQLToken(ctx.ANY_SQL()), - SQLLocation: sqlLoc, - } - s.Set(ctx) - return s - } - - s := &StatementReturn{} - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitStmt_return_next(ctx *gen.Stmt_return_nextContext) any { - s := &StatementReturnNext{ - Returns: ctx.Expression_list().Accept(p).([]Expression), - } - - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitStmt_break(ctx *gen.Stmt_breakContext) interface{} { - s := &StatementBreak{} - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitStmt_sql(ctx *gen.Stmt_sqlContext) any { - sqlLoc := &parseTypes.Node{} - sqlLoc.SetToken(ctx.ANY_SQL().GetSymbol()) - s := &StatementSQL{ - Statement: p.parseSQLToken(ctx.ANY_SQL()), - StatementLocation: sqlLoc, - } - s.Set(ctx) - return s -} - -// ParseSQLToken parses a SQL statement token. -// Since SQL statements are defined as entire tokens in the procedural language, -// they get lexed as a single token. This function will parse the token into an AST. -// It will attempt to parse exactly one sql statement. If more than one statement is found, -// it will return the first statement and log an error. If no statements are found, it will -// return an empty select statement. -func (p *proceduralLangVisitor) parseSQLToken(tok antlr.TerminalNode) tree.AstNode { - stmt := tok.GetText() - errLis := p.errs.ChildFromToken("sql-parse", tok.GetSymbol()) - ast, err := sqlparser.ParseWithErrorListener(stmt, errLis) - if err != nil { - panic(fmt.Errorf("error parsing SQL statement: %s: %s ", stmt, err.Error())) - } - if errLis.Err() != nil { - p.errs.Add(errLis.Errors()...) - } - - if len(ast) != 1 { - p.errs.TokenErr(tok.GetSymbol(), parseTypes.ParseErrorTypeSyntax, errors.New("expected single SQL statement, found "+strconv.Itoa(len(ast)))) - - if len(ast) > 0 { - return ast[0] - } - - return &tree.SelectStmt{} // just to avoid nil pointer dereference - } - - return ast[0] -} - -func (p *proceduralLangVisitor) VisitStmt_variable_assignment(ctx *gen.Stmt_variable_assignmentContext) any { - s := &StatementVariableAssignment{ - Name: getVariable(ctx.VARIABLE()), - Value: p.Visit(ctx.Expression()).(Expression), - } - - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitStmt_variable_assignment_with_declaration(ctx *gen.Stmt_variable_assignment_with_declarationContext) any { - s := &StatementVariableAssignmentWithDeclaration{ - Name: getVariable(ctx.VARIABLE()), - Type: getType(ctx.Type_()), - Value: p.Visit(ctx.Expression()).(Expression), - } - - s.Set(ctx) - return s -} - -func (p *proceduralLangVisitor) VisitStmt_variable_declaration(ctx *gen.Stmt_variable_declarationContext) any { - s := &StatementVariableDeclaration{ - Name: getVariable(ctx.VARIABLE()), - Type: getType(ctx.Type_()), - } - - s.Set(ctx) - return s -} - -func getVariable(v antlr.TerminalNode) string { - t := v.GetText() - // trim off beginning $ - if t[0] != '$' && t[0] != '@' { - // this should never happen - panic("variable names must start with $ or @") - } - - return t -} - -func getType(t gen.ITypeContext) *types.DataType { - return &types.DataType{ - Name: t.IDENTIFIER().GetText(), - IsArray: t.LBRACKET() != nil, - } -} - -func (p *proceduralLangVisitor) VisitType_cast(ctx *gen.Type_castContext) any { - dt := &types.DataType{ - Name: ctx.IDENTIFIER().GetText(), - } - if ctx.LBRACKET() != nil { - dt.IsArray = true - } - - return dt -} diff --git a/parse/procedures/procedures.go b/parse/procedures/procedures.go deleted file mode 100644 index 387361ecd..000000000 --- a/parse/procedures/procedures.go +++ /dev/null @@ -1,153 +0,0 @@ -// package procedures ties together the different visitors to generate the plpgsql code for a procedure. -package procedures - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/core/types" - procedure "github.com/kwilteam/kwil-db/parse/procedures/parser" - "github.com/kwilteam/kwil-db/parse/procedures/visitors/clean" - "github.com/kwilteam/kwil-db/parse/procedures/visitors/generate" - "github.com/kwilteam/kwil-db/parse/procedures/visitors/typing" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// AnalyzeOptions allows for setting options for the generation of plpgsql functions. -// These are useful to control generation behavior and error messages, depending on -// the context in which the generation is being used. E.g., certain errors may be -// more useful in an IDE than in the transaction logs. -type AnalyzeOptions struct { - // LogProcedureNameOnError will log the procedure name in the error message. - // This is generally useful if the parser is not being used in an IDE where positional - // errors are displayed, and we want to tell the user which procedure caused the error. - LogProcedureNameOnError bool - // SchemaInfo is the schema information for the procedure. - // If it is not nil, the schema information will be used to modify the position - // of the error messages. - SchemaInfo *parseTypes.SchemaInfo -} - -// AnalyzeProcedures will analyze a procedure, parse the body, and identify the inputs, returns, variables, and body -// that need to be generated for the procedure. -func AnalyzeProcedures(schema *types.Schema, pgSchemaName string, options *AnalyzeOptions) (stmts []*AnalyzedProcedure, parseErrs parseTypes.ParseErrors, err error) { - stmts = make([]*AnalyzedProcedure, len(schema.Procedures)) - parseErrs = make(parseTypes.ParseErrors, 0) - - if options == nil { - options = &AnalyzeOptions{} - } - - // declaring variables here to allow us to add additional - // information to the error message. - var proc *types.Procedure - var i int - defer func() { - if err != nil && options.LogProcedureNameOnError { - err = fmt.Errorf(`error on procedure "%s": %w`, proc.Name, err) - } - }() - - for i, proc = range schema.Procedures { - - // if schema info is provided, we will use it to modify the error messages. - errorListener := parseTypes.NewErrorListener() - startLine := 0 - startCol := 0 - if options.SchemaInfo != nil { - procPos, ok := options.SchemaInfo.Blocks[proc.Name] - if !ok { - // should never happen, this would be a bug in our code - return nil, nil, fmt.Errorf("could not find position for procedure %s", proc.Name) - } - startLine = procPos.StartLine - startCol = procPos.StartCol - } - errorListener = errorListener.Child("procedure", startLine, startCol) - - parsed, err := procedure.ParseWithErrorListener(proc.Body, errorListener) - if err != nil { - return nil, nil, err - } - - // if there are errors, we should not continue generating the procedure - if errorListener.Err() != nil { - parseErrs.Add(errorListener.Errors()...) - continue - } - - cleanedParams, cleanedSessionVars, err := clean.CleanProcedure(parsed, proc, schema, pgSchemaName, errorListener) - if err != nil { - return nil, nil, err - } - - // if there are errors, we should not continue generating the procedure - if errorListener.Err() != nil { - parseErrs.Add(errorListener.Errors()...) - continue - } - - anonReceivers, err := typing.EnsureTyping(parsed, proc, schema, cleanedParams, cleanedSessionVars, errorListener) - if err != nil { - return nil, nil, err - } - - // if there are errors, we should not continue generating the procedure - if errorListener.Err() != nil { - parseErrs.Add(errorListener.Errors()...) - continue - } - - generated, err := generate.GenerateProcedure(parsed, proc, cleanedParams, anonReceivers, pgSchemaName) - if err != nil { - return nil, nil, err - } - - // If the procedure returns out variables (instead of a table), then we need to ensure that the generated names - // are used, instead of the user-provided names. - returns := types.ProcedureReturn{} - if proc.Returns != nil { - returns = *proc.Returns.Copy() - if generated.OutVariables != nil { - returns.Fields = generated.OutVariables - } - } - - analyzed := &AnalyzedProcedure{ - Name: proc.Name, - Parameters: cleanedParams, - Returns: returns, - DeclaredVariables: generated.DeclaredVariables, - LoopTargets: generated.LoopTargets, - Body: generated.Body, - IsView: proc.IsView(), - OwnerOnly: proc.IsOwnerOnly(), - } - - stmts[i] = analyzed - } - - return stmts, parseErrs, nil -} - -// AnalyzedProcedure is the result of analyzing a procedure. -type AnalyzedProcedure struct { - // Name is the name of the procedure. - Name string - // Parameters are the parameters, in order, that the procedure is expecting. - // If no parameters are expected, this will be nil. - Parameters []*types.NamedType - // Returns is the expected return type(s) of the procedure. - // If no return is expected, this will be nil. - Returns types.ProcedureReturn - // DeclaredVariables are the variables that need to be declared. - DeclaredVariables []*types.NamedType - // LoopTargets is a list of all variables that are loop targets. - // They should be declared as RECORD in plpgsql. - LoopTargets []string - // Body is the plpgsql code for the procedure. - Body string - // IsView is true if the procedure is a view. - IsView bool - // OwnerOnly is true if the procedure is owner-only. - OwnerOnly bool -} diff --git a/parse/procedures/procedures_test.go b/parse/procedures/procedures_test.go deleted file mode 100644 index aad67ad9e..000000000 --- a/parse/procedures/procedures_test.go +++ /dev/null @@ -1,537 +0,0 @@ -package procedures_test - -import ( - "fmt" - "strings" - "testing" - - coreTypes "github.com/kwilteam/kwil-db/core/types" - procedural "github.com/kwilteam/kwil-db/parse/procedures" - "github.com/kwilteam/kwil-db/parse/types" - "github.com/stretchr/testify/require" -) - -// flag that can be set to false for quick debugging. -// If true, it will deploy 3 helper procedures to the schema -// that can be used in the tests. -var deployHelperProcedures = true - -// this test is meant to test the error outputs of certain procedure -// errors. These include syntax errors, types errors, etc. -func Test_Procedures(t *testing.T) { - type testcase struct { - name string - procedure *coreTypes.Procedure - wantErr error - } - - tests := []testcase{ - { - name: "simple", - procedure: procedure("simple"). - withParams("$id:int"). - withBody(` - $id2 int := $id + 1; - `). - build(), - }, - { - name: "adding text", - procedure: procedure("adding_text"). - withParams(). - withBody(` - $id2 int := 1 + '1'; - `).build(), - wantErr: types.ErrArithmeticType, - }, - { - name: "returning single value", - procedure: procedure("returning_single_value"). - withParams(). - withBody(` - return 1; - `).withReturns("int").build(), - }, - { - name: "returning multiple values", - procedure: procedure("returning_multiple_values"). - withParams(). - withBody(` - return 1, 'hello'; - `).withReturns("int", "text").build(), - }, - { - name: "returning table", - procedure: procedure("returning_table"). - withParams(). - withBody(` - return SELECT id, name FROM users; - `).withReturns("table(id int, name text)").build(), - }, - { - name: "for loop select stmt", - procedure: procedure("for_loop"). - withParams(). - withBody(` - $arr int[]; - FOR $row IN SELECT id, name FROM users { - $arr := array_append($arr, $row.id); - } - - return $arr; - `).withReturns("int[]").build(), - }, - { - name: "for loop select to an invalid type", - procedure: procedure("for_loop_invalid_type"). - withParams(). - withBody(` - $arr text[]; - FOR $row IN SELECT id, name FROM users { - $arr := array_append($arr, $row.id); - } - - return $arr; - `). - withReturns("int").build(), - wantErr: types.ErrArrayType, - }, - { - name: "for loop over array", - procedure: procedure("for_loop_array"). - withParams("$arr:text[]"). - withBody(` - FOR $i IN $arr { - return $i; - } - `). - withReturns("text"). - build(), - }, - { - name: "for loop over array return invalid type", - procedure: procedure("for_loop_array_invalid_type"). - withParams("$arr:text[]"). - withBody(` - FOR $i IN $arr { - return $i; - } - `). - withReturns("int"). - build(), - wantErr: types.ErrAssignment, - }, - { - name: "for loop over range", - procedure: procedure("for_loop_range"). - withParams("$start:int", "$end:int"). - withBody(` - $arr int[]; - FOR $i IN $start:$end { - $arr := array_append($arr, $i); - } - - return $arr; - `). - withReturns("int[]"). - build(), - }, - { - name: "for loop over a procedure call", - procedure: procedure("for_loop_procedure_call"). - withParams(). - withBody(` - for $row in get_users() { - if $row.id == 10 { - break; - } - } - `). - build(), - }, - { - name: "array manipulations", - procedure: procedure("array_manipulations"). - withParams("$name:text"). - withBody(` - $name_arr text[] := ['name1', 'name2']; - $name_arr := array_append($name_arr, $name); - $name_arr2 text[] := array_cat($name_arr, ['name3', 'name4']); - $len int := array_length($name_arr2); - - return $name_arr2[$len - 1]; - `). - withReturns("text"). - build(), - }, - { - name: "invalid array manipulation", - procedure: procedure("invalid_array_manipulations"). - withParams("$name:text"). - withBody(` - $name_arr text := 'name1'; - $name_arr2 text[] := array_append($name_arr, $name); - `). - build(), - wantErr: types.ErrParamType, - }, - { - name: "bare procedure call", - procedure: procedure("bare_procedure_call"). - withParams(). - withBody(` - create_user('name', 10, 'address'); - `). - build(), - }, - { - name: "assigning two variables from a procedure call", - procedure: procedure("assigning_two_variables"). - withParams(). - withBody(` - $id int; - $name text; - $id, $name := get_user(1); - return $id, $name; - `). - withReturns("int", "text"). - build(), - }, - { - name: "assigning two variables from a procedure call with invalid type", - procedure: procedure("assigning_two_variables_invalid_type"). - withParams(). - withBody(` - $id text; - $name text; - $id, $name := get_user(1); - `). - build(), - wantErr: types.ErrAssignment, - }, - { - name: "misplaced break", - procedure: procedure("misplaced_break"). - withParams(). - withBody(` - break; - `). - build(), - wantErr: types.ErrBreakUsedOutsideOfLoop, - }, - { - name: "return next", - procedure: procedure("return_next"). - withParams(). - withBody(` - for $row in SELECT id FROM users { - return next $row.id; - } - `). - withReturns("table(id int)"). - build(), - }, - { - name: "if elseif else", - procedure: procedure("if_elseif_else"). - withParams("$id:int"). - withBody(` - if $id > 10 { - return 1; - } elseif $id < 10 { - return 2; - } else { - return 3; - } - `). - withReturns("int"). - build(), - }, - { - name: "multiple ifs with different types", - procedure: procedure("multiple_ifs"). - withParams("$id:int"). - withBody(` - if $id > 10 { - return 1; - } elseif $id < 10 { - return 3, 4; - } else { - return 3; - } - `). - withReturns("int"). - build(), - wantErr: types.ErrReturnCount, - }, - { - name: "sql stmt", - procedure: procedure("sql_stmt"). - withParams(). - withBody(` - INSERT INTO users (name, age, address) VALUES (@txid, 10, @caller); - `). - build(), - }, - { - name: "return single user", - procedure: procedure("return_single_user"). - withParams("$id:int"). - withBody(` - for $row in SELECT id, name FROM users WHERE id = $id { - return $row.id, $row.name; - } - error('user not found'); - `).withReturns("int", "text").build(), - }, - { - name: "procedure call returning table", - procedure: procedure("proc_call"). - withParams(). - withBody(` - $res int := get_users(); - `). - build(), - wantErr: types.ErrAssignment, - }, - { - name: "procedure call with anonymous receiver", - procedure: procedure("proc_call_anonymous_receiver"). - withParams(). - withBody(` - $id int; - $id, _ := get_user(1); - `). - build(), - }, - { - name: "null comparison", - procedure: procedure("null_comparison"). - withParams("$name:text"). - withBody(` - if $name == null { - } - `).build(), - }, - { - name: "sql- invalid join syntax", - procedure: procedure("invalid_join"). - withParams(). - withBody(` - SELECT * FROM users INNER J; - `).build(), - wantErr: types.ErrSyntaxError, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - procs := []*coreTypes.Procedure{tt.procedure} - if deployHelperProcedures { - procs = append(procs, testProcedures...) - } - - _, parseErrs, err := procedural.AnalyzeProcedures(&coreTypes.Schema{ - Tables: testTables, - Procedures: procs, - }, "test_schema", nil) - require.NoError(t, err) // ensure no error is returned, and that they were caught by the error listener - // we want to check parse errors in this test too - if tt.wantErr != nil { - require.NotNil(t, parseErrs) - // we want to ensure that the first error is the one we expect - firstErr := parseErrs[0] - require.Contains(t, firstErr.Error(), tt.wantErr.Error()) - } else { - require.Empty(t, parseErrs) - } - }) - } -} - -var ( - testTables = []*coreTypes.Table{ - { - Name: "users", - Columns: []*coreTypes.Column{ - { - Name: "id", - Type: coreTypes.IntType, - Attributes: []*coreTypes.Attribute{ - { - Type: coreTypes.PRIMARY_KEY, - }, - }, - }, - { - Name: "name", - Type: coreTypes.TextType, - }, - { - Name: "age", - Type: coreTypes.IntType, - }, - { - Name: "address", - Type: coreTypes.TextType, - }, - }, - }, - { - Name: "posts", - Columns: []*coreTypes.Column{ - { - Name: "id", - Type: coreTypes.IntType, - Attributes: []*coreTypes.Attribute{ - { - Type: coreTypes.PRIMARY_KEY, - }, - }, - }, - { - Name: "title", - Type: coreTypes.TextType, - }, - { - Name: "content", - Type: coreTypes.TextType, - }, - { - Name: "author_id", - Type: coreTypes.IntType, - }, - }, - }, - } - - testProcedures = []*coreTypes.Procedure{ - procedure("get_users"). - withBody(` - return SELECT id, name FROM users; - `). - withReturns("table(id int, name text)"). - build(), - procedure("get_user"). - withParams("$id:int"). - withBody(` - for $row in SELECT id, name FROM users WHERE id = $id { - return $row.id, $row.name; - } - `). - withReturns("int", "text"). - build(), - procedure("create_user"). - withParams("$name:text", "$age:int", "$address:text"). - withBody(` - INSERT INTO users (name, age, address) VALUES ($name, $age, $address); - `). - build(), - } -) - -// procedureBuilder is a utility to build a procedure for testing. -type procedureBuilder struct { - name string - params []string - body string - returns []string -} - -func procedure(name string) *procedureBuilder { - return &procedureBuilder{ - name: name, - } -} - -func (pb *procedureBuilder) withParams(params ...string) *procedureBuilder { - pb.params = params - return pb -} - -func (pb *procedureBuilder) withBody(body string) *procedureBuilder { - pb.body = body - return pb -} - -func (pb *procedureBuilder) withReturns(returns ...string) *procedureBuilder { - pb.returns = returns - return pb -} - -func (pb *procedureBuilder) build() *coreTypes.Procedure { - params := make([]*coreTypes.ProcedureParameter, len(pb.params)) - for i, p := range pb.params { - strs := strings.Split(p, ":") - - isArray := false - if strings.HasSuffix(strs[1], "[]") { - isArray = true - strs[1] = strs[1][:len(strs[1])-2] - } - - params[i] = &coreTypes.ProcedureParameter{ - Name: strs[0], - Type: &coreTypes.DataType{ - Name: strs[1], - IsArray: isArray, - }, - } - } - - procReturn := &coreTypes.ProcedureReturn{} - - if len(pb.returns) == 1 && strings.HasPrefix(pb.returns[0], "table") { - procReturn.IsTable = true - // is of type table(name type, name2 type2, ...) - // must parse the name and type - strs := strings.Split(pb.returns[0], "(") - strs = strings.Split(strs[1], ")") - - for _, s := range strings.Split(strs[0], ",") { - s = strings.TrimSpace(s) - sstrs := strings.Split(s, " ") - - isArray := false - if strings.HasSuffix(sstrs[1], "[]") { - isArray = true - sstrs[1] = sstrs[1][:len(sstrs[1])-2] - } - - procReturn.Fields = append(procReturn.Fields, &coreTypes.NamedType{ - Name: sstrs[0], - Type: &coreTypes.DataType{ - Name: sstrs[1], - IsArray: isArray, - }, - }) - } - } else { - returns := make([]*coreTypes.NamedType, len(pb.returns)) - - for i, r := range pb.returns { - isArray := false - if strings.HasSuffix(r, "[]") { - isArray = true - r = r[:len(r)-2] - } - - returns[i] = &coreTypes.NamedType{ - Name: fmt.Sprintf("ret%d", i), - Type: &coreTypes.DataType{ - Name: r, - IsArray: isArray, - }, - } - } - procReturn.Fields = returns - } - - return &coreTypes.Procedure{ - Name: pb.name, - Public: true, - Parameters: params, - Body: pb.body, - Returns: procReturn, - } -} diff --git a/parse/procedures/visitors/clean/clean.go b/parse/procedures/visitors/clean/clean.go deleted file mode 100644 index 0c5d54a9d..000000000 --- a/parse/procedures/visitors/clean/clean.go +++ /dev/null @@ -1,342 +0,0 @@ -// package clean cleans inputs to ensure they are valid. -// it will enforce: -// - all variables are given a name that will not collide with columns -// - all types referencing the local schema will be fully qualified -// - RETURN queries must return either a SELECT or have a RETURNING clause -// - SQL Loop Terms must be SELECTs (no RETURNING clauses allowed) -// - aliases for type "Schema" fields will be fully qualified -// - all SQL queries must be deterministic - -package clean - -import ( - "errors" - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - parser "github.com/kwilteam/kwil-db/parse/procedures/parser" - "github.com/kwilteam/kwil-db/parse/procedures/visitors/traverse" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/parameters" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -// CleanProcedure cleans a procedure to ensure it is valid. -// It will alter the underlying statements to ensure they are valid. -// It will return a list of types and their names that should be declared -// as part of the PLPGSQL function's signature. It also returns a map of -// session variables. These are things like @caller, but renamed to work within -// Postgres. -// It takes the parsed statements, the target procedure and its schema, the pg schema name, -// a prefix which it will used to prefix postgres session variables -// and a set of known postgres session variables and their types. -func CleanProcedure(stmts []parser.Statement, proc *types.Procedure, currentSchema *types.Schema, pgSchemaName string, - errorListener parseTypes.NativeErrorListener) (params []*types.NamedType, sessionVars map[string]*types.DataType, err error) { - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("%v", e) - } - - } - }() - - c := cleaner{ - currentProc: proc, - currentSchema: currentSchema, - pgSchemaName: pgSchemaName, - cleanedSessionVars: map[string]*types.DataType{}, - sqlCanMutate: !proc.IsView(), - errs: errorListener, - } - - // cleanedParams holds the cleaned procedure parameters. - cleanedParams := make([]*types.NamedType, len(proc.Parameters)) - for i, param := range proc.Parameters { - // copy param to avoid modifying the original - - named := &types.NamedType{ - Name: param.Name, - Type: param.Type.Copy(), - } - - c.cleanVar(&named.Name) - - cleanedParams[i] = named - } - - t := traverse.Traverser{ - // statements - StatementVariableDeclaration: func(svd *parser.StatementVariableDeclaration) { - c.cleanVar(&svd.Name) - c.cleanType(svd.Type) - }, - StatementVariableAssignmentWithDeclaration: func(sva *parser.StatementVariableAssignmentWithDeclaration) { - c.cleanVar(&sva.Name) - c.cleanType(sva.Type) - }, - StatementVariableAssignment: func(sva *parser.StatementVariableAssignment) { - c.cleanVar(&sva.Name) - }, - StatementForLoop: func(sfl *parser.StatementForLoop) { - c.cleanVar(&sfl.Variable) - }, - StatementSQL: func(ss *parser.StatementSQL) { - c.cleanSQL(ss.Statement, ss.StatementLocation) - }, - StatementReturn: func(sr *parser.StatementReturn) { - if sr.SQL != nil { - c.cleanSQL(sr.SQL, sr.SQLLocation) - if !returnable(sr.SQL) { - errorListener.NodeErr(&sr.Node, parseTypes.ParseErrorTypeSemantic, - errors.New("RETURN statement must return a SELECT or have a RETURNING clause")) - } - } - }, - StatementProcedureCall: func(spc *parser.StatementProcedureCall) { - cleanedVars := make([]*string, len(spc.Variables)) - for i, arg := range spc.Variables { - if arg != nil { - c.cleanVar(arg) - } - cleanedVars[i] = arg - } - spc.Variables = cleanedVars - }, - // loop targets - LoopTargetSQL: func(lts *parser.LoopTargetSQL) { - c.cleanSQL(lts.Statement, lts.StatementLocation) - - if !returnable(lts.Statement) { - errorListener.NodeErr(<s.Node, parseTypes.ParseErrorTypeSemantic, - errors.New("LOOP target must be a SELECT or have a RETURNING clause")) - } - }, - // expressions - ExpressionMakeArray: func(ema *parser.ExpressionMakeArray) { - if len(ema.Values) == 0 { - errorListener.NodeErr(&ema.Node, parseTypes.ParseErrorTypeSemantic, - errors.New("ARRAY must have at least one element")) - } - }, - ExpressionCall: func(ec *parser.ExpressionCall) { - // we need to check if this is a built in function, - // or a user-defined procedure. If it is a procedure, - // we need to check if it is a view or not. - - ec.Name = strings.ToLower(ec.Name) - _, ok := metadata.Functions[ec.Name] - if !ok { - if c.isForeignProcedure(ec.Name) { - return - } - - proc2, err := c.findProcedure(ec.Name) - if err != nil { - panic(err) - } - - if proc.IsView() && !proc2.IsView() { - errorListener.NodeErr(&ec.Node, parseTypes.ParseErrorTypeSemantic, - fmt.Errorf(`%w: "%s"`, parseTypes.ErrReadOnlyProcedureCallsMutative, proc2.Name)) - } - } - }, - ExpressionForeignCall: func(efc *parser.ExpressionForeignCall) { - // this must be a locally defined procedure - proc, err := c.findForeignProcedure(efc.Name) - if err != nil { - errorListener.NodeErr(&efc.Node, parseTypes.ParseErrorTypeSemantic, err) - } - - if len(efc.ContextArgs) != 2 { - errorListener.NodeErr(&efc.Node, parseTypes.ParseErrorTypeSemantic, - errors.New("foreign procedure calls must have two context arguments")) - } - - if len(efc.Arguments) != len(proc.Parameters) { - errorListener.NodeErr(&efc.Node, parseTypes.ParseErrorTypeSemantic, - errors.New("foreign procedure calls must have the same number of arguments as foreign procedure definition")) - } - - efc.Name = strings.ToLower(efc.Name) - }, - ExpressionVariable: func(ev *parser.ExpressionVariable) { - c.cleanVar(&ev.Name) - }, - ExpressionComparison: func(ec *parser.ExpressionComparison) { - err := ec.Operator.Validate() - if err != nil { - // this should never happen - errorListener.NodeErr(&ec.Node, parseTypes.ParseErrorTypeSyntax, err) - } - }, - ExpressionArithmetic: func(ea *parser.ExpressionArithmetic) { - err := ea.Operator.Validate() - if err != nil { - // this should never happen - errorListener.NodeErr(&ea.Node, parseTypes.ParseErrorTypeSyntax, err) - } - }, - } - - for _, stmt := range stmts { - stmt.Accept(&t) - } - - return cleanedParams, c.cleanedSessionVars, nil -} - -type cleaner struct { - currentSchema *types.Schema - currentProc *types.Procedure - pgSchemaName string - cleanedSessionVars map[string]*types.DataType - sqlCanMutate bool - errs parseTypes.NativeErrorListener -} - -// cleanType ensures a type is fully qualified. -// If the type is not a default type, it will be fully qualified. -// If there is no schema specified, it will be assumed to be the current schema. -// If there is a schema specified, it will use the alias. -func (c *cleaner) cleanType(t *types.DataType) { - err := t.Clean() - if err != nil { - panic(err) - } -} - -// cleanVar ensures a variable name is valid. -func (c *cleaner) cleanVar(n *string) { - r := strings.ToLower(*n) - - if len(r) == 0 || len(r) > 32 { - panic("variable names must be between 1 and 32 characters") - } - - // variables in Kwil are defined with either $ or @, but these - // are not allowed in plpgsql. Furthermore, plpgsql is very picky with - // collisions, and will collide variable and column names. Therefore, - // we remove the prefixes and given them a unique name. Since Kwil - // enforces all columns to start with a letter, we can use underscores - - switch r[0] { - case '$': - // user-defined parameter - *n = util.FormatParameterName(r) - return - case '@': - // for contextual parameters, we use postgres's current_setting() - // feature for setting session variables. For example, @caller - // is accessed via current_setting('ctx.caller') - - sesVar, ok := metadata.GetSessionVariable(r) - if !ok { - panic(fmt.Errorf("%w: %s", parseTypes.ErrUnknownContextualVariable, r)) - } - - // contextual parameter - *n = util.FormatContextualVariableName(r, sesVar) - c.cleanedSessionVars[*n] = sesVar - return - default: - // this should never happen - panic("variable names must start with $ or @") - } -} - -// cleanSQL ensures the SQL AST is valid. -func (c *cleaner) cleanSQL(ast tree.AstNode, ctx *parseTypes.Node) { - // if errors are encountered during cleaning, we should not continue - // in order to avoid panics due to the SQL being invalid. - errLis := c.errs.Child("sql-clean", ctx.StartLine, ctx.StartCol) - err := sqlanalyzer.CleanAST(ast, c.currentSchema, c.pgSchemaName, errLis) - if err != nil { - panic(err) - } - if errLis.Err() != nil { - c.errs.Add(errLis.Errors()...) - return - } - - isMutative, err := sqlanalyzer.IsMutative(ast) - if err != nil { - panic(err) - } - - if !c.sqlCanMutate && isMutative { - c.errs.NodeErr(ctx, parseTypes.ParseErrorTypeSemantic, parseTypes.ErrReadOnlyProcedureContainsDML) - } - - err = parameters.RenameVariables(ast, func(s string) string { - c.cleanVar(&s) - return s - }) - if err != nil { - panic(err) - } -} - -// findProcedure finds a procedure based on its name. -// it returns an error if the schema or procedure is not found. -func (c *cleaner) findProcedure(name string) (*types.Procedure, error) { - for _, proc := range c.currentSchema.Procedures { - if strings.EqualFold(proc.Name, name) { - return proc, nil - } - } - - return nil, fmt.Errorf(`%w: "%s"`, parseTypes.ErrUnknownFunctionOrProcedure, name) -} - -func (c *cleaner) isForeignProcedure(name string) bool { - for _, proc := range c.currentSchema.ForeignProcedures { - if strings.EqualFold(proc.Name, name) { - return true - } - } - - return false -} - -// findForeignProcedure finds a foreign procedure based on its name. -// it returns an error if the schema or procedure is not found. -func (c *cleaner) findForeignProcedure(name string) (*types.ForeignProcedure, error) { - for _, proc := range c.currentSchema.ForeignProcedures { - if strings.EqualFold(proc.Name, name) { - return proc, nil - } - } - - return nil, fmt.Errorf(`%w: "%s"`, parseTypes.ErrUnknownForeignProcedure, name) -} - -// returnable returns true if the statement -// either has a top-level select, or a RETURNING clause. -func returnable(ast tree.AstNode) bool { - _, ok := ast.(*tree.SelectStmt) - if ok { - return true - } - - hasReturning := false - - err := ast.Walk(&tree.ImplementedListener{ - FuncEnterReturningClause: func(p0 *tree.ReturningClause) error { - hasReturning = true - return nil - }, - }) - if err != nil { - panic(err) - } - - return hasReturning -} diff --git a/parse/procedures/visitors/generate/generate.go b/parse/procedures/visitors/generate/generate.go deleted file mode 100644 index 2ba502dc4..000000000 --- a/parse/procedures/visitors/generate/generate.go +++ /dev/null @@ -1,82 +0,0 @@ -// package generate generates the plpgsql code for a procedure. -package generate - -import ( - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/core/utils/order" - parser "github.com/kwilteam/kwil-db/parse/procedures/parser" -) - -type GeneratedProcedure struct { - // Body is the plpgsql code for the procedure. - Body string - // DeclaredVariables are the variables that need to be declared. - DeclaredVariables []*types.NamedType - // LoopTargets are variables that are loop targets. - // They should be declared as RECORD. - LoopTargets []string - // OutVariables are the variables that need to be declared. - OutVariables []*types.NamedType -} - -// GenerateProcedure generates the plpgsql code for a procedure. -// It returns the body, as well as the variables that need to be declared. -// Unlike other visitors, it does not need an error listener, since all errors -// should already be caught. There are some checks it does internally, but this -// should be treated as a last-resort check, and failure to catch these earlier -// should be considered a bug. -func GenerateProcedure(stmts []parser.Statement, proc *types.Procedure, procedureInputs []*types.NamedType, - anonymousReceiverTypes []*types.DataType, pgSchemaName string) (g *GeneratedProcedure, err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("panic: %v", e) - } - }() - - // add procedure inputs to the variables - variables := make(map[string]*types.DataType) - for _, arg := range procedureInputs { - variables[arg.Name] = arg.Type - } - - v := &generatorVisitor{ - variables: variables, - currentProcedure: proc, - anonymousTypes: anonymousReceiverTypes, - pgSchemaName: pgSchemaName, - } - - body := strings.Builder{} - for _, stmt := range stmts { - stmt := stmt.Accept(v).(string) - if stmt == "" { - continue - } - body.WriteString(stmt) - body.WriteString("\n") - } - - declared := make([]*types.NamedType, 0, len(v.variables)) - for _, kv := range order.OrderMap(v.variables) { - declared = append(declared, &types.NamedType{ - Name: kv.Key, - Type: kv.Value.Copy(), - }) - } - - // sanity check in case we have too many/little - // anonymous receivers declared - if len(anonymousReceiverTypes) != v.anonymousReceiverCount { - return nil, fmt.Errorf("internal bug: expected %d anonymous receivers, got %d", v.anonymousReceiverCount, len(anonymousReceiverTypes)) - } - - return &GeneratedProcedure{ - Body: body.String(), - DeclaredVariables: declared, - OutVariables: v.returnedVariables, - LoopTargets: v.loopTargets, - }, nil -} diff --git a/parse/procedures/visitors/generate/visitor.go b/parse/procedures/visitors/generate/visitor.go deleted file mode 100644 index 07462dc0a..000000000 --- a/parse/procedures/visitors/generate/visitor.go +++ /dev/null @@ -1,497 +0,0 @@ -package generate - -import ( - "encoding/hex" - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - parser "github.com/kwilteam/kwil-db/parse/procedures/parser" - "github.com/kwilteam/kwil-db/parse/sql/tree" - "github.com/kwilteam/kwil-db/parse/util" -) - -type generatorVisitor struct { - // variables tracks all variables that the visitor comes across. - // it will assign the variables a unique name. - variables map[string]*types.DataType - // currentProcedure is the current procedure being generated. - currentProcedure *types.Procedure - - // anonymousReceiverCount is the count of anonymous receivers. - // It is used to ensure unique names for anonymous receivers. - // Anonymoud receivers are used when a procedure returns like: - // $return1, _, $return3 := ... - anonymousReceiverCount int - // anonymousTypes are the types of the anonymous receivers. - anonymousTypes []*types.DataType - - // returnedVariables holds the variables that are returned by the procedure, - // if any. - returnedVariables []*types.NamedType - // loopTargets are the variables that are loop targets. - loopTargets []string - // inLoop is true if the visitor is currently in a loop. - inLoop bool - // pgSchemaName is the name of the postgres schema. - pgSchemaName string -} - -var _ parser.Visitor = &generatorVisitor{} - -func (g *generatorVisitor) VisitExpressionArithmetic(p0 *parser.ExpressionArithmetic) any { - str := strings.Builder{} - - str.WriteString(p0.Left.Accept(g).(string)) - str.WriteString(" ") - str.WriteString(string(p0.Operator)) - str.WriteString(" ") - str.WriteString(p0.Right.Accept(g).(string)) - - return str.String() -} - -func (g *generatorVisitor) VisitExpressionArrayAccess(p0 *parser.ExpressionArrayAccess) any { - return typeCast(fmt.Sprintf("%s[%s]", p0.Target.Accept(g).(string), p0.Index.Accept(g).(string)), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionBlobLiteral(p0 *parser.ExpressionBlobLiteral) any { - return typeCast(fmt.Sprintf("'\\%s'", hex.EncodeToString(p0.Value)), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionBooleanLiteral(p0 *parser.ExpressionBooleanLiteral) any { - return typeCast(fmt.Sprintf("%t", p0.Value), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionCall(p0 *parser.ExpressionCall) any { - - inputs := make([]string, len(p0.Arguments)) - for i, arg := range p0.Arguments { - inputs[i] = arg.Accept(g).(string) - } - - // if it is not a function, it is a procedure, - // and we need to prefix it with the schema name. - funcDef, ok := metadata.Functions[p0.Name] - if ok { - return typeCast(funcDef.PGFormat(inputs), p0.TypeCast) - } - - str := strings.Builder{} - str.WriteString(g.pgSchemaName) - str.WriteString(".") - str.WriteString(p0.Name) - - str.WriteString("(") - for i, in := range inputs { - if i > 0 { - str.WriteString(", ") - } - - str.WriteString(in) - } - - str.WriteString(")") - - return typeCast(str.String(), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionForeignCall(p0 *parser.ExpressionForeignCall) any { - // foreign procedure calls are simply locally defined functions. - // They are prefixed with _fp_ to hide them from the user. - // They take the two contextual variables as the first two arguments. - // The rest of the arguments are the same as the procedure definition. - - str := strings.Builder{} - - str.WriteString(util.FormatForeignProcedureName(p0.Name)) - - str.WriteString("(") - // appending the context args and regular args. - for i, in := range append(p0.ContextArgs, p0.Arguments...) { - if i > 0 { - str.WriteString(", ") - } - - str.WriteString(in.Accept(g).(string)) - } - - str.WriteString(")") - - return typeCast(str.String(), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionComparison(p0 *parser.ExpressionComparison) any { - str := strings.Builder{} - - str.WriteString(p0.Left.Accept(g).(string)) - str.WriteString(" ") - str.WriteString(string(p0.Operator)) - str.WriteString(" ") - str.WriteString(p0.Right.Accept(g).(string)) - - return str.String() -} - -func (g *generatorVisitor) VisitExpressionFieldAccess(p0 *parser.ExpressionFieldAccess) any { - return typeCast(fmt.Sprintf("%s.%s", p0.Target.Accept(g).(string), p0.Field), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionIntLiteral(p0 *parser.ExpressionIntLiteral) any { - return typeCast(fmt.Sprintf("%d", p0.Value), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionMakeArray(p0 *parser.ExpressionMakeArray) any { - str := strings.Builder{} - str.WriteString("ARRAY[") - for i, val := range p0.Values { - if i > 0 { - str.WriteString(", ") - } - - str.WriteString(val.Accept(g).(string)) - } - - str.WriteString("]") - - return typeCast(str.String(), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionNullLiteral(p0 *parser.ExpressionNullLiteral) any { - return typeCast("NULL", p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionParenthesized(p0 *parser.ExpressionParenthesized) any { - return typeCast(fmt.Sprintf("(%s)", p0.Expression.Accept(g).(string)), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionTextLiteral(p0 *parser.ExpressionTextLiteral) any { - - // escape single quotes - p0.Value = strings.ReplaceAll(p0.Value, "'", "''") - - return typeCast(fmt.Sprintf("'%s'", p0.Value), p0.TypeCast) -} - -func (g *generatorVisitor) VisitExpressionVariable(p0 *parser.ExpressionVariable) any { - return typeCast(p0.Name, p0.TypeCast) -} - -func (g *generatorVisitor) VisitLoopTargetCall(p0 *parser.LoopTargetCall) any { - return fmt.Sprintf("SELECT * FROM %s", p0.Call.Accept(g).(string)) -} - -func (g *generatorVisitor) VisitLoopTargetRange(p0 *parser.LoopTargetRange) any { - return fmt.Sprintf("%s..%s", p0.Start.Accept(g).(string), p0.End.Accept(g).(string)) -} - -func (g *generatorVisitor) VisitLoopTargetVariable(p0 *parser.LoopTargetVariable) any { - return fmt.Sprintf("ARRAY %s", p0.Variable.Accept(g).(string)) -} - -func (g *generatorVisitor) VisitLoopTargetSQL(p0 *parser.LoopTargetSQL) any { - - stmt, err := tree.SafeToSQL(p0.Statement) - if err != nil { - panic(fmt.Sprintf("error converting statement to sql: %v", err)) - } - - // since our ToSQL returns a semi-colon, we need to remove it. - return strings.TrimSuffix(stmt, "; ") -} - -func (g *generatorVisitor) VisitStatementProcedureCall(p0 *parser.StatementProcedureCall) any { - // in order to handle variadic returns, we will need - // to trim the last paren from the call, and add - // our out variables. - call := p0.Call.Accept(g).(string) - if len(p0.Variables) == 0 { - return fmt.Sprintf("PERFORM %s;", call) - } - - if !strings.HasSuffix(call, ")") { - panic("internal error generating procedure call with return values") - } - - selectInto := strings.Builder{} - for i, v := range p0.Variables { - if i > 0 { - selectInto.WriteString(", ") - } - - // if v is nil, it is an anonymous receiver. - if v == nil { - // if we do not have enough anonymous types, we should panic. - // this is an internal bug. - if len(g.anonymousTypes) <= g.anonymousReceiverCount { - panic("internal error: not enough anonymous types") - } - - // use double underscore for collision avoidance - ident := fmt.Sprintf("__anon_%d", g.anonymousReceiverCount) - g.anonymousReceiverCount++ - - g.variables[ident] = g.anonymousTypes[g.anonymousReceiverCount-1] - selectInto.WriteString(ident) - } else { - selectInto.WriteString(*v) - } - } - - return fmt.Sprintf("SELECT * INTO %s FROM %s;", selectInto.String(), call) -} - -func (g *generatorVisitor) VisitStatementBreak(p0 *parser.StatementBreak) any { - if !g.inLoop { - panic("break statement outside of loop") - } - return "EXIT;" -} - -func (g *generatorVisitor) VisitStatementForLoop(p0 *parser.StatementForLoop) any { - - _, ok := g.variables[p0.Variable] - if ok { - panic(fmt.Sprintf("variable %s already declared", p0.Variable)) - } - - // we need to declare the loop targets as RECORD, - // unless they are looping over a range or array. - str := strings.Builder{} - switch target := p0.Target.(type) { - case *parser.LoopTargetVariable: - // get the target variable type - varType, ok := g.variables[target.Variable.Name] - if !ok { - panic(fmt.Sprintf("variable %s not found", p0.Variable)) - } - - // varType is an array, we declare a variable - // of the same scalar type. - if !varType.IsArray { - // this should be redundant with the type checker, I think I can delete? - panic(fmt.Sprintf("expected array type, got %s", varType)) - } - - g.variables[p0.Variable] = &types.DataType{ - Name: varType.Name, - } - - str.WriteString("FOREACH ") - str.WriteString(p0.Variable) - str.WriteString(" IN ") - str.WriteString(p0.Target.Accept(g).(string)) - case *parser.LoopTargetCall: - g.loopTargets = append(g.loopTargets, p0.Variable) - - str.WriteString("FOR ") - str.WriteString(p0.Variable) - str.WriteString(" IN ") - str.WriteString(p0.Target.Accept(g).(string)) - case *parser.LoopTargetRange: - // declare an int type for the receiver - g.variables[p0.Variable] = types.IntType - - str.WriteString("FOR ") - str.WriteString(p0.Variable) - str.WriteString(" IN ") - str.WriteString(p0.Target.Accept(g).(string)) - case *parser.LoopTargetSQL: - g.loopTargets = append(g.loopTargets, p0.Variable) - - str.WriteString("FOR ") - str.WriteString(p0.Variable) - str.WriteString(" IN ") - str.WriteString(p0.Target.Accept(g).(string)) - default: - panic(fmt.Sprintf("unexpected loop target type: %T", p0.Target)) - } - - str.WriteString(" LOOP\n") - - for _, stmt := range p0.Body { - // we need to check if we are in a loop. - // if we are the outermost loop, we need - // to set inLoop to true, and set it back - // to false when we are done. - if !g.inLoop { - g.inLoop = true - - defer func() { - g.inLoop = false - }() - } - - str.WriteString(stmt.Accept(g).(string)) - str.WriteString("\n") - } - - str.WriteString("END LOOP;") - - return str.String() -} - -func (g *generatorVisitor) VisitStatementIf(p0 *parser.StatementIf) any { - str := strings.Builder{} - - mainIf := p0.IfThens[0] - str.WriteString("IF ") - str.WriteString(mainIf.If.Accept(g).(string)) - str.WriteString(" THEN\n") - for _, stmt := range mainIf.Then { - str.WriteString(stmt.Accept(g).(string)) - str.WriteString("\n") - } - - for _, ifthen := range p0.IfThens[1:] { - str.WriteString("ELSIF ") - str.WriteString(ifthen.If.Accept(g).(string)) - str.WriteString(" THEN\n") - for _, stmt := range ifthen.Then { - str.WriteString(stmt.Accept(g).(string)) - str.WriteString("\n") - } - } - - if p0.Else != nil { - str.WriteString("ELSE\n") - for _, stmt := range p0.Else { - str.WriteString(stmt.Accept(g).(string)) - str.WriteString("\n") - } - } - - str.WriteString("END IF;") - - return str.String() -} - -func (g *generatorVisitor) VisitStatementReturn(p0 *parser.StatementReturn) any { - if p0.SQL != nil { - stmt, err := tree.SafeToSQL(p0.SQL) - if err != nil { - panic(fmt.Sprintf("error converting statement to sql: %v", err)) - } - - return fmt.Sprintf("RETURN QUERY %s", stmt) - } - - str := strings.Builder{} - - if p0.Values != nil { - if len(p0.Values) != len(g.currentProcedure.Returns.Fields) { - panic(fmt.Sprintf("expected %d return values, got %d", len(g.currentProcedure.Returns.Fields), len(p0.Values))) - } - - // redeclare returned variables in case there - // are multiple return paths due to if statements. - g.returnedVariables = make([]*types.NamedType, 0, len(p0.Values)) - - outVars := make([]*types.NamedType, len(p0.Values)) - for i, val := range p0.Values { - s, ok := val.Accept(g).(string) - if !ok { - panic(fmt.Sprintf("unexpected return value type: %T", p0.Values)) - } - - // we need to declare out vars to be able to return them - outVars[i] = &types.NamedType{ - Name: fmt.Sprintf("_out_%d", i), - Type: g.currentProcedure.Returns.Fields[i].Type, - } - - // we will assign the value to the out var - str.WriteString(fmt.Sprintf("%s := %s;\n", outVars[i].Name, s)) - g.returnedVariables = append(g.returnedVariables, &types.NamedType{ - Name: outVars[i].Name, - Type: outVars[i].Type, - }) - } - } - - str.WriteString("RETURN;") - return str.String() -} - -func (g *generatorVisitor) VisitStatementReturnNext(p0 *parser.StatementReturnNext) interface{} { - if !g.inLoop { - panic("RETURN NEXT statement outside of loop") - } - - str := strings.Builder{} - for i, expr := range p0.Returns { - str.WriteString(fmt.Sprintf("%s := %s;\n", g.currentProcedure.Returns.Fields[i].Name, expr.Accept(g).(string))) - } - - str.WriteString("RETURN NEXT;") - - return str.String() -} - -func (g *generatorVisitor) VisitStatementSQL(p0 *parser.StatementSQL) any { - stmt, err := tree.SafeToSQL(p0.Statement) - if err != nil { - panic(fmt.Sprintf("error converting statement to sql: %v", err)) - } - - return stmt -} - -func (g *generatorVisitor) VisitStatementVariableAssignment(p0 *parser.StatementVariableAssignment) any { - - // we will ensure the variable was already declared, - // and then add 1 statement. - - _, ok := g.variables[p0.Name] - if !ok { - panic(fmt.Sprintf("variable %s not found", p0.Name)) - } - - res := p0.Value.Accept(g).(string) - - return fmt.Sprintf("%s := %s;", p0.Name, res) -} - -func (g *generatorVisitor) VisitStatementVariableAssignmentWithDeclaration(p0 *parser.StatementVariableAssignmentWithDeclaration) any { - - // we will add 1 statement, since this is a declaration and an assignment. - - _, ok := g.variables[p0.Name] - if ok { - panic(fmt.Sprintf("variable %s already exists", p0.Name)) - } - - g.variables[p0.Name] = p0.Type - - res := p0.Value.Accept(g).(string) - - return fmt.Sprintf("%s := %s;", p0.Name, res) -} - -func (g *generatorVisitor) VisitStatementVariableDeclaration(p0 *parser.StatementVariableDeclaration) any { - // we will not add any statements, since this is just a declaration. - _, ok := g.variables[p0.Name] - if ok { - panic(fmt.Sprintf("variable %s already exists", p0.Name)) - } - - g.variables[p0.Name] = p0.Type - - return "" -} - -// typeCast casts a string to a specific type. -// If the type is nil, it will return the string as is. -func typeCast(s string, t *types.DataType) string { - if t == nil { - return s - } - - pgName, err := t.PGString() - if err != nil { - panic(fmt.Sprintf("error getting pg string: %v", err)) - } - - return s + "::" + pgName -} diff --git a/parse/procedures/visitors/traverse/traverse.go b/parse/procedures/visitors/traverse/traverse.go deleted file mode 100644 index 0fe200659..000000000 --- a/parse/procedures/visitors/traverse/traverse.go +++ /dev/null @@ -1,286 +0,0 @@ -// Traverse implements a visitor that visits all children of every node in the AST. -// No visitor methods will return anything. -package traverse - -import parser "github.com/kwilteam/kwil-db/parse/procedures/parser" - -// r s all nodes in the AST. -// It can be given a set of functions to call when it visits a node of a certain type. -// It guarantees no order of traversal, and is non-deterministic. -type Traverser struct { - StatementVariableDeclaration func(*parser.StatementVariableDeclaration) - StatementVariableAssignment func(*parser.StatementVariableAssignment) - StatementVariableAssignmentWithDeclaration func(*parser.StatementVariableAssignmentWithDeclaration) - StatementProcedureCall func(*parser.StatementProcedureCall) - StatementForLoop func(*parser.StatementForLoop) - StatementIf func(*parser.StatementIf) - StatementSQL func(*parser.StatementSQL) - StatementReturn func(*parser.StatementReturn) - StatementReturnNext func(*parser.StatementReturnNext) - StatementBreak func(*parser.StatementBreak) - ExpressionTextLiteral func(*parser.ExpressionTextLiteral) - ExpressionBooleanLiteral func(*parser.ExpressionBooleanLiteral) - ExpressionIntLiteral func(*parser.ExpressionIntLiteral) - ExpressionNullLiteral func(*parser.ExpressionNullLiteral) - ExpressionBlobLiteral func(*parser.ExpressionBlobLiteral) - ExpressionMakeArray func(*parser.ExpressionMakeArray) - ExpressionCall func(*parser.ExpressionCall) - ExpressionForeignCall func(*parser.ExpressionForeignCall) - ExpressionVariable func(*parser.ExpressionVariable) - ExpressionArrayAccess func(*parser.ExpressionArrayAccess) - ExpressionFieldAccess func(*parser.ExpressionFieldAccess) - ExpressionParenthesized func(*parser.ExpressionParenthesized) - ExpressionComparison func(*parser.ExpressionComparison) - ExpressionArithmetic func(*parser.ExpressionArithmetic) - LoopTargetRange func(*parser.LoopTargetRange) - LoopTargetCall func(*parser.LoopTargetCall) - LoopTargetVariable func(*parser.LoopTargetVariable) - LoopTargetSQL func(*parser.LoopTargetSQL) -} - -var _ parser.Visitor = &Traverser{} - -func (v *Traverser) VisitStatementVariableDeclaration(s *parser.StatementVariableDeclaration) interface{} { - if v.StatementVariableDeclaration != nil { - v.StatementVariableDeclaration(s) - } - return nil -} -func (v *Traverser) VisitStatementVariableAssignment(s *parser.StatementVariableAssignment) interface{} { - if v.StatementVariableAssignment != nil { - v.StatementVariableAssignment(s) - } - s.Value.Accept(v) - return nil -} -func (v *Traverser) VisitStatementVariableAssignmentWithDeclaration(s *parser.StatementVariableAssignmentWithDeclaration) interface{} { - if v.StatementVariableAssignmentWithDeclaration != nil { - v.StatementVariableAssignmentWithDeclaration(s) - } - s.Value.Accept(v) - return nil -} -func (v *Traverser) VisitStatementProcedureCall(s *parser.StatementProcedureCall) interface{} { - if v.StatementProcedureCall != nil { - v.StatementProcedureCall(s) - } - - s.Call.Accept(v) - - return nil -} -func (v *Traverser) VisitStatementForLoop(s *parser.StatementForLoop) interface{} { - if v.StatementForLoop != nil { - v.StatementForLoop(s) - } - - s.Target.Accept(v) - - for _, stmt := range s.Body { - stmt.Accept(v) - } - - return nil -} -func (v *Traverser) VisitStatementIf(s *parser.StatementIf) interface{} { - if v.StatementIf != nil { - v.StatementIf(s) - } - - for _, ifthen := range s.IfThens { - ifthen.If.Accept(v) - - for _, stmt := range ifthen.Then { - stmt.Accept(v) - } - } - - for _, stmt := range s.Else { - stmt.Accept(v) - } - - return nil -} -func (v *Traverser) VisitStatementSQL(s *parser.StatementSQL) interface{} { - if v.StatementSQL != nil { - v.StatementSQL(s) - } - - return nil -} -func (v *Traverser) VisitStatementReturn(s *parser.StatementReturn) interface{} { - if v.StatementReturn != nil { - v.StatementReturn(s) - } - - for _, expr := range s.Values { - expr.Accept(v) - } - - return nil -} - -func (v *Traverser) VisitStatementReturnNext(s *parser.StatementReturnNext) interface{} { - if v.StatementReturnNext != nil { - v.StatementReturnNext(s) - } - - for _, expr := range s.Returns { - expr.Accept(v) - } - - return nil -} - -func (v *Traverser) VisitStatementBreak(s *parser.StatementBreak) interface{} { - if v.StatementBreak != nil { - v.StatementBreak(s) - } - - return nil -} -func (v *Traverser) VisitExpressionTextLiteral(s *parser.ExpressionTextLiteral) interface{} { - if v.ExpressionTextLiteral != nil { - v.ExpressionTextLiteral(s) - } - return nil -} -func (v *Traverser) VisitExpressionBooleanLiteral(s *parser.ExpressionBooleanLiteral) interface{} { - if v.ExpressionBooleanLiteral != nil { - v.ExpressionBooleanLiteral(s) - } - return nil -} -func (v *Traverser) VisitExpressionIntLiteral(s *parser.ExpressionIntLiteral) interface{} { - if v.ExpressionIntLiteral != nil { - v.ExpressionIntLiteral(s) - } - return nil -} -func (v *Traverser) VisitExpressionNullLiteral(s *parser.ExpressionNullLiteral) interface{} { - if v.ExpressionNullLiteral != nil { - v.ExpressionNullLiteral(s) - } - return nil -} -func (v *Traverser) VisitExpressionBlobLiteral(s *parser.ExpressionBlobLiteral) interface{} { - if v.ExpressionBlobLiteral != nil { - v.ExpressionBlobLiteral(s) - } - return nil -} -func (v *Traverser) VisitExpressionMakeArray(s *parser.ExpressionMakeArray) interface{} { - if v.ExpressionMakeArray != nil { - v.ExpressionMakeArray(s) - } - - for _, elem := range s.Values { - elem.Accept(v) - } - - return nil -} -func (v *Traverser) VisitExpressionCall(s *parser.ExpressionCall) interface{} { - if v.ExpressionCall != nil { - v.ExpressionCall(s) - } - - for _, arg := range s.Arguments { - arg.Accept(v) - } - - return nil -} - -func (v *Traverser) VisitExpressionForeignCall(s *parser.ExpressionForeignCall) interface{} { - if v.ExpressionForeignCall != nil { - v.ExpressionForeignCall(s) - } - - for _, arg := range s.ContextArgs { - arg.Accept(v) - } - - for _, arg := range s.Arguments { - arg.Accept(v) - } - - return nil -} - -func (v *Traverser) VisitExpressionVariable(s *parser.ExpressionVariable) interface{} { - if v.ExpressionVariable != nil { - v.ExpressionVariable(s) - } - return nil -} -func (v *Traverser) VisitExpressionArrayAccess(s *parser.ExpressionArrayAccess) interface{} { - if v.ExpressionArrayAccess != nil { - v.ExpressionArrayAccess(s) - } - s.Target.Accept(v) - s.Index.Accept(v) - return nil -} -func (v *Traverser) VisitExpressionFieldAccess(s *parser.ExpressionFieldAccess) interface{} { - if v.ExpressionFieldAccess != nil { - v.ExpressionFieldAccess(s) - } - s.Target.Accept(v) - return nil -} -func (v *Traverser) VisitExpressionParenthesized(s *parser.ExpressionParenthesized) interface{} { - if v.ExpressionParenthesized != nil { - v.ExpressionParenthesized(s) - } - s.Expression.Accept(v) - return nil -} -func (v *Traverser) VisitExpressionComparison(s *parser.ExpressionComparison) interface{} { - if v.ExpressionComparison != nil { - v.ExpressionComparison(s) - } - s.Left.Accept(v) - s.Right.Accept(v) - return nil -} -func (v *Traverser) VisitExpressionArithmetic(s *parser.ExpressionArithmetic) interface{} { - if v.ExpressionArithmetic != nil { - v.ExpressionArithmetic(s) - } - s.Left.Accept(v) - s.Right.Accept(v) - return nil -} - -func (v *Traverser) VisitLoopTargetRange(s *parser.LoopTargetRange) interface{} { - if v.LoopTargetRange != nil { - v.LoopTargetRange(s) - } - s.Start.Accept(v) - s.End.Accept(v) - return nil -} - -func (v *Traverser) VisitLoopTargetCall(s *parser.LoopTargetCall) interface{} { - if v.LoopTargetCall != nil { - v.LoopTargetCall(s) - } - s.Call.Accept(v) - return nil -} - -func (v *Traverser) VisitLoopTargetVariable(s *parser.LoopTargetVariable) interface{} { - if v.LoopTargetVariable != nil { - v.LoopTargetVariable(s) - } - s.Variable.Accept(v) - return nil -} - -func (v *Traverser) VisitLoopTargetSQL(s *parser.LoopTargetSQL) interface{} { - if v.LoopTargetSQL != nil { - v.LoopTargetSQL(s) - } - return nil -} diff --git a/parse/procedures/visitors/typing/typing.go b/parse/procedures/visitors/typing/typing.go deleted file mode 100644 index d53c0cae3..000000000 --- a/parse/procedures/visitors/typing/typing.go +++ /dev/null @@ -1,946 +0,0 @@ -// package typing checks the type safety of a procedure. -// It will return data types for expressions, map[string]DataType for loop terms, -// and nothing for statements. -package typing - -import ( - "errors" - "fmt" - "runtime" - - coreTypes "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - "github.com/kwilteam/kwil-db/parse/procedures/parser" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/typing" - "github.com/kwilteam/kwil-db/parse/sql/tree" - "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -func EnsureTyping(stmts []parser.Statement, procedure *coreTypes.Procedure, schema *coreTypes.Schema, cleanedInputs []*coreTypes.NamedType, - sessionVars map[string]*coreTypes.DataType, errorListeners types.NativeErrorListener) (anonReceiverTypes []*coreTypes.DataType, err error) { - - declarations := make(map[string]*coreTypes.DataType) - for _, param := range cleanedInputs { - declarations[param.Name] = param.Type - } - - for v, typ := range sessionVars { - _, ok := declarations[v] - if ok { - // this should never happen, since session variables have a unique - // prefix - return nil, fmt.Errorf("session variable %s collision", v) - } - - declarations[v] = typ - } - - t := &typingVisitor{ - currentSchema: schema, - declarations: declarations, - currentProcedure: procedure, - anonymousDeclarations: make(map[string]map[string]*coreTypes.DataType), - anonymousReceiverTypes: make([]*coreTypes.DataType, 0), - errs: errorListeners, - } - - defer func() { - if r := recover(); r != nil { - var ok bool - err, ok = r.(error) - if !ok { - err = fmt.Errorf("panic: %v", r) - } else { - err = fmt.Errorf("panic: %w", err) - } - - // add stack trace since this is a bug: - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - err = fmt.Errorf("%w\n%s", err, buf[:stackSize]) - } - }() - - for _, stmt := range stmts { - stmt.Accept(t) - } - - return t.anonymousReceiverTypes, nil -} - -type typingVisitor struct { - // currentSchema holds the schema of the current procedure - currentSchema *coreTypes.Schema - // declarations holds information about all variable declarations in the procedure - declarations map[string]*coreTypes.DataType - // currentProcedure holds the information about the current procedure - currentProcedure *coreTypes.Procedure - // anonymousDeclarations holds information about all anonymous variable declarations in the procedure - // currently, the only anonymous declarations are loop targets (e.g. FOR i IN SELECT * FROM users). - // anonymousDeclarations are essentially anonymous compound types, so the map maps the name - // to the fields to their data types. - anonymousDeclarations map[string]map[string]*coreTypes.DataType - - // loopTarget is the anonymous declaration of the current loop target. - // Its type can be found in anonymousDeclarations. - // If we are not in a loop, this will be an empty string. - loopTarget string - - // anonymousReceiverTypes holds the types of the anonymous receivers - anonymousReceiverTypes []*coreTypes.DataType - - // errs is the current error listener - errs types.NativeErrorListener -} - -var _ parser.Visitor = &typingVisitor{} - -func (t *typingVisitor) VisitExpressionArithmetic(p0 *parser.ExpressionArithmetic) any { - left := p0.Left.Accept(t).(*coreTypes.DataType) - right := p0.Right.Accept(t).(*coreTypes.DataType) - - if !left.Equals(right) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, leftRightErr(types.ErrArithmeticType, left, right)) - } - - if !isNumeric(left) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, types.ErrNotNumericType) - } - - return coreTypes.IntType -} - -func (t *typingVisitor) VisitExpressionArrayAccess(p0 *parser.ExpressionArrayAccess) any { - t.asserIntType(p0.Index) - - r, ok := p0.Target.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - if !r.IsArray { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, errors.New("expected array")) - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return &coreTypes.DataType{ - Name: r.Name, - } -} - -func (t *typingVisitor) VisitExpressionBlobLiteral(p0 *parser.ExpressionBlobLiteral) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return coreTypes.BlobType -} - -func (t *typingVisitor) VisitExpressionBooleanLiteral(p0 *parser.ExpressionBooleanLiteral) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return coreTypes.BoolType -} - -func (t *typingVisitor) VisitExpressionCall(p0 *parser.ExpressionCall) any { - funcDef, ok := metadata.Functions[p0.Name] - if ok { - argsTypes := make([]*coreTypes.DataType, len(p0.Arguments)) - for i, arg := range p0.Arguments { - argsTypes[i] = arg.Accept(t).(*coreTypes.DataType) - } - - returnType, err := funcDef.ValidateArgs(argsTypes) - if err != nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, err) - return coreTypes.UnknownType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return returnType - } - - params, returns, err := util.FindProcOrForeign(t.currentSchema, p0.Name) - if err != nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, err) - return coreTypes.UnknownType - } - - // check the args - if len(p0.Arguments) != len(params) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`expected %d arguments, got %d`, len(params), len(p0.Arguments))) - return coreTypes.UnknownType - } - - for i, arg := range p0.Arguments { - argType := arg.Accept(t).(*coreTypes.DataType) - if !argType.Equals(params[i]) { - t.errs.NodeErr(arg.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`argument %d has wrong type`, i)) - } - } - - // it must not return a table, and only return exactly one value - if returns == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`procedure "%s" does not return anything`, p0.Name)) - return coreTypes.UnknownType - } - - if returns.IsTable { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`%w: procedure "%s" returns a table`, types.ErrAssignment, p0.Name)) - return coreTypes.UnknownType - } - - if len(returns.Fields) != 1 { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`procedure "%s" does not return exactly 1 value`, p0.Name)) - return coreTypes.UnknownType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return returns.Fields[0].Type -} - -func (t *typingVisitor) VisitExpressionForeignCall(p0 *parser.ExpressionForeignCall) any { - // foreign call must be defined in the schema. - // We will reverse-clean to get the original name, - // and search for it in the foreign procedures. - var proc *coreTypes.ForeignProcedure - found := false - - for _, proc = range t.currentSchema.ForeignProcedures { - if proc.Name == p0.Name { - found = true - break - } - } - if !found { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, fmt.Errorf(`%w: "%s"`, types.ErrUnknownForeignProcedure, p0.Name)) - return coreTypes.UnknownType - } - - // we need to verify that there are exactly two contextual args, and that they are - // both strings - if len(p0.ContextArgs) != 2 { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, errors.New("expected exactly two contextual arguments")) - return coreTypes.UnknownType - } - for _, arg := range p0.ContextArgs { - r, ok := arg.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !r.Equals(coreTypes.TextType) { - t.errs.NodeErr(arg.GetNode(), types.ParseErrorTypeType, errors.New("expected text type")) - } - } - - // check the args - if len(p0.Arguments) != len(proc.Parameters) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`expected %d arguments, got %d`, len(proc.Parameters), len(p0.Arguments))) - return coreTypes.UnknownType - } - - for i, arg := range p0.Arguments { - argType := arg.Accept(t).(*coreTypes.DataType) - if !argType.Equals(proc.Parameters[i]) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`argument %d has wrong type`, i)) - } - } - - if proc.Returns == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`foreign procedure "%s" does not return anything`, p0.Name)) - return coreTypes.UnknownType - } - - // proc must return exactly one value that is not a table - if proc.Returns.IsTable { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`%w: foreign procedure "%s" returns a table`, types.ErrAssignment, p0.Name)) - return coreTypes.UnknownType - } - if len(proc.Returns.Fields) != 1 { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`foreign procedure "%s" does not return exactly 1 value`, p0.Name)) - return coreTypes.UnknownType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return proc.Returns.Fields[0].Type -} - -func (t *typingVisitor) VisitExpressionComparison(p0 *parser.ExpressionComparison) any { - left := p0.Left.Accept(t).(*coreTypes.DataType) - right := p0.Right.Accept(t).(*coreTypes.DataType) - - // left and right must either be the same type, - // or one of them must be null - if !left.Equals(right) { - if !left.Equals(coreTypes.NullType) && !right.Equals(coreTypes.NullType) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, types.ErrComparisonType) - } - } - - return coreTypes.BoolType -} - -func (t *typingVisitor) VisitExpressionFieldAccess(p0 *parser.ExpressionFieldAccess) any { - anonType, ok := p0.Target.Accept(t).(map[string]*coreTypes.DataType) - if !ok { - // this is a bug, so we panic - panic("expected anonymous type") - } - - dt, ok := anonType[p0.Field] - if !ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, types.ErrUnknownField) - return coreTypes.UnknownType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return dt -} - -func (t *typingVisitor) VisitExpressionIntLiteral(p0 *parser.ExpressionIntLiteral) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return coreTypes.IntType -} - -func (t *typingVisitor) VisitExpressionMakeArray(p0 *parser.ExpressionMakeArray) any { - var arrayType *coreTypes.DataType - for _, e := range p0.Values { - dataType, ok := e.Accept(t).(*coreTypes.DataType) - if !ok { - // this is a bug, so we panic - panic(fmt.Sprintf("expected data type in array, got %T", e.Accept(t))) - } - - if dataType.IsArray { - t.errs.NodeErr(e.GetNode(), types.ParseErrorTypeType, errors.New("array cannot contain arrays")) - return coreTypes.UnknownType - } - - if arrayType == nil { - arrayType = dataType - continue - } - - if !arrayType.Equals(dataType) { - t.errs.NodeErr(e.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: %s != %s", types.ErrArrayType, arrayType, dataType)) - } - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return &coreTypes.DataType{ - Name: arrayType.Name, - IsArray: true, - } -} - -func (t *typingVisitor) VisitExpressionNullLiteral(p0 *parser.ExpressionNullLiteral) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return coreTypes.NullType -} - -func (t *typingVisitor) VisitExpressionParenthesized(p0 *parser.ExpressionParenthesized) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return p0.Expression.Accept(t) -} - -func (t *typingVisitor) VisitExpressionTextLiteral(p0 *parser.ExpressionTextLiteral) any { - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return coreTypes.TextType -} - -func (t *typingVisitor) VisitExpressionVariable(p0 *parser.ExpressionVariable) any { - dt, ok := t.declarations[p0.Name] - if !ok { - anonType, ok := t.anonymousDeclarations[p0.Name] - if !ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, - fmt.Errorf(`%w: "%s"`, types.ErrUndeclaredVariable, util.UnformatParameterName(p0.Name))) - return coreTypes.UnknownType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return anonType - } - - // return type cast as the type if it exists - if p0.TypeCast != nil { - return p0.TypeCast - } - - return dt -} - -func (t *typingVisitor) VisitLoopTargetCall(p0 *parser.LoopTargetCall) any { - r := t.analyzeProcedureCall(p0.Call) - - if !r.IsTable { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, errors.New("loops on procedures must return a table")) - } - - vals := make(map[string]*coreTypes.DataType) - for _, col := range r.Fields { - vals[col.Name] = col.Type - } - - return vals -} - -func (t *typingVisitor) VisitLoopTargetRange(p0 *parser.LoopTargetRange) any { - t.asserIntType(p0.Start) - t.asserIntType(p0.End) - return coreTypes.IntType -} - -func (t *typingVisitor) VisitLoopTargetSQL(p0 *parser.LoopTargetSQL) any { - rel := t.analyzeSQL(p0.StatementLocation, p0.Statement) - - r := make(map[string]*coreTypes.DataType) - err := rel.Loop(func(s string, a *typing.Attribute) error { - r[s] = a.Type - return nil - }) - if err != nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, err) - } - return r -} - -func (t *typingVisitor) VisitLoopTargetVariable(p0 *parser.LoopTargetVariable) any { - // must check that the variable is an array - r, ok := p0.Variable.Accept(t).(*coreTypes.DataType) - if !ok { - // this is a bug, so we panic - panic("expected data type") - } - - if !r.IsArray { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, errors.New("expected array")) - return coreTypes.UnknownType - } - - return &coreTypes.DataType{ - Name: r.Name, - } -} - -func (t *typingVisitor) VisitStatementProcedureCall(p0 *parser.StatementProcedureCall) any { - returns := t.analyzeProcedureCall(p0.Call) - - // a procedure that returns data can choose - // not to use the return values - if len(p0.Variables) == 0 { - return nil - } - - if len(returns.Fields) != len(p0.Variables) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`%w: expected: %d received: %d`, types.ErrReturnCount, len(returns.Fields), len(p0.Variables))) - return nil - } - - if returns.IsTable { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: procedure returns a table, which cannot be assigned to variables", types.ErrAssignment)) - } - - for i, v := range p0.Variables { - if v == nil { - // skip if nil, since it is an anonymous receiver - t.anonymousReceiverTypes = append(t.anonymousReceiverTypes, returns.Fields[i].Type) - continue - } - varType, ok := t.declarations[*v] - if !ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`%w: "%s"`, types.ErrUndeclaredVariable, util.UnformatParameterName(*v))) - continue - } - - if !varType.Equals(returns.Fields[i].Type) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`%w: cannot assign return type %s to variable "%s" of type %s`, types.ErrAssignment, returns.Fields[i].Type.String(), util.UnformatParameterName(*v), varType.String())) - } - } - - return nil -} - -// analyzeProcedureCall is used to visit a procedure call and get info on the return type. -// This is kept separate from the visitor, since the visit visits procedure/function calls -// as expressions. When used as expressions, procedures must return exactly 1 value -// (e.g. if a < other_val() {...}). This is used to return more detailed information. -func (t *typingVisitor) analyzeProcedureCall(p0 parser.ICallExpression) *coreTypes.ProcedureReturn { - switch call := p0.(type) { - case *parser.ExpressionCall: - // check if it is a function - funcDef, ok := metadata.Functions[call.Name] - if ok { - argsTypes := make([]*coreTypes.DataType, len(call.Arguments)) - for i, arg := range call.Arguments { - argsTypes[i] = arg.Accept(t).(*coreTypes.DataType) - } - - returnType, err := funcDef.ValidateArgs(argsTypes) - if err != nil { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeType, err) - return &coreTypes.ProcedureReturn{} - } - - return &coreTypes.ProcedureReturn{ - Fields: []*coreTypes.NamedType{ - { - Type: returnType, - }, - }, - } - } - - params, returns, err := util.FindProcOrForeign(t.currentSchema, call.Name) - if err != nil { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeSemantic, err) - return &coreTypes.ProcedureReturn{} - } - - // check the args - if len(call.Arguments) != len(params) { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`expected %d arguments, got %d`, len(params), len(call.Arguments))) - return &coreTypes.ProcedureReturn{} - } - - for i, arg := range call.Arguments { - argType := arg.Accept(t).(*coreTypes.DataType) - if !argType.Equals(params[i]) { - t.errs.NodeErr(arg.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`argument %d has wrong type`, i)) - } - } - - if returns == nil { - return &coreTypes.ProcedureReturn{} // avoid nil pointer - } - - return returns - case *parser.ExpressionForeignCall: - // foreign call must be defined in the schema. - // We will reverse-clean to get the original name, - // and search for it in the foreign procedures. - var proc *coreTypes.ForeignProcedure - found := false - - for _, proc = range t.currentSchema.ForeignProcedures { - if proc.Name == call.Name { - found = true - break - } - } - if !found { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeSemantic, fmt.Errorf(`%w: "%s"`, types.ErrUnknownForeignProcedure, call.Name)) - return &coreTypes.ProcedureReturn{} - } - - // we need to verify that there are exactly two contextual args, and that they are - // both strings - if len(call.ContextArgs) != 2 { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeType, errors.New("expected exactly two contextual arguments")) - return &coreTypes.ProcedureReturn{} - } - for _, arg := range call.ContextArgs { - r, ok := arg.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !r.Equals(coreTypes.TextType) { - t.errs.NodeErr(arg.GetNode(), types.ParseErrorTypeType, errors.New("expected text type")) - } - } - - // check the args - if len(call.Arguments) != len(proc.Parameters) { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`expected %d arguments, got %d`, len(proc.Parameters), len(call.Arguments))) - return &coreTypes.ProcedureReturn{} - } - - for i, arg := range call.Arguments { - argType := arg.Accept(t).(*coreTypes.DataType) - if !argType.Equals(proc.Parameters[i]) { - t.errs.NodeErr(call.GetNode(), types.ParseErrorTypeType, fmt.Errorf(`argument %d has wrong type`, i)) - } - } - - if proc.Returns == nil { - return &coreTypes.ProcedureReturn{} // avoid nil pointer - } - - return proc.Returns - default: - panic("unknown call type") - } -} - -func (t *typingVisitor) VisitStatementBreak(p0 *parser.StatementBreak) any { - if t.loopTarget == "" { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrBreakUsedOutsideOfLoop) - } - return nil -} - -func (t *typingVisitor) VisitStatementForLoop(p0 *parser.StatementForLoop) any { - // set the loop target so children know we are in a loop - t.loopTarget = p0.Variable - - switch target := p0.Target.(type) { - case *parser.LoopTargetVariable: - r := target.Accept(t).(*coreTypes.DataType) - - // we will not declare these as anonymous, since this is simply - // a field in an array of a known type - _, ok := t.declarations[p0.Variable] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - return nil - } - - t.declarations[p0.Variable] = r - - // check that we are iterating over an array - dataType, ok := t.declarations[target.Variable.Name] - if !ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, - fmt.Errorf(`%w: "%s"`, types.ErrUndeclaredVariable, util.UnformatParameterName(target.Variable.Name))) - return nil - } - - if !dataType.IsArray { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`%w: cannot loop over type %s`, types.ErrInvalidIterable, dataType.String())) - return nil - } - case *parser.LoopTargetCall: - // this can be either a table or a custom data type - r := target.Accept(t).(map[string]*coreTypes.DataType) - _, ok := t.anonymousDeclarations[p0.Variable] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - } - - t.anonymousDeclarations[p0.Variable] = r - case *parser.LoopTargetRange: - r := target.Accept(t).(*coreTypes.DataType) // int - - // we will not declare these as anonymous, since it is a simple int - _, ok := t.declarations[p0.Variable] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - } - - t.declarations[p0.Variable] = r - case *parser.LoopTargetSQL: - r := target.Accept(t).(map[string]*coreTypes.DataType) - - _, ok := t.anonymousDeclarations[p0.Variable] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - } - - t.anonymousDeclarations[p0.Variable] = r - default: - panic("unknown loop target") - } - - for _, stmt := range p0.Body { - stmt.Accept(t) - } - - // unset the loop target - t.loopTarget = "" - - return nil -} - -// analyzeSQL analyzes the given SQL statement and returns the resulting relation. -func (t *typingVisitor) analyzeSQL(location *types.Node, stmt tree.AstNode) *typing.Relation { - // we create a new error listener taking into account our current position - errLis := t.errs.Child("sql-types", location.StartLine, location.StartCol) - m, err := typing.AnalyzeTypes(stmt, t.currentSchema.Tables, &typing.AnalyzeOptions{ - BindParams: t.declarations, - Qualify: true, - VerifyProcedures: true, - Schema: t.currentSchema, - ErrorListener: errLis, - }) - if err != nil { - panic(err) - } - - t.errs.Add(errLis.Errors()...) - - return m -} - -func (t *typingVisitor) VisitStatementIf(p0 *parser.StatementIf) any { - for _, it := range p0.IfThens { - t.assertBoolType(it.If) - - for _, stmt := range it.Then { - stmt.Accept(t) - } - } - - for _, stmt := range p0.Else { - stmt.Accept(t) - } - - return nil -} - -func (t *typingVisitor) VisitStatementReturn(p0 *parser.StatementReturn) any { - if t.currentProcedure.Returns == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, errors.New("procedure does not return anything")) - return nil - } - - if t.currentProcedure.Returns.IsTable { - if p0.SQL == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, errors.New("procedure returning table must have a return a SQL statement")) - return nil - } - - r := t.analyzeSQL(p0.SQLLocation, p0.SQL) - - for _, col := range t.currentProcedure.Returns.Fields { - attr, ok := r.Attribute(col.Name) - if !ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, - fmt.Errorf(`missing column: procedure expects column "%s" in return table`, col.Name)) - continue - } - - if !col.Type.Equals(attr.Type) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`column "%s" returns wrong type`, col.Name)) - } - } - } else { - if p0.Values == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, errors.New("procedure expects return values")) - return nil - } - - if len(p0.Values) != len(t.currentProcedure.Returns.Fields) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf(`%w: expected: %d received: %d`, types.ErrReturnCount, len(t.currentProcedure.Returns.Fields), len(p0.Values))) - return nil - } - - for i, v := range p0.Values { - r, ok := v.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !t.currentProcedure.Returns.Fields[i].Type.Equals(r) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: expected: %s received: %s", types.ErrAssignment, t.currentProcedure.Returns.Fields[i].Type.String(), r.String())) - } - } - } - - return nil -} - -func (t *typingVisitor) VisitStatementReturnNext(p0 *parser.StatementReturnNext) any { - if t.loopTarget == "" { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrReturnNextUsedOutsideOfLoop) - return nil - } - - if t.currentProcedure.Returns == nil { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, errors.New("procedure does not return anything")) - return nil - } - - if !t.currentProcedure.Returns.IsTable { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, types.ErrReturnNextUsedInNonTableProc) - return nil - } - - if len(p0.Returns) != len(t.currentProcedure.Returns.Fields) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrReturnNextInvalidCount) - } - - for i, col := range t.currentProcedure.Returns.Fields { - r, ok := p0.Returns[i].Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !col.Type.Equals(r) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: expected: %s received: %s", types.ErrAssignment, col.Type.String(), r.String())) - } - } - - return nil -} - -func (t *typingVisitor) VisitStatementSQL(p0 *parser.StatementSQL) any { - t.analyzeSQL(p0.StatementLocation, p0.Statement) - // we do not care about the return value - return nil -} - -func (t *typingVisitor) VisitStatementVariableAssignment(p0 *parser.StatementVariableAssignment) any { - typ, ok := t.declarations[p0.Name] - if !ok { - // I don't think this can happen - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, - fmt.Errorf(`%w: "%s"`, types.ErrUntypedVariable, util.UnformatParameterName(p0.Name))) - return nil - } - - r, ok := p0.Value.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !typ.Equals(r) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: expected: %s received: %s", types.ErrAssignment, typ, r)) - } - - return nil -} - -func (t *typingVisitor) VisitStatementVariableAssignmentWithDeclaration(p0 *parser.StatementVariableAssignmentWithDeclaration) any { - retType, ok := p0.Value.Accept(t).(*coreTypes.DataType) - if !ok { - panic("BUG: expected data type") - } - - if !p0.Type.Equals(retType) { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeType, - fmt.Errorf("%w: expected: %s received: %s", types.ErrAssignment, p0.Type, retType)) - } - - _, ok = t.declarations[p0.Name] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - return nil - } - - t.declarations[p0.Name] = p0.Type - - return nil -} - -func (t *typingVisitor) VisitStatementVariableDeclaration(p0 *parser.StatementVariableDeclaration) any { - _, ok := t.declarations[p0.Name] - if ok { - t.errs.NodeErr(p0.GetNode(), types.ParseErrorTypeSemantic, types.ErrVariableAlreadyDeclared) - return nil - } - - t.declarations[p0.Name] = p0.Type - return nil -} - -// asserIntType asserts that the given expression is an integer type. -// It will panic if it is not. -func (t *typingVisitor) asserIntType(dt parser.Expression) { - res, ok := dt.Accept(t).(*coreTypes.DataType) - if !ok { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected integer type")) - return - } - if res == nil { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected integer type")) - return - } - - if !res.Equals(coreTypes.IntType) { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected integer type")) - return - } -} - -// assertBoolType asserts that the given expression is a boolean type. -// It will panic if it is not. -func (t *typingVisitor) assertBoolType(dt parser.Expression) { - res, ok := dt.Accept(t).(*coreTypes.DataType) - if !ok { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected boolean type")) - return - } - if res == nil { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected boolean type")) - return - } - - if !res.Equals(coreTypes.BoolType) { - t.errs.NodeErr(dt.GetNode(), types.ParseErrorTypeType, errors.New("expected boolean type")) - return - } -} - -// leftRightErr returns an error with the message that the left and right. It is -// used for incompatible coreTypes. -func leftRightErr(err error, left, right *coreTypes.DataType) error { - return fmt.Errorf("%w: %s not comparable to %s", err, left.String(), right.String()) -} - -// isNumeric returns true if the given data type is numeric. -// right now, this is only int, but we are about to add numeric and uint256 -// TODO: delete the above comment once we add numeric and uint256 -func isNumeric(dt *coreTypes.DataType) bool { - return dt.Equals(coreTypes.IntType) -} diff --git a/parse/procedures/visitors/typing/typing_test.go b/parse/procedures/visitors/typing/typing_test.go deleted file mode 100644 index 6fbe825ff..000000000 --- a/parse/procedures/visitors/typing/typing_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package typing_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/core/types/testdata" - - "github.com/kwilteam/kwil-db/parse/metadata" - parser "github.com/kwilteam/kwil-db/parse/procedures/parser" - "github.com/kwilteam/kwil-db/parse/procedures/visitors/typing" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - - "github.com/stretchr/testify/require" -) - -// TODO: we need better tests, but due to how much these concerns are intertwined with the rest of -// the procedural language, I am going to leave this as is for now, since we will have robust -// procedural language tests. -func Test_Typing(t *testing.T) { - type testcase struct { - name string - body string - err error // can be nil - } - - /* - the bodies below are inputted into a default procedure. - It has two parameters: $id and $name. - */ - - testcases := []testcase{ - { - name: "declare and assign", - body: ` - $id1 int := 1; - `, - }, - { - name: "declare, then assign", - body: ` - $id1 int; - $id1 := 1; - `, - }, - { - name: "double declare", - body: ` - $id1 int; - $id1 text; - `, - err: parseTypes.ErrVariableAlreadyDeclared, - }, - { - name: "redeclare input", - // there is already a parameter named $id - body: ` - $id int; - `, - err: parseTypes.ErrVariableAlreadyDeclared, - }, - { - name: "math", - body: ` - $sum int := $id + 1; - `, - }, - } - - for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - proc := &types.Procedure{ - Name: "simple", - Parameters: []*types.ProcedureParameter{ - { - Name: "$id", - Type: types.IntType, - }, - { - Name: "$name", - Type: types.TextType, - }, - }, - Body: tc.body, - } - - stmts, err := parser.Parse(tc.body) - require.NoError(t, err) - - errListener := parseTypes.NewErrorListener() - - // named types match the parameters of the procedure - _, err = typing.EnsureTyping(stmts, proc, testdata.TestSchema, []*types.NamedType{ - { - Name: "$id", - Type: types.IntType, - }, - { - Name: "$name", - Type: types.TextType, - }, - }, metadata.PgSessionVars, errListener) - // if the error listener has an error, we should use that error - if errListener.Err() != nil { - err = errListener.Err() - } - - if tc.err != nil { - require.ErrorAs(t, err, &tc.err) - } else { - require.NoError(t, err) - } - }) - } -} diff --git a/parse/sql/ast_builder.go b/parse/sql/ast_builder.go deleted file mode 100644 index cee3705c7..000000000 --- a/parse/sql/ast_builder.go +++ /dev/null @@ -1,1326 +0,0 @@ -package sqlparser - -import ( - "encoding/hex" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/antlr4-go/antlr/v4" - - "github.com/kwilteam/kwil-db/core/types" - grammar "github.com/kwilteam/kwil-db/parse/sql/gen" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -// astBuilder is a visitor that visits Antlr parsed tree and builds sql AST. -type astBuilder struct { - *grammar.BaseSQLParserVisitor - errs parseTypes.AntlrErrorListener - trace bool -} - -var _ grammar.SQLParserVisitor = &astBuilder{} - -// VisitCommon_table_expression is called when visiting a common_table_expression, return *tree.CTE -func (v *astBuilder) VisitCommon_table_expression(ctx *grammar.Common_table_expressionContext) interface{} { - cte := tree.CTE{} - cte.Set(ctx) - - // cte_table_name - cteTableCtx := ctx.Cte_table_name() - cte.Table = util.ExtractSQLName(cteTableCtx.Table_name().GetText()) - if len(cteTableCtx.AllColumn_name()) > 0 { - cte.Columns = make([]string, len(cteTableCtx.AllColumn_name())) - for i, colNameCtx := range cteTableCtx.AllColumn_name() { - cte.Columns[i] = util.ExtractSQLName(colNameCtx.GetText()) - } - } - - cte.Select = v.Visit(ctx.Select_core()).(*tree.SelectCore) - return &cte -} - -// VisitCommon_table_stmt is called when visiting a common_table_stmt, return []*tree.CTE. -func (v *astBuilder) VisitCommon_table_stmt(ctx *grammar.Common_table_stmtContext) interface{} { - if ctx == nil { - return nil - } - - cteCount := len(ctx.AllCommon_table_expression()) - ctes := make([]*tree.CTE, cteCount) - for i := 0; i < cteCount; i++ { - cte := v.Visit(ctx.Common_table_expression(i)).(*tree.CTE) - ctes[i] = cte - } - return ctes -} - -func getInsertType(ctx *grammar.Insert_coreContext) tree.InsertType { - return tree.InsertTypeInsert -} - -// VisitType_cast is called when visiting a type_cast, return tree.TypeCastType -func (v *astBuilder) VisitType_cast(ctx *grammar.Type_castContext) interface{} { - if ctx != nil { - typeCastRaw := ctx.Cast_type().GetText() - if typeCastRaw[0] == '`' || typeCastRaw[0] == '"' { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("type cast should not be wrapped in %c", typeCastRaw[0])) - return types.UnknownType - } - - // should be "typename", potentially "typename[]" for array - var typ *types.DataType - if strings.HasSuffix(typeCastRaw, "[]") { - typ = &types.DataType{ - Name: strings.TrimSuffix(typeCastRaw, "[]"), - IsArray: true, - } - } else { - typ = &types.DataType{ - Name: typeCastRaw, - } - } - - err := typ.Clean() - if err != nil { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeType, err) - return types.UnknownType - } - - return typ - } else { - return types.UnknownType - } -} - -// VisitLiteral_expr is called when visiting a literal_expr, return *tree.ExpressionLiteral -func (v *astBuilder) VisitText_literal_expr(ctx *grammar.Text_literal_exprContext) interface{} { - // all literal values are string - val := ctx.TEXT_LITERAL().GetText() - if !strings.HasPrefix(val, "'") || !strings.HasSuffix(val, "'") { - // this shouldn't happen, and should be caught by the lexer - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("invalid text literal %s", val)) - return &tree.ExpressionTextLiteral{} - } - - expr := &tree.ExpressionTextLiteral{ - Value: val[1 : len(val)-1], - } - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -func (v *astBuilder) VisitNumeric_literal_expr(ctx *grammar.Numeric_literal_exprContext) interface{} { - t := ctx.NUMERIC_LITERAL().GetText() - val, err := strconv.ParseInt(t, 10, 64) - if err != nil { - // this shouldn't happen, and should be caught by the lexer - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("failed to parse numeric literal %s: %w", t, err)) - return &tree.ExpressionNumericLiteral{} - } - - expr := &tree.ExpressionNumericLiteral{ - Value: val, - } - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - - return expr -} - -func (v *astBuilder) VisitBoolean_literal_expr(ctx *grammar.Boolean_literal_exprContext) interface{} { - b := ctx.BOOLEAN_LITERAL().GetText() - boolVal, err := strconv.ParseBool(b) - if err != nil { - // this shouldn't happen, and should be caught by the lexer - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("failed to parse boolean literal %s: %w", b, err)) - return &tree.ExpressionBooleanLiteral{} - } - - expr := &tree.ExpressionBooleanLiteral{ - Value: boolVal, - } - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -func (v *astBuilder) VisitNull_literal_expr(ctx *grammar.Null_literal_exprContext) interface{} { - expr := &tree.ExpressionNullLiteral{} - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -func (v *astBuilder) VisitBlob_literal_expr(ctx *grammar.Blob_literal_exprContext) interface{} { - t := ctx.BLOB_LITERAL().GetText() - - // trim 0x prefix - if !strings.HasPrefix(t, "0x") { - // should be caught by the lexer - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("invalid blob literal %s", t)) - return &tree.ExpressionBlobLiteral{} - } - t = t[2:] - - decoded, err := hex.DecodeString(t) - if err != nil { - // should be caught by the lexer - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("failed to decode blob literal %s: %w", t, err)) - return &tree.ExpressionBlobLiteral{} - } - - expr := &tree.ExpressionBlobLiteral{ - Value: decoded, - } - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - - return expr -} - -// VisitVariable_expr is called when visiting a variable_expr, return *tree.ExpressionBindParameter -func (v *astBuilder) VisitVariable_expr(ctx *grammar.Variable_exprContext) interface{} { - expr := &tree.ExpressionBindParameter{ - Parameter: ctx.Variable().GetText(), - } - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -// VisitColumn_ref is called when visiting a column_ref, return *tree.ExpressionColumn, without -// type cast info. -func (v *astBuilder) VisitColumn_ref(ctx *grammar.Column_refContext) interface{} { - expr := &tree.ExpressionColumn{} - if ctx.Table_name() != nil { - expr.Table = util.ExtractSQLName(ctx.Table_name().GetText()) - } - expr.Column = util.ExtractSQLName(ctx.Column_name().GetText()) - expr.Set(ctx) - return expr -} - -// VisitColumn_expr is called when visiting a column_expr, return *tree.ExpressionColumn -func (v *astBuilder) VisitColumn_expr(ctx *grammar.Column_exprContext) interface{} { - expr := v.Visit(ctx.Column_ref()).(*tree.ExpressionColumn) - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -// VistUnary_expr is called when visiting a unary_expr, return *tree.ExpressionUnary -func (v *astBuilder) VisitUnary_expr(ctx *grammar.Unary_exprContext) interface{} { - expr := &tree.ExpressionUnary{} - switch { - case ctx.MINUS() != nil: - expr.Operator = tree.UnaryOperatorMinus - case ctx.PLUS() != nil: - expr.Operator = tree.UnaryOperatorPlus - default: - panic(fmt.Sprintf("unknown unary operator %s", ctx.GetText())) - } - expr.Operand = v.Visit(ctx.Expr()).(tree.Expression) - expr.Set(ctx) - return expr -} - -func (v *astBuilder) getCollateType(collationName string) tree.CollationType { - // case insensitive - switch strings.ToLower(collationName) { - case "nocase": - return tree.CollationTypeNoCase - default: - // NOTE: this is a semantic error - panic(fmt.Sprintf("unknown collation type %s", collationName)) - } -} - -// VisitCollate_expr is called when visiting a collate_expr, return *tree.ExpressionCollate -func (v *astBuilder) VisitCollate_expr(ctx *grammar.Collate_exprContext) interface{} { - collationName := util.ExtractSQLName(ctx.Collation_name().GetText()) - expr2 := &tree.ExpressionCollate{ - Expression: v.Visit(ctx.Expr()).(tree.Expression), - Collation: v.getCollateType(collationName), - } - expr2.Set(ctx) - return expr2 -} - -// VisitParenthesized_expr is called when visiting a parenthesized_expr, return *tree.Expression -func (v *astBuilder) VisitParenthesized_expr(ctx *grammar.Parenthesized_exprContext) interface{} { - var typeCast *types.DataType - if ctx.Type_cast() != nil { - typeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - - expr := v.Visit(ctx.Expr()).(tree.Expression) - switch e := expr.(type) { - case *tree.ExpressionTextLiteral: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionNumericLiteral: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionBooleanLiteral: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionNullLiteral: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionBlobLiteral: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionBindParameter: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionColumn: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionUnary: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionArithmetic: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionBinaryComparison: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionFunction: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionList: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionCollate: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionStringCompare: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionIs: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionBetween: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionSelect: - e.Wrapped = true - e.TypeCast = typeCast - case *tree.ExpressionCase: - e.Wrapped = true - // typeCast does not apply on case expression - } - - expr.Set(ctx) - - return expr -} - -func (v *astBuilder) VisitSubquery(ctx *grammar.SubqueryContext) interface{} { - s := v.Visit(ctx.Select_core()).(*tree.SelectCore) - s.Set(ctx) - return s -} - -// VisitSubquery_expr is called when visiting a subquery_expr, return *tree.ExpressionSelect -func (v *astBuilder) VisitSubquery_expr(ctx *grammar.Subquery_exprContext) interface{} { - stmt := v.Visit(ctx.Subquery()).(*tree.SelectCore) - expr := &tree.ExpressionSelect{ - Select: stmt, - } - if ctx.EXISTS_() != nil { - expr.IsExists = true - } - if ctx.NOT_() != nil { - expr.IsNot = true - } - expr.Set(ctx) - return expr -} - -// VisitWhen_clause is called when visiting a when_clause, return [2]*tree.Expression -func (v *astBuilder) VisitWhen_clause(ctx *grammar.When_clauseContext) interface{} { - var when = [2]tree.Expression{} - when[0] = v.Visit(ctx.GetCondition()).(tree.Expression) - when[1] = v.Visit(ctx.GetResult()).(tree.Expression) - return when -} - -// VisitCase_expr is called when visiting a case_expr, return *tree.ExpressionCase -func (v *astBuilder) VisitCase_expr(ctx *grammar.Case_exprContext) interface{} { - expr := &tree.ExpressionCase{} - if ctx.GetCase_clause() != nil { - expr.CaseExpression = v.Visit(ctx.GetCase_clause()).(tree.Expression) - } - if ctx.GetElse_clause() != nil { - expr.ElseExpression = v.Visit(ctx.GetElse_clause()).(tree.Expression) - } - - for _, whenCtx := range ctx.AllWhen_clause() { - expr.WhenThenPairs = append(expr.WhenThenPairs, - v.Visit(whenCtx).([2]tree.Expression)) - } - expr.Set(ctx) - return expr -} - -// VisitFunction_call is called when visiting a function_call, return *tree.ExpressionFunction -func (v *astBuilder) VisitFunction_call(ctx *grammar.Function_callContext) interface{} { - panic("should be impossible to reach here") - // expr := &tree.ExpressionFunction{ - // Inputs: make([]tree.Expression, len(ctx.AllExpr())), - // } - // expr.Function = util.ExtractSQLName(ctx.Function_name().GetText()) - - // if ctx.STAR() != nil { - // expr.Star = true - // } - // if ctx.DISTINCT_() != nil { - // expr.Distinct = true - // } - - // for i, e := range ctx.AllExpr() { - // expr.Inputs[i] = v.Visit(e).(tree.Expression) - // } - - // return expr -} - -func (v *astBuilder) VisitNormal_function_call(ctx *grammar.Normal_function_callContext) interface{} { - expr := &tree.ExpressionFunction{} - expr.Function = util.ExtractSQLName(ctx.Function_name().GetText()) - - if ctx.STAR() != nil { - expr.Star = true - } - if ctx.DISTINCT_() != nil { - expr.Distinct = true - } - - if ctx.Expr_list() != nil { - expr.Inputs = v.Visit(ctx.Expr_list()).(*tree.ExpressionList).Expressions - } - expr.Set(ctx) - return expr -} - -func (v *astBuilder) VisitForeign_function_call(ctx *grammar.Foreign_function_callContext) interface{} { - expr := &tree.ExpressionFunction{} - - expr.Function = util.ExtractSQLName(ctx.IDENTIFIER().GetText()) - - if ctx.GetDbid() == nil { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("%w: missing dbid", parseTypes.ErrForeignCallMissingField)) - return expr - } - - expr.ContextualParams = append(expr.ContextualParams, v.Visit(ctx.GetDbid()).(tree.Expression)) - - if ctx.GetProcedure() == nil { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("%w: missing procedure", parseTypes.ErrForeignCallMissingField)) - return expr - } - - expr.ContextualParams = append(expr.ContextualParams, v.Visit(ctx.GetProcedure()).(tree.Expression)) - - if ctx.Expr_list() != nil { - expr.Inputs = v.Visit(ctx.Expr_list()).(*tree.ExpressionList).Expressions - } - expr.Set(ctx) - return expr -} - -// VisitFunction_expr is called when visiting a function_expr, return *tree.ExpressionFunction -func (v *astBuilder) VisitFunction_expr(ctx *grammar.Function_exprContext) interface{} { - expr := v.Visit(ctx.Function_call()).(*tree.ExpressionFunction) - if ctx.Type_cast() != nil { - expr.TypeCast = v.Visit(ctx.Type_cast()).(*types.DataType) - } - expr.Set(ctx) - return expr -} - -// VisitExpr_list_expr is called when visiting a expr_list_expr, return *tree.ExpressionList -func (v *astBuilder) VisitExpr_list_expr(ctx *grammar.Expr_list_exprContext) interface{} { - e := v.Visit(ctx.Expr_list()).(*tree.ExpressionList) - e.Set(ctx) - return e -} - -// VisitArithmetic_expr is called when visiting a arithmetic_expr, return *tree.ExpressionArithmetic -func (v *astBuilder) VisitArithmetic_expr(ctx *grammar.Arithmetic_exprContext) interface{} { - expr := &tree.ExpressionArithmetic{} - expr.Left = v.Visit(ctx.GetLeft()).(tree.Expression) - expr.Right = v.Visit(ctx.GetRight()).(tree.Expression) - - switch { - case ctx.STAR() != nil: - expr.Operator = tree.ArithmeticOperatorMultiply - case ctx.DIV() != nil: - expr.Operator = tree.ArithmeticOperatorDivide - case ctx.MOD() != nil: - expr.Operator = tree.ArithmeticOperatorModulus - case ctx.PLUS() != nil: - expr.Operator = tree.ArithmeticOperatorAdd - case ctx.MINUS() != nil: - expr.Operator = tree.ArithmeticOperatorSubtract - default: - panic(fmt.Sprintf("unknown arithmetic operator %s", ctx.GetText())) - } - - expr.Set(ctx) - return expr -} - -// VisitIn_subquery_expr is called when visiting a in_suquery_expr, return *tree.ExpressionBinaryComparison -func (v *astBuilder) VisitIn_subquery_expr(ctx *grammar.In_subquery_exprContext) interface{} { - expr := &tree.ExpressionBinaryComparison{ - Left: v.Visit(ctx.GetElem()).(tree.Expression), - Operator: tree.ComparisonOperatorIn, - } - if ctx.NOT_() != nil { - expr.Operator = tree.ComparisonOperatorNotIn - } - sub := v.Visit(ctx.Subquery()).(*tree.SelectCore) - expr.Right = &tree.ExpressionSelect{ - Select: sub, - Node: sub.Node, - } - expr.Set(ctx) - return expr -} - -// VisitExpr_list is called when visiting a expr_list, return *tree.ExpressionList -func (v *astBuilder) VisitExpr_list(ctx *grammar.Expr_listContext) interface{} { - exprCount := len(ctx.AllExpr()) - exprs := make([]tree.Expression, exprCount) - for i, exprCtx := range ctx.AllExpr() { - exprs[i] = v.Visit(exprCtx).(tree.Expression) - } - expr := &tree.ExpressionList{Expressions: exprs} - expr.Set(ctx) - return expr -} - -// VisitIn_list_expr is called when visiting a in_list_expr, return *tree.ExpressionBinaryComparison -func (v *astBuilder) VisitIn_list_expr(ctx *grammar.In_list_exprContext) interface{} { - expr := &tree.ExpressionBinaryComparison{ - Left: v.Visit(ctx.GetElem()).(tree.Expression), - Operator: tree.ComparisonOperatorIn, - } - if ctx.NOT_() != nil { - expr.Operator = tree.ComparisonOperatorNotIn - } - expr.Right = v.Visit(ctx.Expr_list()).(*tree.ExpressionList) - expr.Set(ctx) - return expr -} - -// VisitBetween_expr is called when visiting a between_expr, return *tree.ExpressionBetween -func (v *astBuilder) VisitBetween_expr(ctx *grammar.Between_exprContext) interface{} { - expr := &tree.ExpressionBetween{ - Expression: v.Visit(ctx.GetElem()).(tree.Expression), - Left: v.Visit(ctx.GetLow()).(tree.Expression), - Right: v.Visit(ctx.GetHigh()).(tree.Expression), - } - if ctx.NOT_() != nil { - expr.NotBetween = true - } - expr.Set(ctx) - return expr -} - -// VisitLike_expr is called when visiting a like_expr, return *tree.ExpressionStringCompare -func (v *astBuilder) VisitLike_expr(ctx *grammar.Like_exprContext) interface{} { - expr := &tree.ExpressionStringCompare{ - Left: v.Visit(ctx.GetElem()).(tree.Expression), - Operator: tree.StringOperatorLike, - Right: v.Visit(ctx.GetPattern()).(tree.Expression), - } - if ctx.NOT_() != nil { - expr.Operator = tree.StringOperatorNotLike - } - if ctx.ESCAPE_() != nil { - expr.Escape = v.Visit(ctx.GetEscape()).(tree.Expression) - } - expr.Set(ctx) - return expr -} - -// VisitComparisonOperator is called when visiting a comparisonOpertor, return tree.ComparisonOperator -func (v *astBuilder) VisitComparisonOperator(ctx *grammar.ComparisonOperatorContext) interface{} { - switch { - case ctx.LT() != nil: - return tree.ComparisonOperatorLessThan - case ctx.LT_EQ() != nil: - return tree.ComparisonOperatorLessThanOrEqual - case ctx.GT() != nil: - return tree.ComparisonOperatorGreaterThan - case ctx.GT_EQ() != nil: - return tree.ComparisonOperatorGreaterThanOrEqual - case ctx.ASSIGN() != nil: - return tree.ComparisonOperatorEqual - case ctx.NOT_EQ1() != nil: - return tree.ComparisonOperatorNotEqual - case ctx.NOT_EQ2() != nil: - return tree.ComparisonOperatorNotEqualDiamond - default: - panic(fmt.Sprintf("unknown comparison operator %s", ctx.GetText())) - } -} - -// VisitComparison_expr is called when visiting a comparison_expr, return *tree.ExpressionBinaryComparison -func (v *astBuilder) VisitComparison_expr(ctx *grammar.Comparison_exprContext) interface{} { - expr := &tree.ExpressionBinaryComparison{ - Left: v.Visit(ctx.GetLeft()).(tree.Expression), - Operator: v.Visit(ctx.ComparisonOperator()).(tree.ComparisonOperator), - Right: v.Visit(ctx.GetRight()).(tree.Expression), - } - expr.Set(ctx) - return expr -} - -// VisitIs_expr is called when visiting a is_expr, return *tree.ExpressionIs -func (v *astBuilder) VisitIs_expr(ctx *grammar.Is_exprContext) interface{} { - expr := &tree.ExpressionIs{ - Left: v.Visit(ctx.Expr(0)).(tree.Expression), - } - expr.Set(ctx) - if ctx.NOT_() != nil { - expr.Not = true - } - - switch { - case ctx.NULL_LITERAL() != nil: - expr.Right = &tree.ExpressionNullLiteral{} - expr.Right.SetToken(ctx.NULL_LITERAL().GetSymbol()) - case ctx.BOOLEAN_LITERAL() != nil: - tf := ctx.BOOLEAN_LITERAL().GetText() - var b bool - if strings.EqualFold(tf, "true") { - b = true - } else if strings.EqualFold(tf, "false") { - b = false - } else { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, fmt.Errorf("unknown boolean literal %s", tf)) - return expr - } - - expr.Right = &tree.ExpressionBooleanLiteral{ - Value: b, - } - expr.Right.SetToken(ctx.BOOLEAN_LITERAL().GetSymbol()) - case ctx.DISTINCT_() != nil: - expr.Right = v.Visit(ctx.Expr(1)).(tree.Expression) - expr.Distinct = true - expr.Right.Set(ctx.Expr(1)) - default: - panic(fmt.Sprintf("unknown IS expression %s", ctx.GetText())) - } - return expr -} - -// VisitNull_expr is called when visiting a null_expr, return *tree.ExpressionIs -func (v *astBuilder) VisitNull_expr(ctx *grammar.Null_exprContext) interface{} { - expr := &tree.ExpressionIs{ - Left: v.Visit(ctx.Expr()).(tree.Expression), - Right: &tree.ExpressionNullLiteral{}, - } - expr.Set(ctx) - expr.Right.Set(ctx) - - if ctx.NOTNULL_() != nil { - expr.Not = true - } - return expr -} - -// VisitLogical_not_expr is called when visiting a logical_not_expr, return *tree.ExpressionUnary -func (v *astBuilder) VisitLogical_not_expr(ctx *grammar.Logical_not_exprContext) interface{} { - e := &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: v.Visit(ctx.Expr()).(tree.Expression), - } - e.Set(ctx) - return e -} - -// VisitLogical_binary_expr is called when visiting a logical_binary_expr, return *tree.ExpressionBinaryLogical -func (v *astBuilder) VisitLogical_binary_expr(ctx *grammar.Logical_binary_exprContext) interface{} { - expr := &tree.ExpressionBinaryComparison{ - Left: v.Visit(ctx.GetLeft()).(tree.Expression), - Right: v.Visit(ctx.GetRight()).(tree.Expression), - } - expr.Set(ctx) - - switch { - case ctx.AND_() != nil: - expr.Operator = tree.LogicalOperatorAnd - case ctx.OR_() != nil: - expr.Operator = tree.LogicalOperatorOr - default: - panic(fmt.Sprintf("unknown logical operator %s", ctx.GetText())) - } - - return expr -} - -// VisitValues_clause is called when visiting a values_clause, return [][]tree.Expression -func (v *astBuilder) VisitValues_clause(ctx *grammar.Values_clauseContext) interface{} { - if ctx == nil { - return nil - } - - allValueRowCtx := ctx.AllValue_row() - rows := make([][]tree.Expression, len(allValueRowCtx)) - for i, valueRowCtx := range allValueRowCtx { - allExprCtx := valueRowCtx.AllExpr() - exprs := make([]tree.Expression, len(allExprCtx)) - for j, exprCtx := range allExprCtx { - exprs[j] = v.Visit(exprCtx).(tree.Expression) - } - rows[i] = exprs - } - return rows -} - -// VisitUpsert_clause is called when visiting a upsert_clause, return *tree.Upsert -func (v *astBuilder) VisitUpsert_clause(ctx *grammar.Upsert_clauseContext) interface{} { - clause := tree.Upsert{ - Type: tree.UpsertTypeDoNothing, - } - clause.Set(ctx) - - // conflict target - conflictTarget := tree.ConflictTarget{} - conflictTarget.Set(ctx) - allIndexedColumnCtx := ctx.AllIndexed_column() - indexedColumns := make([]string, len(allIndexedColumnCtx)) - for i, indexedColumnCtx := range allIndexedColumnCtx { - indexedColumns[i] = util.ExtractSQLName(indexedColumnCtx.Column_name().GetText()) - } - conflictTarget.IndexedColumns = indexedColumns - - if ctx.GetTarget_expr() != nil { - conflictTarget.Where = v.Visit(ctx.GetTarget_expr()).(tree.Expression) - } - - if len(allIndexedColumnCtx) != 0 { - clause.ConflictTarget = &conflictTarget - } - - if ctx.NOTHING_() != nil { - return &clause - } - - // conflict update - clause.Type = tree.UpsertTypeDoUpdate - updateCount := len(ctx.AllUpsert_update()) - updates := make([]*tree.UpdateSetClause, updateCount) - for i, updateCtx := range ctx.AllUpsert_update() { - updates[i] = v.Visit(updateCtx).(*tree.UpdateSetClause) - } - - clause.Updates = updates - - if ctx.GetUpdate_expr() != nil { - clause.Where = v.Visit(ctx.GetUpdate_expr()).(tree.Expression) - } - return &clause -} - -// VisitUpsert_update is called when visiting a upsert_update, return *tree.UpdateSetClause -func (v *astBuilder) VisitUpsert_update(ctx *grammar.Upsert_updateContext) interface{} { - clause := tree.UpdateSetClause{} - clause.Set(ctx) - if ctx.Column_name_list() != nil { - clause.Columns = v.Visit(ctx.Column_name_list()).([]string) - } else { - clause.Columns = []string{util.ExtractSQLName(ctx.Column_name().GetText())} - } - - clause.Expression = v.Visit(ctx.Expr()).(tree.Expression) - return &clause -} - -// VisitColumn_name_list is called when visiting a column_name_list, return []string -func (v *astBuilder) VisitColumn_name_list(ctx *grammar.Column_name_listContext) interface{} { - names := make([]string, len(ctx.AllColumn_name())) - for i, nameCtx := range ctx.AllColumn_name() { - names[i] = util.ExtractSQLName(nameCtx.GetText()) - } - return names -} - -// VisitColumn_name is called when visiting a column_name, return string -func (v *astBuilder) VisitColumn_name(ctx *grammar.Column_nameContext) interface{} { - return util.ExtractSQLName(ctx.GetText()) -} - -// VisitReturning_clause is called when visiting a returning_clause, return *tree.ReturningClause -func (v *astBuilder) VisitReturning_clause(ctx *grammar.Returning_clauseContext) interface{} { - clause := tree.ReturningClause{} - clause.Set(ctx) - clause.Returned = make([]*tree.ReturningClauseColumn, len(ctx.AllReturning_clause_result_column())) - for i, columnCtx := range ctx.AllReturning_clause_result_column() { - if columnCtx.STAR() != nil { - col := &tree.ReturningClauseColumn{ - All: true, - } - col.SetToken(columnCtx.STAR().GetSymbol()) - clause.Returned[i] = col - continue - } - - col := &tree.ReturningClauseColumn{ - Expression: v.Visit(columnCtx.Expr()).(tree.Expression), - } - col.Set(columnCtx.Expr()) - clause.Returned[i] = col - - if columnCtx.Column_alias() != nil { - clause.Returned[i].Alias = util.ExtractSQLName(columnCtx.Column_alias().GetText()) - } - - } - return &clause -} - -// VisitUpdate_set_subclause is called when visiting a column_assign_subclause, return *tree.UpdateSetClause -func (v *astBuilder) VisitUpdate_set_subclause(ctx *grammar.Update_set_subclauseContext) interface{} { - result := tree.UpdateSetClause{} - result.Set(ctx) - if ctx.Column_name_list() != nil { - result.Columns = v.Visit(ctx.Column_name_list()).([]string) - } else { - result.Columns = []string{util.ExtractSQLName(ctx.Column_name().GetText())} - } - - result.Expression = v.Visit(ctx.Expr()).(tree.Expression) - return &result -} - -// VisitQualified_table_name is called when visiting a qualified_table_name, return *tree.QualifiedTableName -func (v *astBuilder) VisitQualified_table_name(ctx *grammar.Qualified_table_nameContext) interface{} { - result := tree.QualifiedTableName{} - result.Set(ctx) - result.TableName = util.ExtractSQLName(ctx.Table_name().GetText()) - - if ctx.Table_alias() != nil { - result.TableAlias = util.ExtractSQLName(ctx.Table_alias().GetText()) - } - - return &result -} - -// VisitUpdate_core is called when visiting a update_core, return *tree.UpdateCore -func (v *astBuilder) VisitUpdate_core(ctx *grammar.Update_coreContext) interface{} { - var updateStmt tree.UpdateCore - updateStmt.Set(ctx) - - updateStmt.QualifiedTableName = v.Visit(ctx.Qualified_table_name()).(*tree.QualifiedTableName) - - updateStmt.UpdateSetClause = make([]*tree.UpdateSetClause, len(ctx.AllUpdate_set_subclause())) - for i, subclauseCtx := range ctx.AllUpdate_set_subclause() { - updateStmt.UpdateSetClause[i] = v.Visit(subclauseCtx).(*tree.UpdateSetClause) - } - - if ctx.FROM_() != nil { - updateStmt.From = v.Visit(ctx.Relation()).(tree.Relation) - } - - if ctx.WHERE_() != nil { - updateStmt.Where = v.Visit(ctx.Expr()).(tree.Expression) - } - - if ctx.Returning_clause() != nil { - updateStmt.Returning = v.Visit(ctx.Returning_clause()).(*tree.ReturningClause) - } - - return &updateStmt -} - -// VisitUpdate_stmt is called when visiting a update_stmt, return *tree.UpdateStmt -func (v *astBuilder) VisitUpdate_stmt(ctx *grammar.Update_stmtContext) interface{} { - t := tree.UpdateStmt{} - t.Set(ctx) - - if ctx.Common_table_stmt() != nil { - t.CTE = v.Visit(ctx.Common_table_stmt()).([]*tree.CTE) - } - - t.Core = v.Visit(ctx.Update_core()).(*tree.UpdateCore) - return &t -} - -func (v *astBuilder) VisitInsert_core(ctx *grammar.Insert_coreContext) interface{} { - var insertStmt tree.InsertCore - insertStmt.Set(ctx) - - insertStmt.InsertType = getInsertType(ctx) - insertStmt.Table = util.ExtractSQLName(ctx.Table_name().GetText()) - if ctx.Table_alias() != nil { - insertStmt.TableAlias = util.ExtractSQLName(ctx.Table_alias().GetText()) - } - - allColumnNameCtx := ctx.AllColumn_name() - if len(allColumnNameCtx) > 0 { - insertStmt.Columns = make([]string, len(allColumnNameCtx)) - for i, nc := range allColumnNameCtx { - insertStmt.Columns[i] = util.ExtractSQLName(nc.GetText()) - } - } - - insertStmt.Values = v.Visit(ctx.Values_clause()).([][]tree.Expression) - if ctx.Upsert_clause() != nil { - insertStmt.Upsert = v.Visit(ctx.Upsert_clause()).(*tree.Upsert) - } - if ctx.Returning_clause() != nil { - insertStmt.ReturningClause = v.Visit(ctx.Returning_clause()).(*tree.ReturningClause) - } - - return &insertStmt -} - -func (v *astBuilder) VisitInsert_stmt(ctx *grammar.Insert_stmtContext) interface{} { - t := tree.InsertStmt{} - t.Set(ctx) - - if ctx.Common_table_stmt() != nil { - t.CTE = v.Visit(ctx.Common_table_stmt()).([]*tree.CTE) - } - - t.Core = v.Visit(ctx.Insert_core()).(*tree.InsertCore) - return &t -} - -// VisitCompound_operator is called when visiting a compound_operator, return *tree.CompoundOperator -func (v *astBuilder) VisitCompound_operator(ctx *grammar.Compound_operatorContext) interface{} { - var t *tree.CompoundOperator - switch { - case ctx.UNION_() != nil: - if ctx.ALL_() != nil { - t = &tree.CompoundOperator{Operator: tree.CompoundOperatorTypeUnionAll} - } else { - t = &tree.CompoundOperator{Operator: tree.CompoundOperatorTypeUnion} - } - case ctx.INTERSECT_() != nil: - t = &tree.CompoundOperator{Operator: tree.CompoundOperatorTypeIntersect} - case ctx.EXCEPT_() != nil: - t = &tree.CompoundOperator{Operator: tree.CompoundOperatorTypeExcept} - default: - panic("unknown compound operator") - } - - t.Set(ctx) - return t -} - -// VisitOrdering_term is called when visiting a ordering_term, return *tree.OrderingTerm -func (v *astBuilder) VisitOrdering_term(ctx *grammar.Ordering_termContext) interface{} { - result := tree.OrderingTerm{} - result.Set(ctx) - result.Expression = v.Visit(ctx.Expr()).(tree.Expression) - - if ctx.Asc_desc() != nil { - if ctx.Asc_desc().DESC_() != nil { - result.OrderType = tree.OrderTypeDesc - } else { - result.OrderType = tree.OrderTypeAsc - } - } - - if ctx.NULLS_() != nil { - if ctx.FIRST_() != nil { - result.NullOrdering = tree.NullOrderingTypeFirst - } else { - result.NullOrdering = tree.NullOrderingTypeLast - } - } - - return &result -} - -// VisitOrder_by_stmt is called when visiting a order_by_stmt, return *tree.OrderBy -func (v *astBuilder) VisitOrder_by_stmt(ctx *grammar.Order_by_stmtContext) interface{} { - count := len(ctx.AllOrdering_term()) - result := tree.OrderBy{OrderingTerms: make([]*tree.OrderingTerm, count)} - result.Set(ctx) - - for i, orderingTermCtx := range ctx.AllOrdering_term() { - result.OrderingTerms[i] = v.Visit(orderingTermCtx).(*tree.OrderingTerm) - } - - return &result -} - -// VisitLimit_stmt is called when visiting a limit_stmt, return *tree.Limit -func (v *astBuilder) VisitLimit_stmt(ctx *grammar.Limit_stmtContext) interface{} { - result := tree.Limit{ - Expression: v.Visit(ctx.Expr(0)).(tree.Expression), - } - result.Set(ctx) - - // LIMIT row_count OFFSET offset; - // IS SAME AS - // LIMIT offset, row_count; - // TODO: in the tree we should just use one or the other, not both. - - if ctx.OFFSET_() != nil { - result.Offset = v.Visit(ctx.Expr(1)).(tree.Expression) - } - - return &result -} - -// VisitTable_or_subquery is called when visiting a table_or_subquery, return tree.TableOrSubquery -func (v *astBuilder) VisitTable_or_subquery(ctx *grammar.Table_or_subqueryContext) interface{} { - switch { - case ctx.Table_name() != nil: - t := tree.RelationTable{ - Name: util.ExtractSQLName(ctx.Table_name().GetText()), - } - if ctx.Table_alias() != nil { - t.Alias = util.ExtractSQLName(ctx.Table_alias().GetText()) - } - t.Set(ctx) - return &t - case ctx.Select_core() != nil: - t := tree.RelationSubquery{ - Select: v.Visit(ctx.Select_core()).(*tree.SelectCore), - } - if ctx.Table_alias() != nil { - t.Alias = util.ExtractSQLName(ctx.Table_alias().GetText()) - } - t.Set(ctx) - return &t - case ctx.Function_call() != nil: - funcDef := v.Visit(ctx.Function_call()).(*tree.ExpressionFunction) - if funcDef.Star { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("cannot join on a function that uses *")) - } - if funcDef.Distinct { - v.errs.RuleErr(ctx, parseTypes.ParseErrorTypeSyntax, errors.New("cannot join on a function that uses DISTINCT")) - } - - t := tree.RelationFunction{ - Function: funcDef, - } - t.Set(ctx) - if ctx.Table_alias() != nil { - t.Alias = util.ExtractSQLName(ctx.Table_alias().GetText()) - } - return &t - default: - panic("unsupported table_or_subquery type") - } -} - -// VisitJoin_operator is called when visiting a join_operator, return *tree.JoinOperator -func (v *astBuilder) VisitJoin_operator(ctx *grammar.Join_operatorContext) interface{} { - jp := tree.JoinOperator{ - JoinType: tree.JoinTypeJoin, - } - jp.Set(ctx) - - if ctx.INNER_() != nil { - jp.JoinType = tree.JoinTypeInner - return &jp - } - - switch { - case ctx.LEFT_() != nil: - jp.JoinType = tree.JoinTypeLeft - case ctx.RIGHT_() != nil: - jp.JoinType = tree.JoinTypeRight - case ctx.FULL_() != nil: - jp.JoinType = tree.JoinTypeFull - } - - if ctx.OUTER_() != nil { - jp.Outer = true - } - - return &jp -} - -// VisitJoin_relation is called when visiting a join_relation, return *tree.JoinPredicate -func (v *astBuilder) VisitJoin_relation(ctx *grammar.Join_relationContext) interface{} { - jp := tree.JoinPredicate{} - jp.Set(ctx) - jp.JoinOperator = v.Visit(ctx.Join_operator()).(*tree.JoinOperator) - jp.Table = v.Visit(ctx.GetRight_relation()).(tree.Relation) - jp.Constraint = v.Visit(ctx.Join_constraint().Expr()).(tree.Expression) - return &jp -} - -// VisitResult_column is called when visiting a result_column, return tree.ResultColumn -func (v *astBuilder) VisitResult_column(ctx *grammar.Result_columnContext) interface{} { - switch { - // table_name need to be checked first - case ctx.Table_name() != nil: - t := &tree.ResultColumnTable{ - TableName: util.ExtractSQLName(ctx.Table_name().GetText()), - } - t.Set(ctx) - return t - case ctx.STAR() != nil: - t := &tree.ResultColumnStar{} - t.Set(ctx) - return t - case ctx.Expr() != nil: - r := &tree.ResultColumnExpression{ - Expression: v.Visit(ctx.Expr()).(tree.Expression), - } - if ctx.Column_alias() != nil { - r.Alias = util.ExtractSQLName(ctx.Column_alias().GetText()) - } - r.Set(ctx) - return r - } - - return nil -} - -func (v *astBuilder) VisitDelete_core(ctx *grammar.Delete_coreContext) interface{} { - var deleteStmt tree.DeleteCore - deleteStmt.Set(ctx) - deleteStmt.QualifiedTableName = v.Visit(ctx.Qualified_table_name()).(*tree.QualifiedTableName) - - if ctx.WHERE_() != nil { - deleteStmt.Where = v.Visit(ctx.Expr()).(tree.Expression) - } - - if ctx.Returning_clause() != nil { - deleteStmt.Returning = v.Visit(ctx.Returning_clause()).(*tree.ReturningClause) - } - - return &deleteStmt -} - -// VisitDelete_stmt is called when visiting a delete_stmt, return *tree.DeleteStmt -func (v *astBuilder) VisitDelete_stmt(ctx *grammar.Delete_stmtContext) interface{} { - t := tree.DeleteStmt{} - t.Set(ctx) - - if ctx.Common_table_stmt() != nil { - t.CTE = v.Visit(ctx.Common_table_stmt()).([]*tree.CTE) - } - - t.Core = v.Visit(ctx.Delete_core()).(*tree.DeleteCore) - return &t -} - -// VisitSimple_select is called when visiting a Simple_select, return *tree.SelectCore -func (v *astBuilder) VisitSimple_select(ctx *grammar.Simple_selectContext) interface{} { - t := tree.SimpleSelect{ - SelectType: tree.SelectTypeAll, - } - t.Set(ctx) - - if ctx.DISTINCT_() != nil { - t.SelectType = tree.SelectTypeDistinct - } - - //NOTE: Columns will be changed in SelectCore - //assume all columns are * or table.* or table.column - t.Columns = make([]tree.ResultColumn, len(ctx.AllResult_column())) - for i, columnCtx := range ctx.AllResult_column() { - t.Columns[i] = v.Visit(columnCtx).(tree.ResultColumn) - } - - if ctx.FROM_() != nil { - t.From = v.Visit(ctx.Relation()).(tree.Relation) - } - - if ctx.GetWhereExpr() != nil { - t.Where = v.Visit(ctx.GetWhereExpr()).(tree.Expression) - } - - if ctx.GROUP_() != nil { - exprs := make([]tree.Expression, len(ctx.GetGroupByExpr())) - for i, exprCtx := range ctx.GetGroupByExpr() { - exprs[i] = v.Visit(exprCtx).(tree.Expression) - } - - groupBy := &tree.GroupBy{ - Expressions: exprs, - } - groupBy.Set(ctx) - - if ctx.HAVING_() != nil { - groupBy.Having = v.Visit(ctx.GetHavingExpr()).(tree.Expression) - } - - t.GroupBy = groupBy - } - - return &t -} - -// VisitRelation is called when visiting a relation, return tree.Relation -func (v *astBuilder) VisitRelation(ctx *grammar.RelationContext) interface{} { - left := v.Visit(ctx.Table_or_subquery()).(tree.Relation) - - if len(ctx.AllJoin_relation()) > 0 { - rel := tree.RelationJoin{ - Relation: left, - Joins: make([]*tree.JoinPredicate, len(ctx.AllJoin_relation())), - } - rel.Set(ctx) - // join relations - for i, joinRelationCtx := range ctx.AllJoin_relation() { - rel.Joins[i] = v.Visit(joinRelationCtx).(*tree.JoinPredicate) - } - return &rel - } else { - // table or subquery relation - return left - } -} - -// VisitSelect_core is called when visiting a select_stmt_core, return *tree.SelectCore -func (v *astBuilder) VisitSelect_core(ctx *grammar.Select_coreContext) interface{} { - t := tree.SelectCore{} - t.Set(ctx) - selectCores := make([]*tree.SimpleSelect, len(ctx.AllSimple_select())) - - // first Simple_select - selectCores[0] = v.Visit(ctx.Simple_select(0)).(*tree.SimpleSelect) - - // rest Simple_select - for i, selectCoreCtx := range ctx.AllSimple_select()[1:] { - compoundOperator := v.Visit(ctx.Compound_operator(i)).(*tree.CompoundOperator) - core := v.Visit(selectCoreCtx).(*tree.SimpleSelect) - core.Compound = compoundOperator - selectCores[i+1] = core - } - - t.SimpleSelects = selectCores - - if ctx.Order_by_stmt() != nil { - t.OrderBy = v.Visit(ctx.Order_by_stmt()).(*tree.OrderBy) - } - - if ctx.Limit_stmt() != nil { - t.Limit = v.Visit(ctx.Limit_stmt()).(*tree.Limit) - } - - return &t -} - -// VisitSelect_stmt is called when visiting a select_stmt, return *tree.SelectStmt -func (v *astBuilder) VisitSelect_stmt(ctx *grammar.Select_stmtContext) interface{} { - t := tree.SelectStmt{} - t.Set(ctx) - - if ctx.Common_table_stmt() != nil { - t.CTE = v.Visit(ctx.Common_table_stmt()).([]*tree.CTE) - } - - t.Stmt = v.Visit(ctx.Select_core()).(*tree.SelectCore) - return &t -} - -func (v *astBuilder) VisitSql_stmt_list(ctx *grammar.Sql_stmt_listContext) interface{} { - - res := make([]tree.AstNode, len(ctx.AllSql_stmt())) - for i, stmtCtx := range ctx.AllSql_stmt() { - res[i] = stmtCtx.Accept(v).(tree.AstNode) - } - - return v.VisitChildren(ctx) -} - -func (v *astBuilder) VisitSql_stmt(ctx *grammar.Sql_stmtContext) interface{} { - switch { - case ctx.Delete_stmt() != nil: - return ctx.Delete_stmt().Accept(v) - case ctx.Insert_stmt() != nil: - return ctx.Insert_stmt().Accept(v) - case ctx.Select_stmt() != nil: - return ctx.Select_stmt().Accept(v) - case ctx.Update_stmt() != nil: - return ctx.Update_stmt().Accept(v) - default: - str := ctx.GetText() - _ = str - panic("unsupported sql statement") - } -} - -// VisitStatements is called when visiting a statements, return []tree.AstNode -func (v *astBuilder) VisitStatements(ctx *grammar.StatementsContext) interface{} { - // ParseContext will only have one Sql_stmt_listContext - sqlStmtListContext := ctx.Sql_stmt_list(0) - - results := make([]tree.AstNode, len(sqlStmtListContext.AllSql_stmt())) - - for i, stmtCtx := range sqlStmtListContext.AllSql_stmt() { - results[i] = stmtCtx.Accept(v).(tree.AstNode) - } - - return results -} - -// Visit dispatch to the visit method of the ctx -// e.g. if the tree is a ParseContext, then dispatch call VisitParse. -// Overwrite is needed, -// refer to https://github.com/antlr/antlr4/pull/1841#issuecomment-576791512 -func (v *astBuilder) Visit(parseTree antlr.ParseTree) interface{} { - if v.trace { - fmt.Printf("visit tree: %v, %s\n", reflect.TypeOf(parseTree), parseTree.GetText()) - } - return parseTree.Accept(v) -} - -// VisitChildren visits the children of the specified node. -// Overwrite is needed, -// refer to https://github.com/antlr/antlr4/pull/1841#issuecomment-576791512 -// calling function need to convert the result to asts -func (v *astBuilder) VisitChildren(node antlr.RuleNode) interface{} { - var result []tree.AstNode - n := node.GetChildCount() - for i := 0; i < n; i++ { - child := node.GetChild(i) - if !v.shouldVisitNextChild(child, result) { - if v.trace { - fmt.Printf("should not visit next child: %v,\n", reflect.TypeOf(child)) - } - break - } - c := child.(antlr.ParseTree) - childResult := v.Visit(c).(tree.AstNode) - result = append(result, childResult) - } - return result -} - -func (v *astBuilder) shouldVisitNextChild(node antlr.Tree, currentResult interface{}) bool { - if _, ok := node.(antlr.TerminalNode); ok { - return false - } - - return true -} diff --git a/parse/sql/error.go b/parse/sql/error.go deleted file mode 100644 index 9c5211dd6..000000000 --- a/parse/sql/error.go +++ /dev/null @@ -1,10 +0,0 @@ -package sqlparser - -import ( - "errors" -) - -var ( - ErrTableNotFound = errors.New("table not found") - ErrColumnNotFound = errors.New("column not found") -) diff --git a/parse/sql/error_listener.go b/parse/sql/error_listener.go deleted file mode 100644 index 13d81154b..000000000 --- a/parse/sql/error_listener.go +++ /dev/null @@ -1,80 +0,0 @@ -package sqlparser - -import ( - "errors" - "fmt" - - "github.com/antlr4-go/antlr/v4" -) - -var ErrInvalidSyntax = errors.New("syntax error") - -type ErrorList []error - -func (e *ErrorList) Add(msg string) { - *e = append(*e, errors.New(msg)) -} - -func (e *ErrorList) AddError(err error) { - *e = append(*e, err) -} - -// Unwrap is used by the standard library's errors.Is function. -func (e ErrorList) Unwrap() []error { - return e -} - -var _ error = ErrorList{} -var _ error = (*ErrorList)(nil) - -// Error satisfies the standard library error interface. -func (e ErrorList) Error() string { - switch len(e) { - case 0: - return "no errors" - case 1: - return e[0].Error() - default: - return fmt.Sprintf("%s (with %d+ errors)", e[0], len(e)-1) - } -} - -func (e ErrorList) Err() error { - if len(e) == 0 { - return nil - } - return e -} - -type ErrorListener struct { - ErrorList -} - -var _ antlr.ErrorListener = &ErrorListener{} - -func NewErrorListener() *ErrorListener { - return &ErrorListener{ - ErrorList: ErrorList{}, - } -} - -func (l *ErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, - msg string, e antlr.RecognitionException) { - //symbol := offendingSymbol.(antlr.Token) - l.AddError(fmt.Errorf(`%w: line %d:%d "%s"`, ErrInvalidSyntax, line, column, msg)) -} - -func (l *ErrorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, - exact bool, ambigAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { - //l.ErrorHandler.Add(startIndex, errors.Wrap(ErrAmbiguity, "ambiguity")) -} - -func (l *ErrorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, - stopIndex int, conflictingAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { - //l.ErrorHandler.Add(startIndex, errors.Wrap(ErrAttemptingFullContext, "attempting full context")) -} - -func (l *ErrorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, - prediction int, configs *antlr.ATNConfigSet) { - //l.ErrorHandler.Add(startIndex, errors.Wrap(ErrContextSensitivity, "context sensitivity")) -} diff --git a/parse/sql/gen/sql_lexer.go b/parse/sql/gen/sql_lexer.go deleted file mode 100644 index b3a35d97b..000000000 --- a/parse/sql/gen/sql_lexer.go +++ /dev/null @@ -1,553 +0,0 @@ -// Code generated from SQLLexer.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package sqlgrammar - -import ( - "fmt" - "github.com/antlr4-go/antlr/v4" - "sync" - "unicode" -) - -// Suppress unused import error -var _ = fmt.Printf -var _ = sync.Once{} -var _ = unicode.IsLetter - -type SQLLexer struct { - *antlr.BaseLexer - channelNames []string - modeNames []string - // TODO: EOF string -} - -var SQLLexerLexerStaticData struct { - once sync.Once - serializedATN []int32 - ChannelNames []string - ModeNames []string - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func sqllexerLexerInit() { - staticData := &SQLLexerLexerStaticData - staticData.ChannelNames = []string{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN", - } - staticData.ModeNames = []string{ - "DEFAULT_MODE", - } - staticData.LiteralNames = []string{ - "", "';'", "'.'", "'('", "')'", "'['", "']'", "','", "'='", "'*'", "'+'", - "'-'", "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'<>'", "'::'", - "'ADD'", "'ALL'", "'AND'", "'ASC'", "'AS'", "'BETWEEN'", "'BY'", "'CASE'", - "'COLLATE'", "'COMMIT'", "'CONFLICT'", "'CREATE'", "'CROSS'", "'DEFAULT'", - "'DELETE'", "'DESC'", "'DISTINCT'", "'DO'", "'ELSE'", "'END'", "'ESCAPE'", - "'EXCEPT'", "'EXISTS'", "'FILTER'", "'FIRST'", "'FROM'", "'FULL'", "'GROUPS'", - "'GROUP'", "'HAVING'", "'INNER'", "'INSERT'", "'INTERSECT'", "'INTO'", - "'IN'", "'ISNULL'", "'IS'", "'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", - "'LIMIT'", "'NOTHING'", "'NOTNULL'", "'NOT'", "'NULLS'", "'OFFSET'", - "'OF'", "'ON'", "'ORDER'", "'OR'", "'OUTER'", "'RAISE'", "'REPLACE'", - "'RETURNING'", "'RIGHT'", "'SELECT'", "'SET'", "'THEN'", "'UNION'", - "'UPDATE'", "'USING'", "'VALUES'", "'WHEN'", "'WHERE'", "'WITH'", "", - "", "", "", "'null'", - } - staticData.SymbolicNames = []string{ - "", "SCOL", "DOT", "OPEN_PAR", "CLOSE_PAR", "L_BRACKET", "R_BRACKET", - "COMMA", "ASSIGN", "STAR", "PLUS", "MINUS", "DIV", "MOD", "LT", "LT_EQ", - "GT", "GT_EQ", "NOT_EQ1", "NOT_EQ2", "TYPE_CAST", "ADD_", "ALL_", "AND_", - "ASC_", "AS_", "BETWEEN_", "BY_", "CASE_", "COLLATE_", "COMMIT_", "CONFLICT_", - "CREATE_", "CROSS_", "DEFAULT_", "DELETE_", "DESC_", "DISTINCT_", "DO_", - "ELSE_", "END_", "ESCAPE_", "EXCEPT_", "EXISTS_", "FILTER_", "FIRST_", - "FROM_", "FULL_", "GROUPS_", "GROUP_", "HAVING_", "INNER_", "INSERT_", - "INTERSECT_", "INTO_", "IN_", "ISNULL_", "IS_", "JOIN_", "LAST_", "LEFT_", - "LIKE_", "LIMIT_", "NOTHING_", "NOTNULL_", "NOT_", "NULLS_", "OFFSET_", - "OF_", "ON_", "ORDER_", "OR_", "OUTER_", "RAISE_", "REPLACE_", "RETURNING_", - "RIGHT_", "SELECT_", "SET_", "THEN_", "UNION_", "UPDATE_", "USING_", - "VALUES_", "WHEN_", "WHERE_", "WITH_", "BOOLEAN_LITERAL", "NUMERIC_LITERAL", - "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", "BIND_PARAMETER", - "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", - } - staticData.RuleNames = []string{ - "SCOL", "DOT", "OPEN_PAR", "CLOSE_PAR", "L_BRACKET", "R_BRACKET", "COMMA", - "ASSIGN", "STAR", "PLUS", "MINUS", "DIV", "MOD", "LT", "LT_EQ", "GT", - "GT_EQ", "NOT_EQ1", "NOT_EQ2", "TYPE_CAST", "ADD_", "ALL_", "AND_", - "ASC_", "AS_", "BETWEEN_", "BY_", "CASE_", "COLLATE_", "COMMIT_", "CONFLICT_", - "CREATE_", "CROSS_", "DEFAULT_", "DELETE_", "DESC_", "DISTINCT_", "DO_", - "ELSE_", "END_", "ESCAPE_", "EXCEPT_", "EXISTS_", "FILTER_", "FIRST_", - "FROM_", "FULL_", "GROUPS_", "GROUP_", "HAVING_", "INNER_", "INSERT_", - "INTERSECT_", "INTO_", "IN_", "ISNULL_", "IS_", "JOIN_", "LAST_", "LEFT_", - "LIKE_", "LIMIT_", "NOTHING_", "NOTNULL_", "NOT_", "NULLS_", "OFFSET_", - "OF_", "ON_", "ORDER_", "OR_", "OUTER_", "RAISE_", "REPLACE_", "RETURNING_", - "RIGHT_", "SELECT_", "SET_", "THEN_", "UNION_", "UPDATE_", "USING_", - "VALUES_", "WHEN_", "WHERE_", "WITH_", "BOOLEAN_LITERAL", "NUMERIC_LITERAL", - "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", "BIND_PARAMETER", - "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 0, 97, 736, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, - 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, - 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, - 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, - 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, - 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, - 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, - 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, - 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, - 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, - 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, - 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, - 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, - 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, - 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, - 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, - 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, - 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, - 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, - 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, - 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, - 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, - 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, - 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, - 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, - 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, - 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, - 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, - 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, - 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, - 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, - 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, - 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, - 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, - 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, - 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, - 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, - 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, - 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, - 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, - 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, - 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, - 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, - 1, 55, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, - 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, - 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, - 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, - 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, - 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, - 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, - 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, - 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, - 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, - 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, - 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, - 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, - 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, - 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, - 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, - 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, - 86, 1, 86, 1, 86, 3, 86, 636, 8, 86, 1, 87, 4, 87, 639, 8, 87, 11, 87, - 12, 87, 640, 1, 88, 1, 88, 1, 88, 1, 88, 4, 88, 647, 8, 88, 11, 88, 12, - 88, 648, 1, 89, 1, 89, 1, 89, 1, 89, 5, 89, 655, 8, 89, 10, 89, 12, 89, - 658, 9, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, - 91, 1, 91, 1, 91, 5, 91, 671, 8, 91, 10, 91, 12, 91, 674, 9, 91, 1, 91, - 1, 91, 1, 91, 1, 91, 1, 91, 5, 91, 681, 8, 91, 10, 91, 12, 91, 684, 9, - 91, 1, 91, 1, 91, 1, 91, 5, 91, 689, 8, 91, 10, 91, 12, 91, 692, 9, 91, - 3, 91, 694, 8, 91, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 5, - 93, 703, 8, 93, 10, 93, 12, 93, 706, 9, 93, 1, 93, 3, 93, 709, 8, 93, 1, - 93, 1, 93, 3, 93, 713, 8, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, - 5, 94, 721, 8, 94, 10, 94, 12, 94, 724, 9, 94, 1, 94, 1, 94, 1, 94, 1, - 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 722, 0, 97, 1, - 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, - 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, - 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, - 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, - 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, - 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, - 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, - 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, - 72, 145, 73, 147, 74, 149, 75, 151, 76, 153, 77, 155, 78, 157, 79, 159, - 80, 161, 81, 163, 82, 165, 83, 167, 84, 169, 85, 171, 86, 173, 87, 175, - 88, 177, 89, 179, 90, 181, 91, 183, 92, 185, 93, 187, 94, 189, 95, 191, - 96, 193, 97, 1, 0, 34, 2, 0, 65, 65, 97, 97, 2, 0, 68, 68, 100, 100, 2, - 0, 76, 76, 108, 108, 2, 0, 78, 78, 110, 110, 2, 0, 83, 83, 115, 115, 2, - 0, 67, 67, 99, 99, 2, 0, 66, 66, 98, 98, 2, 0, 69, 69, 101, 101, 2, 0, - 84, 84, 116, 116, 2, 0, 87, 87, 119, 119, 2, 0, 89, 89, 121, 121, 2, 0, - 79, 79, 111, 111, 2, 0, 77, 77, 109, 109, 2, 0, 73, 73, 105, 105, 2, 0, - 70, 70, 102, 102, 2, 0, 82, 82, 114, 114, 2, 0, 85, 85, 117, 117, 2, 0, - 80, 80, 112, 112, 2, 0, 88, 88, 120, 120, 2, 0, 71, 71, 103, 103, 2, 0, - 72, 72, 104, 104, 2, 0, 86, 86, 118, 118, 2, 0, 74, 74, 106, 106, 2, 0, - 75, 75, 107, 107, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 1, 0, 39, - 39, 1, 0, 34, 34, 1, 0, 96, 96, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, - 57, 65, 90, 95, 95, 97, 122, 2, 0, 36, 36, 64, 64, 2, 0, 10, 10, 13, 13, - 3, 0, 9, 11, 13, 13, 32, 32, 751, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, - 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, - 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, - 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, - 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, - 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, - 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, - 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, - 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, - 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, - 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, - 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, - 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, - 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, - 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, - 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, - 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, - 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, - 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, - 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, - 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, 0, 0, - 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0, - 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 0, 169, - 1, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 173, 1, 0, 0, 0, 0, 175, 1, 0, 0, 0, - 0, 177, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 0, 183, 1, - 0, 0, 0, 0, 185, 1, 0, 0, 0, 0, 187, 1, 0, 0, 0, 0, 189, 1, 0, 0, 0, 0, - 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 1, 195, 1, 0, 0, 0, 3, 197, 1, 0, - 0, 0, 5, 199, 1, 0, 0, 0, 7, 201, 1, 0, 0, 0, 9, 203, 1, 0, 0, 0, 11, 205, - 1, 0, 0, 0, 13, 207, 1, 0, 0, 0, 15, 209, 1, 0, 0, 0, 17, 211, 1, 0, 0, - 0, 19, 213, 1, 0, 0, 0, 21, 215, 1, 0, 0, 0, 23, 217, 1, 0, 0, 0, 25, 219, - 1, 0, 0, 0, 27, 221, 1, 0, 0, 0, 29, 223, 1, 0, 0, 0, 31, 226, 1, 0, 0, - 0, 33, 228, 1, 0, 0, 0, 35, 231, 1, 0, 0, 0, 37, 234, 1, 0, 0, 0, 39, 237, - 1, 0, 0, 0, 41, 240, 1, 0, 0, 0, 43, 244, 1, 0, 0, 0, 45, 248, 1, 0, 0, - 0, 47, 252, 1, 0, 0, 0, 49, 256, 1, 0, 0, 0, 51, 259, 1, 0, 0, 0, 53, 267, - 1, 0, 0, 0, 55, 270, 1, 0, 0, 0, 57, 275, 1, 0, 0, 0, 59, 283, 1, 0, 0, - 0, 61, 290, 1, 0, 0, 0, 63, 299, 1, 0, 0, 0, 65, 306, 1, 0, 0, 0, 67, 312, - 1, 0, 0, 0, 69, 320, 1, 0, 0, 0, 71, 327, 1, 0, 0, 0, 73, 332, 1, 0, 0, - 0, 75, 341, 1, 0, 0, 0, 77, 344, 1, 0, 0, 0, 79, 349, 1, 0, 0, 0, 81, 353, - 1, 0, 0, 0, 83, 360, 1, 0, 0, 0, 85, 367, 1, 0, 0, 0, 87, 374, 1, 0, 0, - 0, 89, 381, 1, 0, 0, 0, 91, 387, 1, 0, 0, 0, 93, 392, 1, 0, 0, 0, 95, 397, - 1, 0, 0, 0, 97, 404, 1, 0, 0, 0, 99, 410, 1, 0, 0, 0, 101, 417, 1, 0, 0, - 0, 103, 423, 1, 0, 0, 0, 105, 430, 1, 0, 0, 0, 107, 440, 1, 0, 0, 0, 109, - 445, 1, 0, 0, 0, 111, 448, 1, 0, 0, 0, 113, 455, 1, 0, 0, 0, 115, 458, - 1, 0, 0, 0, 117, 463, 1, 0, 0, 0, 119, 468, 1, 0, 0, 0, 121, 473, 1, 0, - 0, 0, 123, 478, 1, 0, 0, 0, 125, 484, 1, 0, 0, 0, 127, 492, 1, 0, 0, 0, - 129, 500, 1, 0, 0, 0, 131, 504, 1, 0, 0, 0, 133, 510, 1, 0, 0, 0, 135, - 517, 1, 0, 0, 0, 137, 520, 1, 0, 0, 0, 139, 523, 1, 0, 0, 0, 141, 529, - 1, 0, 0, 0, 143, 532, 1, 0, 0, 0, 145, 538, 1, 0, 0, 0, 147, 544, 1, 0, - 0, 0, 149, 552, 1, 0, 0, 0, 151, 562, 1, 0, 0, 0, 153, 568, 1, 0, 0, 0, - 155, 575, 1, 0, 0, 0, 157, 579, 1, 0, 0, 0, 159, 584, 1, 0, 0, 0, 161, - 590, 1, 0, 0, 0, 163, 597, 1, 0, 0, 0, 165, 603, 1, 0, 0, 0, 167, 610, - 1, 0, 0, 0, 169, 615, 1, 0, 0, 0, 171, 621, 1, 0, 0, 0, 173, 635, 1, 0, - 0, 0, 175, 638, 1, 0, 0, 0, 177, 642, 1, 0, 0, 0, 179, 650, 1, 0, 0, 0, - 181, 661, 1, 0, 0, 0, 183, 693, 1, 0, 0, 0, 185, 695, 1, 0, 0, 0, 187, - 698, 1, 0, 0, 0, 189, 716, 1, 0, 0, 0, 191, 730, 1, 0, 0, 0, 193, 734, - 1, 0, 0, 0, 195, 196, 5, 59, 0, 0, 196, 2, 1, 0, 0, 0, 197, 198, 5, 46, - 0, 0, 198, 4, 1, 0, 0, 0, 199, 200, 5, 40, 0, 0, 200, 6, 1, 0, 0, 0, 201, - 202, 5, 41, 0, 0, 202, 8, 1, 0, 0, 0, 203, 204, 5, 91, 0, 0, 204, 10, 1, - 0, 0, 0, 205, 206, 5, 93, 0, 0, 206, 12, 1, 0, 0, 0, 207, 208, 5, 44, 0, - 0, 208, 14, 1, 0, 0, 0, 209, 210, 5, 61, 0, 0, 210, 16, 1, 0, 0, 0, 211, - 212, 5, 42, 0, 0, 212, 18, 1, 0, 0, 0, 213, 214, 5, 43, 0, 0, 214, 20, - 1, 0, 0, 0, 215, 216, 5, 45, 0, 0, 216, 22, 1, 0, 0, 0, 217, 218, 5, 47, - 0, 0, 218, 24, 1, 0, 0, 0, 219, 220, 5, 37, 0, 0, 220, 26, 1, 0, 0, 0, - 221, 222, 5, 60, 0, 0, 222, 28, 1, 0, 0, 0, 223, 224, 5, 60, 0, 0, 224, - 225, 5, 61, 0, 0, 225, 30, 1, 0, 0, 0, 226, 227, 5, 62, 0, 0, 227, 32, - 1, 0, 0, 0, 228, 229, 5, 62, 0, 0, 229, 230, 5, 61, 0, 0, 230, 34, 1, 0, - 0, 0, 231, 232, 5, 33, 0, 0, 232, 233, 5, 61, 0, 0, 233, 36, 1, 0, 0, 0, - 234, 235, 5, 60, 0, 0, 235, 236, 5, 62, 0, 0, 236, 38, 1, 0, 0, 0, 237, - 238, 5, 58, 0, 0, 238, 239, 5, 58, 0, 0, 239, 40, 1, 0, 0, 0, 240, 241, - 7, 0, 0, 0, 241, 242, 7, 1, 0, 0, 242, 243, 7, 1, 0, 0, 243, 42, 1, 0, - 0, 0, 244, 245, 7, 0, 0, 0, 245, 246, 7, 2, 0, 0, 246, 247, 7, 2, 0, 0, - 247, 44, 1, 0, 0, 0, 248, 249, 7, 0, 0, 0, 249, 250, 7, 3, 0, 0, 250, 251, - 7, 1, 0, 0, 251, 46, 1, 0, 0, 0, 252, 253, 7, 0, 0, 0, 253, 254, 7, 4, - 0, 0, 254, 255, 7, 5, 0, 0, 255, 48, 1, 0, 0, 0, 256, 257, 7, 0, 0, 0, - 257, 258, 7, 4, 0, 0, 258, 50, 1, 0, 0, 0, 259, 260, 7, 6, 0, 0, 260, 261, - 7, 7, 0, 0, 261, 262, 7, 8, 0, 0, 262, 263, 7, 9, 0, 0, 263, 264, 7, 7, - 0, 0, 264, 265, 7, 7, 0, 0, 265, 266, 7, 3, 0, 0, 266, 52, 1, 0, 0, 0, - 267, 268, 7, 6, 0, 0, 268, 269, 7, 10, 0, 0, 269, 54, 1, 0, 0, 0, 270, - 271, 7, 5, 0, 0, 271, 272, 7, 0, 0, 0, 272, 273, 7, 4, 0, 0, 273, 274, - 7, 7, 0, 0, 274, 56, 1, 0, 0, 0, 275, 276, 7, 5, 0, 0, 276, 277, 7, 11, - 0, 0, 277, 278, 7, 2, 0, 0, 278, 279, 7, 2, 0, 0, 279, 280, 7, 0, 0, 0, - 280, 281, 7, 8, 0, 0, 281, 282, 7, 7, 0, 0, 282, 58, 1, 0, 0, 0, 283, 284, - 7, 5, 0, 0, 284, 285, 7, 11, 0, 0, 285, 286, 7, 12, 0, 0, 286, 287, 7, - 12, 0, 0, 287, 288, 7, 13, 0, 0, 288, 289, 7, 8, 0, 0, 289, 60, 1, 0, 0, - 0, 290, 291, 7, 5, 0, 0, 291, 292, 7, 11, 0, 0, 292, 293, 7, 3, 0, 0, 293, - 294, 7, 14, 0, 0, 294, 295, 7, 2, 0, 0, 295, 296, 7, 13, 0, 0, 296, 297, - 7, 5, 0, 0, 297, 298, 7, 8, 0, 0, 298, 62, 1, 0, 0, 0, 299, 300, 7, 5, - 0, 0, 300, 301, 7, 15, 0, 0, 301, 302, 7, 7, 0, 0, 302, 303, 7, 0, 0, 0, - 303, 304, 7, 8, 0, 0, 304, 305, 7, 7, 0, 0, 305, 64, 1, 0, 0, 0, 306, 307, - 7, 5, 0, 0, 307, 308, 7, 15, 0, 0, 308, 309, 7, 11, 0, 0, 309, 310, 7, - 4, 0, 0, 310, 311, 7, 4, 0, 0, 311, 66, 1, 0, 0, 0, 312, 313, 7, 1, 0, - 0, 313, 314, 7, 7, 0, 0, 314, 315, 7, 14, 0, 0, 315, 316, 7, 0, 0, 0, 316, - 317, 7, 16, 0, 0, 317, 318, 7, 2, 0, 0, 318, 319, 7, 8, 0, 0, 319, 68, - 1, 0, 0, 0, 320, 321, 7, 1, 0, 0, 321, 322, 7, 7, 0, 0, 322, 323, 7, 2, - 0, 0, 323, 324, 7, 7, 0, 0, 324, 325, 7, 8, 0, 0, 325, 326, 7, 7, 0, 0, - 326, 70, 1, 0, 0, 0, 327, 328, 7, 1, 0, 0, 328, 329, 7, 7, 0, 0, 329, 330, - 7, 4, 0, 0, 330, 331, 7, 5, 0, 0, 331, 72, 1, 0, 0, 0, 332, 333, 7, 1, - 0, 0, 333, 334, 7, 13, 0, 0, 334, 335, 7, 4, 0, 0, 335, 336, 7, 8, 0, 0, - 336, 337, 7, 13, 0, 0, 337, 338, 7, 3, 0, 0, 338, 339, 7, 5, 0, 0, 339, - 340, 7, 8, 0, 0, 340, 74, 1, 0, 0, 0, 341, 342, 7, 1, 0, 0, 342, 343, 7, - 11, 0, 0, 343, 76, 1, 0, 0, 0, 344, 345, 7, 7, 0, 0, 345, 346, 7, 2, 0, - 0, 346, 347, 7, 4, 0, 0, 347, 348, 7, 7, 0, 0, 348, 78, 1, 0, 0, 0, 349, - 350, 7, 7, 0, 0, 350, 351, 7, 3, 0, 0, 351, 352, 7, 1, 0, 0, 352, 80, 1, - 0, 0, 0, 353, 354, 7, 7, 0, 0, 354, 355, 7, 4, 0, 0, 355, 356, 7, 5, 0, - 0, 356, 357, 7, 0, 0, 0, 357, 358, 7, 17, 0, 0, 358, 359, 7, 7, 0, 0, 359, - 82, 1, 0, 0, 0, 360, 361, 7, 7, 0, 0, 361, 362, 7, 18, 0, 0, 362, 363, - 7, 5, 0, 0, 363, 364, 7, 7, 0, 0, 364, 365, 7, 17, 0, 0, 365, 366, 7, 8, - 0, 0, 366, 84, 1, 0, 0, 0, 367, 368, 7, 7, 0, 0, 368, 369, 7, 18, 0, 0, - 369, 370, 7, 13, 0, 0, 370, 371, 7, 4, 0, 0, 371, 372, 7, 8, 0, 0, 372, - 373, 7, 4, 0, 0, 373, 86, 1, 0, 0, 0, 374, 375, 7, 14, 0, 0, 375, 376, - 7, 13, 0, 0, 376, 377, 7, 2, 0, 0, 377, 378, 7, 8, 0, 0, 378, 379, 7, 7, - 0, 0, 379, 380, 7, 15, 0, 0, 380, 88, 1, 0, 0, 0, 381, 382, 7, 14, 0, 0, - 382, 383, 7, 13, 0, 0, 383, 384, 7, 15, 0, 0, 384, 385, 7, 4, 0, 0, 385, - 386, 7, 8, 0, 0, 386, 90, 1, 0, 0, 0, 387, 388, 7, 14, 0, 0, 388, 389, - 7, 15, 0, 0, 389, 390, 7, 11, 0, 0, 390, 391, 7, 12, 0, 0, 391, 92, 1, - 0, 0, 0, 392, 393, 7, 14, 0, 0, 393, 394, 7, 16, 0, 0, 394, 395, 7, 2, - 0, 0, 395, 396, 7, 2, 0, 0, 396, 94, 1, 0, 0, 0, 397, 398, 7, 19, 0, 0, - 398, 399, 7, 15, 0, 0, 399, 400, 7, 11, 0, 0, 400, 401, 7, 16, 0, 0, 401, - 402, 7, 17, 0, 0, 402, 403, 7, 4, 0, 0, 403, 96, 1, 0, 0, 0, 404, 405, - 7, 19, 0, 0, 405, 406, 7, 15, 0, 0, 406, 407, 7, 11, 0, 0, 407, 408, 7, - 16, 0, 0, 408, 409, 7, 17, 0, 0, 409, 98, 1, 0, 0, 0, 410, 411, 7, 20, - 0, 0, 411, 412, 7, 0, 0, 0, 412, 413, 7, 21, 0, 0, 413, 414, 7, 13, 0, - 0, 414, 415, 7, 3, 0, 0, 415, 416, 7, 19, 0, 0, 416, 100, 1, 0, 0, 0, 417, - 418, 7, 13, 0, 0, 418, 419, 7, 3, 0, 0, 419, 420, 7, 3, 0, 0, 420, 421, - 7, 7, 0, 0, 421, 422, 7, 15, 0, 0, 422, 102, 1, 0, 0, 0, 423, 424, 7, 13, - 0, 0, 424, 425, 7, 3, 0, 0, 425, 426, 7, 4, 0, 0, 426, 427, 7, 7, 0, 0, - 427, 428, 7, 15, 0, 0, 428, 429, 7, 8, 0, 0, 429, 104, 1, 0, 0, 0, 430, - 431, 7, 13, 0, 0, 431, 432, 7, 3, 0, 0, 432, 433, 7, 8, 0, 0, 433, 434, - 7, 7, 0, 0, 434, 435, 7, 15, 0, 0, 435, 436, 7, 4, 0, 0, 436, 437, 7, 7, - 0, 0, 437, 438, 7, 5, 0, 0, 438, 439, 7, 8, 0, 0, 439, 106, 1, 0, 0, 0, - 440, 441, 7, 13, 0, 0, 441, 442, 7, 3, 0, 0, 442, 443, 7, 8, 0, 0, 443, - 444, 7, 11, 0, 0, 444, 108, 1, 0, 0, 0, 445, 446, 7, 13, 0, 0, 446, 447, - 7, 3, 0, 0, 447, 110, 1, 0, 0, 0, 448, 449, 7, 13, 0, 0, 449, 450, 7, 4, - 0, 0, 450, 451, 7, 3, 0, 0, 451, 452, 7, 16, 0, 0, 452, 453, 7, 2, 0, 0, - 453, 454, 7, 2, 0, 0, 454, 112, 1, 0, 0, 0, 455, 456, 7, 13, 0, 0, 456, - 457, 7, 4, 0, 0, 457, 114, 1, 0, 0, 0, 458, 459, 7, 22, 0, 0, 459, 460, - 7, 11, 0, 0, 460, 461, 7, 13, 0, 0, 461, 462, 7, 3, 0, 0, 462, 116, 1, - 0, 0, 0, 463, 464, 7, 2, 0, 0, 464, 465, 7, 0, 0, 0, 465, 466, 7, 4, 0, - 0, 466, 467, 7, 8, 0, 0, 467, 118, 1, 0, 0, 0, 468, 469, 7, 2, 0, 0, 469, - 470, 7, 7, 0, 0, 470, 471, 7, 14, 0, 0, 471, 472, 7, 8, 0, 0, 472, 120, - 1, 0, 0, 0, 473, 474, 7, 2, 0, 0, 474, 475, 7, 13, 0, 0, 475, 476, 7, 23, - 0, 0, 476, 477, 7, 7, 0, 0, 477, 122, 1, 0, 0, 0, 478, 479, 7, 2, 0, 0, - 479, 480, 7, 13, 0, 0, 480, 481, 7, 12, 0, 0, 481, 482, 7, 13, 0, 0, 482, - 483, 7, 8, 0, 0, 483, 124, 1, 0, 0, 0, 484, 485, 7, 3, 0, 0, 485, 486, - 7, 11, 0, 0, 486, 487, 7, 8, 0, 0, 487, 488, 7, 20, 0, 0, 488, 489, 7, - 13, 0, 0, 489, 490, 7, 3, 0, 0, 490, 491, 7, 19, 0, 0, 491, 126, 1, 0, - 0, 0, 492, 493, 7, 3, 0, 0, 493, 494, 7, 11, 0, 0, 494, 495, 7, 8, 0, 0, - 495, 496, 7, 3, 0, 0, 496, 497, 7, 16, 0, 0, 497, 498, 7, 2, 0, 0, 498, - 499, 7, 2, 0, 0, 499, 128, 1, 0, 0, 0, 500, 501, 7, 3, 0, 0, 501, 502, - 7, 11, 0, 0, 502, 503, 7, 8, 0, 0, 503, 130, 1, 0, 0, 0, 504, 505, 7, 3, - 0, 0, 505, 506, 7, 16, 0, 0, 506, 507, 7, 2, 0, 0, 507, 508, 7, 2, 0, 0, - 508, 509, 7, 4, 0, 0, 509, 132, 1, 0, 0, 0, 510, 511, 7, 11, 0, 0, 511, - 512, 7, 14, 0, 0, 512, 513, 7, 14, 0, 0, 513, 514, 7, 4, 0, 0, 514, 515, - 7, 7, 0, 0, 515, 516, 7, 8, 0, 0, 516, 134, 1, 0, 0, 0, 517, 518, 7, 11, - 0, 0, 518, 519, 7, 14, 0, 0, 519, 136, 1, 0, 0, 0, 520, 521, 7, 11, 0, - 0, 521, 522, 7, 3, 0, 0, 522, 138, 1, 0, 0, 0, 523, 524, 7, 11, 0, 0, 524, - 525, 7, 15, 0, 0, 525, 526, 7, 1, 0, 0, 526, 527, 7, 7, 0, 0, 527, 528, - 7, 15, 0, 0, 528, 140, 1, 0, 0, 0, 529, 530, 7, 11, 0, 0, 530, 531, 7, - 15, 0, 0, 531, 142, 1, 0, 0, 0, 532, 533, 7, 11, 0, 0, 533, 534, 7, 16, - 0, 0, 534, 535, 7, 8, 0, 0, 535, 536, 7, 7, 0, 0, 536, 537, 7, 15, 0, 0, - 537, 144, 1, 0, 0, 0, 538, 539, 7, 15, 0, 0, 539, 540, 7, 0, 0, 0, 540, - 541, 7, 13, 0, 0, 541, 542, 7, 4, 0, 0, 542, 543, 7, 7, 0, 0, 543, 146, - 1, 0, 0, 0, 544, 545, 7, 15, 0, 0, 545, 546, 7, 7, 0, 0, 546, 547, 7, 17, - 0, 0, 547, 548, 7, 2, 0, 0, 548, 549, 7, 0, 0, 0, 549, 550, 7, 5, 0, 0, - 550, 551, 7, 7, 0, 0, 551, 148, 1, 0, 0, 0, 552, 553, 7, 15, 0, 0, 553, - 554, 7, 7, 0, 0, 554, 555, 7, 8, 0, 0, 555, 556, 7, 16, 0, 0, 556, 557, - 7, 15, 0, 0, 557, 558, 7, 3, 0, 0, 558, 559, 7, 13, 0, 0, 559, 560, 7, - 3, 0, 0, 560, 561, 7, 19, 0, 0, 561, 150, 1, 0, 0, 0, 562, 563, 7, 15, - 0, 0, 563, 564, 7, 13, 0, 0, 564, 565, 7, 19, 0, 0, 565, 566, 7, 20, 0, - 0, 566, 567, 7, 8, 0, 0, 567, 152, 1, 0, 0, 0, 568, 569, 7, 4, 0, 0, 569, - 570, 7, 7, 0, 0, 570, 571, 7, 2, 0, 0, 571, 572, 7, 7, 0, 0, 572, 573, - 7, 5, 0, 0, 573, 574, 7, 8, 0, 0, 574, 154, 1, 0, 0, 0, 575, 576, 7, 4, - 0, 0, 576, 577, 7, 7, 0, 0, 577, 578, 7, 8, 0, 0, 578, 156, 1, 0, 0, 0, - 579, 580, 7, 8, 0, 0, 580, 581, 7, 20, 0, 0, 581, 582, 7, 7, 0, 0, 582, - 583, 7, 3, 0, 0, 583, 158, 1, 0, 0, 0, 584, 585, 7, 16, 0, 0, 585, 586, - 7, 3, 0, 0, 586, 587, 7, 13, 0, 0, 587, 588, 7, 11, 0, 0, 588, 589, 7, - 3, 0, 0, 589, 160, 1, 0, 0, 0, 590, 591, 7, 16, 0, 0, 591, 592, 7, 17, - 0, 0, 592, 593, 7, 1, 0, 0, 593, 594, 7, 0, 0, 0, 594, 595, 7, 8, 0, 0, - 595, 596, 7, 7, 0, 0, 596, 162, 1, 0, 0, 0, 597, 598, 7, 16, 0, 0, 598, - 599, 7, 4, 0, 0, 599, 600, 7, 13, 0, 0, 600, 601, 7, 3, 0, 0, 601, 602, - 7, 19, 0, 0, 602, 164, 1, 0, 0, 0, 603, 604, 7, 21, 0, 0, 604, 605, 7, - 0, 0, 0, 605, 606, 7, 2, 0, 0, 606, 607, 7, 16, 0, 0, 607, 608, 7, 7, 0, - 0, 608, 609, 7, 4, 0, 0, 609, 166, 1, 0, 0, 0, 610, 611, 7, 9, 0, 0, 611, - 612, 7, 20, 0, 0, 612, 613, 7, 7, 0, 0, 613, 614, 7, 3, 0, 0, 614, 168, - 1, 0, 0, 0, 615, 616, 7, 9, 0, 0, 616, 617, 7, 20, 0, 0, 617, 618, 7, 7, - 0, 0, 618, 619, 7, 15, 0, 0, 619, 620, 7, 7, 0, 0, 620, 170, 1, 0, 0, 0, - 621, 622, 7, 9, 0, 0, 622, 623, 7, 13, 0, 0, 623, 624, 7, 8, 0, 0, 624, - 625, 7, 20, 0, 0, 625, 172, 1, 0, 0, 0, 626, 627, 7, 8, 0, 0, 627, 628, - 7, 15, 0, 0, 628, 629, 7, 16, 0, 0, 629, 636, 7, 7, 0, 0, 630, 631, 7, - 14, 0, 0, 631, 632, 7, 0, 0, 0, 632, 633, 7, 2, 0, 0, 633, 634, 7, 4, 0, - 0, 634, 636, 7, 7, 0, 0, 635, 626, 1, 0, 0, 0, 635, 630, 1, 0, 0, 0, 636, - 174, 1, 0, 0, 0, 637, 639, 7, 24, 0, 0, 638, 637, 1, 0, 0, 0, 639, 640, - 1, 0, 0, 0, 640, 638, 1, 0, 0, 0, 640, 641, 1, 0, 0, 0, 641, 176, 1, 0, - 0, 0, 642, 643, 5, 48, 0, 0, 643, 644, 7, 18, 0, 0, 644, 646, 1, 0, 0, - 0, 645, 647, 7, 25, 0, 0, 646, 645, 1, 0, 0, 0, 647, 648, 1, 0, 0, 0, 648, - 646, 1, 0, 0, 0, 648, 649, 1, 0, 0, 0, 649, 178, 1, 0, 0, 0, 650, 656, - 5, 39, 0, 0, 651, 655, 8, 26, 0, 0, 652, 653, 5, 39, 0, 0, 653, 655, 5, - 39, 0, 0, 654, 651, 1, 0, 0, 0, 654, 652, 1, 0, 0, 0, 655, 658, 1, 0, 0, - 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, - 656, 1, 0, 0, 0, 659, 660, 5, 39, 0, 0, 660, 180, 1, 0, 0, 0, 661, 662, - 7, 3, 0, 0, 662, 663, 7, 16, 0, 0, 663, 664, 7, 2, 0, 0, 664, 665, 7, 2, - 0, 0, 665, 182, 1, 0, 0, 0, 666, 672, 5, 34, 0, 0, 667, 671, 8, 27, 0, - 0, 668, 669, 5, 34, 0, 0, 669, 671, 5, 34, 0, 0, 670, 667, 1, 0, 0, 0, - 670, 668, 1, 0, 0, 0, 671, 674, 1, 0, 0, 0, 672, 670, 1, 0, 0, 0, 672, - 673, 1, 0, 0, 0, 673, 675, 1, 0, 0, 0, 674, 672, 1, 0, 0, 0, 675, 694, - 5, 34, 0, 0, 676, 682, 5, 96, 0, 0, 677, 681, 8, 28, 0, 0, 678, 679, 5, - 96, 0, 0, 679, 681, 5, 96, 0, 0, 680, 677, 1, 0, 0, 0, 680, 678, 1, 0, - 0, 0, 681, 684, 1, 0, 0, 0, 682, 680, 1, 0, 0, 0, 682, 683, 1, 0, 0, 0, - 683, 685, 1, 0, 0, 0, 684, 682, 1, 0, 0, 0, 685, 694, 5, 96, 0, 0, 686, - 690, 7, 29, 0, 0, 687, 689, 7, 30, 0, 0, 688, 687, 1, 0, 0, 0, 689, 692, - 1, 0, 0, 0, 690, 688, 1, 0, 0, 0, 690, 691, 1, 0, 0, 0, 691, 694, 1, 0, - 0, 0, 692, 690, 1, 0, 0, 0, 693, 666, 1, 0, 0, 0, 693, 676, 1, 0, 0, 0, - 693, 686, 1, 0, 0, 0, 694, 184, 1, 0, 0, 0, 695, 696, 7, 31, 0, 0, 696, - 697, 3, 183, 91, 0, 697, 186, 1, 0, 0, 0, 698, 699, 5, 45, 0, 0, 699, 700, - 5, 45, 0, 0, 700, 704, 1, 0, 0, 0, 701, 703, 8, 32, 0, 0, 702, 701, 1, - 0, 0, 0, 703, 706, 1, 0, 0, 0, 704, 702, 1, 0, 0, 0, 704, 705, 1, 0, 0, - 0, 705, 712, 1, 0, 0, 0, 706, 704, 1, 0, 0, 0, 707, 709, 5, 13, 0, 0, 708, - 707, 1, 0, 0, 0, 708, 709, 1, 0, 0, 0, 709, 710, 1, 0, 0, 0, 710, 713, - 5, 10, 0, 0, 711, 713, 5, 0, 0, 1, 712, 708, 1, 0, 0, 0, 712, 711, 1, 0, - 0, 0, 713, 714, 1, 0, 0, 0, 714, 715, 6, 93, 0, 0, 715, 188, 1, 0, 0, 0, - 716, 717, 5, 47, 0, 0, 717, 718, 5, 42, 0, 0, 718, 722, 1, 0, 0, 0, 719, - 721, 9, 0, 0, 0, 720, 719, 1, 0, 0, 0, 721, 724, 1, 0, 0, 0, 722, 723, - 1, 0, 0, 0, 722, 720, 1, 0, 0, 0, 723, 725, 1, 0, 0, 0, 724, 722, 1, 0, - 0, 0, 725, 726, 5, 42, 0, 0, 726, 727, 5, 47, 0, 0, 727, 728, 1, 0, 0, - 0, 728, 729, 6, 94, 0, 0, 729, 190, 1, 0, 0, 0, 730, 731, 7, 33, 0, 0, - 731, 732, 1, 0, 0, 0, 732, 733, 6, 95, 0, 0, 733, 192, 1, 0, 0, 0, 734, - 735, 9, 0, 0, 0, 735, 194, 1, 0, 0, 0, 16, 0, 635, 640, 648, 654, 656, - 670, 672, 680, 682, 690, 693, 704, 708, 712, 722, 1, 0, 1, 0, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// SQLLexerInit initializes any static state used to implement SQLLexer. By default the -// static state used to implement the lexer is lazily initialized during the first call to -// NewSQLLexer(). You can call this function if you wish to initialize the static state ahead -// of time. -func SQLLexerInit() { - staticData := &SQLLexerLexerStaticData - staticData.once.Do(sqllexerLexerInit) -} - -// NewSQLLexer produces a new lexer instance for the optional input antlr.CharStream. -func NewSQLLexer(input antlr.CharStream) *SQLLexer { - SQLLexerInit() - l := new(SQLLexer) - l.BaseLexer = antlr.NewBaseLexer(input) - staticData := &SQLLexerLexerStaticData - l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - l.channelNames = staticData.ChannelNames - l.modeNames = staticData.ModeNames - l.RuleNames = staticData.RuleNames - l.LiteralNames = staticData.LiteralNames - l.SymbolicNames = staticData.SymbolicNames - l.GrammarFileName = "SQLLexer.g4" - // TODO: l.EOF = antlr.TokenEOF - - return l -} - -// SQLLexer tokens. -const ( - SQLLexerSCOL = 1 - SQLLexerDOT = 2 - SQLLexerOPEN_PAR = 3 - SQLLexerCLOSE_PAR = 4 - SQLLexerL_BRACKET = 5 - SQLLexerR_BRACKET = 6 - SQLLexerCOMMA = 7 - SQLLexerASSIGN = 8 - SQLLexerSTAR = 9 - SQLLexerPLUS = 10 - SQLLexerMINUS = 11 - SQLLexerDIV = 12 - SQLLexerMOD = 13 - SQLLexerLT = 14 - SQLLexerLT_EQ = 15 - SQLLexerGT = 16 - SQLLexerGT_EQ = 17 - SQLLexerNOT_EQ1 = 18 - SQLLexerNOT_EQ2 = 19 - SQLLexerTYPE_CAST = 20 - SQLLexerADD_ = 21 - SQLLexerALL_ = 22 - SQLLexerAND_ = 23 - SQLLexerASC_ = 24 - SQLLexerAS_ = 25 - SQLLexerBETWEEN_ = 26 - SQLLexerBY_ = 27 - SQLLexerCASE_ = 28 - SQLLexerCOLLATE_ = 29 - SQLLexerCOMMIT_ = 30 - SQLLexerCONFLICT_ = 31 - SQLLexerCREATE_ = 32 - SQLLexerCROSS_ = 33 - SQLLexerDEFAULT_ = 34 - SQLLexerDELETE_ = 35 - SQLLexerDESC_ = 36 - SQLLexerDISTINCT_ = 37 - SQLLexerDO_ = 38 - SQLLexerELSE_ = 39 - SQLLexerEND_ = 40 - SQLLexerESCAPE_ = 41 - SQLLexerEXCEPT_ = 42 - SQLLexerEXISTS_ = 43 - SQLLexerFILTER_ = 44 - SQLLexerFIRST_ = 45 - SQLLexerFROM_ = 46 - SQLLexerFULL_ = 47 - SQLLexerGROUPS_ = 48 - SQLLexerGROUP_ = 49 - SQLLexerHAVING_ = 50 - SQLLexerINNER_ = 51 - SQLLexerINSERT_ = 52 - SQLLexerINTERSECT_ = 53 - SQLLexerINTO_ = 54 - SQLLexerIN_ = 55 - SQLLexerISNULL_ = 56 - SQLLexerIS_ = 57 - SQLLexerJOIN_ = 58 - SQLLexerLAST_ = 59 - SQLLexerLEFT_ = 60 - SQLLexerLIKE_ = 61 - SQLLexerLIMIT_ = 62 - SQLLexerNOTHING_ = 63 - SQLLexerNOTNULL_ = 64 - SQLLexerNOT_ = 65 - SQLLexerNULLS_ = 66 - SQLLexerOFFSET_ = 67 - SQLLexerOF_ = 68 - SQLLexerON_ = 69 - SQLLexerORDER_ = 70 - SQLLexerOR_ = 71 - SQLLexerOUTER_ = 72 - SQLLexerRAISE_ = 73 - SQLLexerREPLACE_ = 74 - SQLLexerRETURNING_ = 75 - SQLLexerRIGHT_ = 76 - SQLLexerSELECT_ = 77 - SQLLexerSET_ = 78 - SQLLexerTHEN_ = 79 - SQLLexerUNION_ = 80 - SQLLexerUPDATE_ = 81 - SQLLexerUSING_ = 82 - SQLLexerVALUES_ = 83 - SQLLexerWHEN_ = 84 - SQLLexerWHERE_ = 85 - SQLLexerWITH_ = 86 - SQLLexerBOOLEAN_LITERAL = 87 - SQLLexerNUMERIC_LITERAL = 88 - SQLLexerBLOB_LITERAL = 89 - SQLLexerTEXT_LITERAL = 90 - SQLLexerNULL_LITERAL = 91 - SQLLexerIDENTIFIER = 92 - SQLLexerBIND_PARAMETER = 93 - SQLLexerSINGLE_LINE_COMMENT = 94 - SQLLexerMULTILINE_COMMENT = 95 - SQLLexerSPACES = 96 - SQLLexerUNEXPECTED_CHAR = 97 -) diff --git a/parse/sql/gen/sql_parser.go b/parse/sql/gen/sql_parser.go deleted file mode 100644 index e9bc4bd5a..000000000 --- a/parse/sql/gen/sql_parser.go +++ /dev/null @@ -1,13050 +0,0 @@ -// Code generated from SQLParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package sqlgrammar // SQLParser -import ( - "fmt" - "strconv" - "sync" - - "github.com/antlr4-go/antlr/v4" -) - -// Suppress unused import errors -var _ = fmt.Printf -var _ = strconv.Itoa -var _ = sync.Once{} - -type SQLParser struct { - *antlr.BaseParser -} - -var SQLParserParserStaticData struct { - once sync.Once - serializedATN []int32 - LiteralNames []string - SymbolicNames []string - RuleNames []string - PredictionContextCache *antlr.PredictionContextCache - atn *antlr.ATN - decisionToDFA []*antlr.DFA -} - -func sqlparserParserInit() { - staticData := &SQLParserParserStaticData - staticData.LiteralNames = []string{ - "", "';'", "'.'", "'('", "')'", "'['", "']'", "','", "'='", "'*'", "'+'", - "'-'", "'/'", "'%'", "'<'", "'<='", "'>'", "'>='", "'!='", "'<>'", "'::'", - "'ADD'", "'ALL'", "'AND'", "'ASC'", "'AS'", "'BETWEEN'", "'BY'", "'CASE'", - "'COLLATE'", "'COMMIT'", "'CONFLICT'", "'CREATE'", "'CROSS'", "'DEFAULT'", - "'DELETE'", "'DESC'", "'DISTINCT'", "'DO'", "'ELSE'", "'END'", "'ESCAPE'", - "'EXCEPT'", "'EXISTS'", "'FILTER'", "'FIRST'", "'FROM'", "'FULL'", "'GROUPS'", - "'GROUP'", "'HAVING'", "'INNER'", "'INSERT'", "'INTERSECT'", "'INTO'", - "'IN'", "'ISNULL'", "'IS'", "'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", - "'LIMIT'", "'NOTHING'", "'NOTNULL'", "'NOT'", "'NULLS'", "'OFFSET'", - "'OF'", "'ON'", "'ORDER'", "'OR'", "'OUTER'", "'RAISE'", "'REPLACE'", - "'RETURNING'", "'RIGHT'", "'SELECT'", "'SET'", "'THEN'", "'UNION'", - "'UPDATE'", "'USING'", "'VALUES'", "'WHEN'", "'WHERE'", "'WITH'", "", - "", "", "", "'null'", - } - staticData.SymbolicNames = []string{ - "", "SCOL", "DOT", "OPEN_PAR", "CLOSE_PAR", "L_BRACKET", "R_BRACKET", - "COMMA", "ASSIGN", "STAR", "PLUS", "MINUS", "DIV", "MOD", "LT", "LT_EQ", - "GT", "GT_EQ", "NOT_EQ1", "NOT_EQ2", "TYPE_CAST", "ADD_", "ALL_", "AND_", - "ASC_", "AS_", "BETWEEN_", "BY_", "CASE_", "COLLATE_", "COMMIT_", "CONFLICT_", - "CREATE_", "CROSS_", "DEFAULT_", "DELETE_", "DESC_", "DISTINCT_", "DO_", - "ELSE_", "END_", "ESCAPE_", "EXCEPT_", "EXISTS_", "FILTER_", "FIRST_", - "FROM_", "FULL_", "GROUPS_", "GROUP_", "HAVING_", "INNER_", "INSERT_", - "INTERSECT_", "INTO_", "IN_", "ISNULL_", "IS_", "JOIN_", "LAST_", "LEFT_", - "LIKE_", "LIMIT_", "NOTHING_", "NOTNULL_", "NOT_", "NULLS_", "OFFSET_", - "OF_", "ON_", "ORDER_", "OR_", "OUTER_", "RAISE_", "REPLACE_", "RETURNING_", - "RIGHT_", "SELECT_", "SET_", "THEN_", "UNION_", "UPDATE_", "USING_", - "VALUES_", "WHEN_", "WHERE_", "WITH_", "BOOLEAN_LITERAL", "NUMERIC_LITERAL", - "BLOB_LITERAL", "TEXT_LITERAL", "NULL_LITERAL", "IDENTIFIER", "BIND_PARAMETER", - "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", - } - staticData.RuleNames = []string{ - "statements", "sql_stmt_list", "sql_stmt", "indexed_column", "cte_table_name", - "common_table_expression", "common_table_stmt", "delete_core", "delete_stmt", - "variable", "function_call", "column_ref", "when_clause", "expr", "subquery", - "expr_list", "comparisonOperator", "cast_type", "type_cast", "value_row", - "values_clause", "insert_core", "insert_stmt", "returning_clause", "upsert_update", - "upsert_clause", "select_core", "select_stmt", "join_relation", "relation", - "simple_select", "table_or_subquery", "result_column", "returning_clause_result_column", - "join_operator", "join_constraint", "compound_operator", "update_set_subclause", - "update_core", "update_stmt", "column_name_list", "qualified_table_name", - "order_by_stmt", "limit_stmt", "ordering_term", "asc_desc", "function_keyword", - "function_name", "table_name", "table_alias", "column_name", "column_alias", - "collation_name", "index_name", - } - staticData.PredictionContextCache = antlr.NewPredictionContextCache() - staticData.serializedATN = []int32{ - 4, 1, 97, 721, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, - 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, - 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, - 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, - 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, - 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, - 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, - 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, - 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, - 52, 2, 53, 7, 53, 1, 0, 5, 0, 110, 8, 0, 10, 0, 12, 0, 113, 9, 0, 1, 0, - 1, 0, 1, 1, 5, 1, 118, 8, 1, 10, 1, 12, 1, 121, 9, 1, 1, 1, 1, 1, 4, 1, - 125, 8, 1, 11, 1, 12, 1, 126, 1, 1, 5, 1, 130, 8, 1, 10, 1, 12, 1, 133, - 9, 1, 1, 1, 5, 1, 136, 8, 1, 10, 1, 12, 1, 139, 9, 1, 1, 2, 1, 2, 1, 2, - 1, 2, 3, 2, 145, 8, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, - 154, 8, 4, 10, 4, 12, 4, 157, 9, 4, 1, 4, 1, 4, 3, 4, 161, 8, 4, 1, 5, - 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 173, 8, 6, - 10, 6, 12, 6, 176, 9, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 183, 8, 7, - 1, 7, 3, 7, 186, 8, 7, 1, 8, 3, 8, 189, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, - 10, 1, 10, 1, 10, 3, 10, 198, 8, 10, 1, 10, 1, 10, 3, 10, 202, 8, 10, 1, - 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, - 214, 8, 10, 1, 10, 1, 10, 3, 10, 218, 8, 10, 1, 11, 1, 11, 1, 11, 3, 11, - 223, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, - 13, 1, 13, 3, 13, 235, 8, 13, 1, 13, 1, 13, 3, 13, 239, 8, 13, 1, 13, 1, - 13, 3, 13, 243, 8, 13, 1, 13, 1, 13, 3, 13, 247, 8, 13, 1, 13, 1, 13, 3, - 13, 251, 8, 13, 1, 13, 1, 13, 3, 13, 255, 8, 13, 1, 13, 1, 13, 3, 13, 259, - 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 267, 8, 13, 1, - 13, 3, 13, 270, 8, 13, 1, 13, 3, 13, 273, 8, 13, 1, 13, 1, 13, 1, 13, 3, - 13, 278, 8, 13, 1, 13, 4, 13, 281, 8, 13, 11, 13, 12, 13, 282, 1, 13, 1, - 13, 3, 13, 287, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, - 1, 13, 3, 13, 297, 8, 13, 1, 13, 1, 13, 3, 13, 301, 8, 13, 1, 13, 1, 13, - 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 311, 8, 13, 1, 13, 1, - 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, - 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 333, 8, - 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 339, 8, 13, 1, 13, 1, 13, 1, 13, - 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 348, 8, 13, 1, 13, 1, 13, 1, 13, 1, - 13, 3, 13, 354, 8, 13, 1, 13, 1, 13, 1, 13, 3, 13, 359, 8, 13, 1, 13, 1, - 13, 1, 13, 1, 13, 1, 13, 3, 13, 366, 8, 13, 1, 13, 1, 13, 5, 13, 370, 8, - 13, 10, 13, 12, 13, 373, 9, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, - 1, 15, 5, 15, 382, 8, 15, 10, 15, 12, 15, 385, 9, 15, 1, 16, 1, 16, 1, - 17, 1, 17, 1, 17, 3, 17, 392, 8, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, - 1, 19, 1, 19, 5, 19, 401, 8, 19, 10, 19, 12, 19, 404, 9, 19, 1, 19, 1, - 19, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 412, 8, 20, 10, 20, 12, 20, 415, - 9, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 422, 8, 21, 1, 21, 1, - 21, 1, 21, 1, 21, 5, 21, 428, 8, 21, 10, 21, 12, 21, 431, 9, 21, 1, 21, - 1, 21, 3, 21, 435, 8, 21, 1, 21, 1, 21, 3, 21, 439, 8, 21, 1, 21, 3, 21, - 442, 8, 21, 1, 22, 3, 22, 445, 8, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, - 1, 23, 5, 23, 453, 8, 23, 10, 23, 12, 23, 456, 9, 23, 1, 24, 1, 24, 3, - 24, 460, 8, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, - 1, 25, 5, 25, 471, 8, 25, 10, 25, 12, 25, 474, 9, 25, 1, 25, 1, 25, 1, - 25, 3, 25, 479, 8, 25, 3, 25, 481, 8, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, - 25, 1, 25, 1, 25, 5, 25, 490, 8, 25, 10, 25, 12, 25, 493, 9, 25, 1, 25, - 1, 25, 3, 25, 497, 8, 25, 3, 25, 499, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, - 5, 26, 505, 8, 26, 10, 26, 12, 26, 508, 9, 26, 1, 26, 3, 26, 511, 8, 26, - 1, 26, 3, 26, 514, 8, 26, 1, 27, 3, 27, 517, 8, 27, 1, 27, 1, 27, 1, 28, - 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 5, 29, 527, 8, 29, 10, 29, 12, 29, 530, - 9, 29, 1, 30, 1, 30, 3, 30, 534, 8, 30, 1, 30, 1, 30, 1, 30, 5, 30, 539, - 8, 30, 10, 30, 12, 30, 542, 9, 30, 1, 30, 1, 30, 3, 30, 546, 8, 30, 1, - 30, 1, 30, 3, 30, 550, 8, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 5, 30, - 557, 8, 30, 10, 30, 12, 30, 560, 9, 30, 1, 30, 1, 30, 3, 30, 564, 8, 30, - 3, 30, 566, 8, 30, 1, 31, 1, 31, 1, 31, 3, 31, 571, 8, 31, 1, 31, 1, 31, - 1, 31, 3, 31, 576, 8, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 583, - 8, 31, 3, 31, 585, 8, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, - 32, 1, 32, 3, 32, 595, 8, 32, 3, 32, 597, 8, 32, 1, 33, 1, 33, 1, 33, 1, - 33, 3, 33, 603, 8, 33, 3, 33, 605, 8, 33, 1, 34, 1, 34, 3, 34, 609, 8, - 34, 1, 34, 3, 34, 612, 8, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, - 1, 36, 3, 36, 621, 8, 36, 1, 36, 1, 36, 3, 36, 625, 8, 36, 1, 37, 1, 37, - 3, 37, 629, 8, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, - 38, 1, 38, 5, 38, 640, 8, 38, 10, 38, 12, 38, 643, 9, 38, 1, 38, 1, 38, - 3, 38, 647, 8, 38, 1, 38, 1, 38, 3, 38, 651, 8, 38, 1, 38, 3, 38, 654, - 8, 38, 1, 39, 3, 39, 657, 8, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, - 40, 5, 40, 665, 8, 40, 10, 40, 12, 40, 668, 9, 40, 1, 40, 1, 40, 1, 41, - 1, 41, 1, 41, 3, 41, 675, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 5, - 42, 682, 8, 42, 10, 42, 12, 42, 685, 9, 42, 1, 43, 1, 43, 1, 43, 1, 43, - 3, 43, 691, 8, 43, 1, 44, 1, 44, 3, 44, 695, 8, 44, 1, 44, 1, 44, 3, 44, - 699, 8, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 3, 47, 707, 8, 47, - 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, - 53, 1, 53, 1, 53, 0, 1, 26, 54, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, - 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, - 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, - 94, 96, 98, 100, 102, 104, 106, 0, 8, 1, 0, 10, 11, 2, 0, 9, 9, 12, 13, - 2, 0, 56, 56, 64, 64, 2, 0, 8, 8, 14, 19, 3, 0, 47, 47, 60, 60, 76, 76, - 2, 0, 45, 45, 59, 59, 2, 0, 24, 24, 36, 36, 2, 0, 61, 61, 74, 74, 792, - 0, 111, 1, 0, 0, 0, 2, 119, 1, 0, 0, 0, 4, 144, 1, 0, 0, 0, 6, 146, 1, - 0, 0, 0, 8, 148, 1, 0, 0, 0, 10, 162, 1, 0, 0, 0, 12, 168, 1, 0, 0, 0, - 14, 177, 1, 0, 0, 0, 16, 188, 1, 0, 0, 0, 18, 192, 1, 0, 0, 0, 20, 217, - 1, 0, 0, 0, 22, 222, 1, 0, 0, 0, 24, 226, 1, 0, 0, 0, 26, 300, 1, 0, 0, - 0, 28, 374, 1, 0, 0, 0, 30, 378, 1, 0, 0, 0, 32, 386, 1, 0, 0, 0, 34, 388, - 1, 0, 0, 0, 36, 393, 1, 0, 0, 0, 38, 396, 1, 0, 0, 0, 40, 407, 1, 0, 0, - 0, 42, 416, 1, 0, 0, 0, 44, 444, 1, 0, 0, 0, 46, 448, 1, 0, 0, 0, 48, 459, - 1, 0, 0, 0, 50, 464, 1, 0, 0, 0, 52, 500, 1, 0, 0, 0, 54, 516, 1, 0, 0, - 0, 56, 520, 1, 0, 0, 0, 58, 524, 1, 0, 0, 0, 60, 531, 1, 0, 0, 0, 62, 584, - 1, 0, 0, 0, 64, 596, 1, 0, 0, 0, 66, 604, 1, 0, 0, 0, 68, 611, 1, 0, 0, - 0, 70, 615, 1, 0, 0, 0, 72, 624, 1, 0, 0, 0, 74, 628, 1, 0, 0, 0, 76, 633, - 1, 0, 0, 0, 78, 656, 1, 0, 0, 0, 80, 660, 1, 0, 0, 0, 82, 671, 1, 0, 0, - 0, 84, 676, 1, 0, 0, 0, 86, 686, 1, 0, 0, 0, 88, 692, 1, 0, 0, 0, 90, 700, - 1, 0, 0, 0, 92, 702, 1, 0, 0, 0, 94, 706, 1, 0, 0, 0, 96, 708, 1, 0, 0, - 0, 98, 710, 1, 0, 0, 0, 100, 712, 1, 0, 0, 0, 102, 714, 1, 0, 0, 0, 104, - 716, 1, 0, 0, 0, 106, 718, 1, 0, 0, 0, 108, 110, 3, 2, 1, 0, 109, 108, - 1, 0, 0, 0, 110, 113, 1, 0, 0, 0, 111, 109, 1, 0, 0, 0, 111, 112, 1, 0, - 0, 0, 112, 114, 1, 0, 0, 0, 113, 111, 1, 0, 0, 0, 114, 115, 5, 0, 0, 1, - 115, 1, 1, 0, 0, 0, 116, 118, 5, 1, 0, 0, 117, 116, 1, 0, 0, 0, 118, 121, - 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 122, 1, 0, - 0, 0, 121, 119, 1, 0, 0, 0, 122, 131, 3, 4, 2, 0, 123, 125, 5, 1, 0, 0, - 124, 123, 1, 0, 0, 0, 125, 126, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 126, - 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 130, 3, 4, 2, 0, 129, 124, - 1, 0, 0, 0, 130, 133, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 131, 132, 1, 0, - 0, 0, 132, 137, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 134, 136, 5, 1, 0, 0, - 135, 134, 1, 0, 0, 0, 136, 139, 1, 0, 0, 0, 137, 135, 1, 0, 0, 0, 137, - 138, 1, 0, 0, 0, 138, 3, 1, 0, 0, 0, 139, 137, 1, 0, 0, 0, 140, 145, 3, - 16, 8, 0, 141, 145, 3, 44, 22, 0, 142, 145, 3, 54, 27, 0, 143, 145, 3, - 78, 39, 0, 144, 140, 1, 0, 0, 0, 144, 141, 1, 0, 0, 0, 144, 142, 1, 0, - 0, 0, 144, 143, 1, 0, 0, 0, 145, 5, 1, 0, 0, 0, 146, 147, 3, 100, 50, 0, - 147, 7, 1, 0, 0, 0, 148, 160, 3, 96, 48, 0, 149, 150, 5, 3, 0, 0, 150, - 155, 3, 100, 50, 0, 151, 152, 5, 7, 0, 0, 152, 154, 3, 100, 50, 0, 153, - 151, 1, 0, 0, 0, 154, 157, 1, 0, 0, 0, 155, 153, 1, 0, 0, 0, 155, 156, - 1, 0, 0, 0, 156, 158, 1, 0, 0, 0, 157, 155, 1, 0, 0, 0, 158, 159, 5, 4, - 0, 0, 159, 161, 1, 0, 0, 0, 160, 149, 1, 0, 0, 0, 160, 161, 1, 0, 0, 0, - 161, 9, 1, 0, 0, 0, 162, 163, 3, 8, 4, 0, 163, 164, 5, 25, 0, 0, 164, 165, - 5, 3, 0, 0, 165, 166, 3, 52, 26, 0, 166, 167, 5, 4, 0, 0, 167, 11, 1, 0, - 0, 0, 168, 169, 5, 86, 0, 0, 169, 174, 3, 10, 5, 0, 170, 171, 5, 7, 0, - 0, 171, 173, 3, 10, 5, 0, 172, 170, 1, 0, 0, 0, 173, 176, 1, 0, 0, 0, 174, - 172, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 13, 1, 0, 0, 0, 176, 174, 1, - 0, 0, 0, 177, 178, 5, 35, 0, 0, 178, 179, 5, 46, 0, 0, 179, 182, 3, 82, - 41, 0, 180, 181, 5, 85, 0, 0, 181, 183, 3, 26, 13, 0, 182, 180, 1, 0, 0, - 0, 182, 183, 1, 0, 0, 0, 183, 185, 1, 0, 0, 0, 184, 186, 3, 46, 23, 0, - 185, 184, 1, 0, 0, 0, 185, 186, 1, 0, 0, 0, 186, 15, 1, 0, 0, 0, 187, 189, - 3, 12, 6, 0, 188, 187, 1, 0, 0, 0, 188, 189, 1, 0, 0, 0, 189, 190, 1, 0, - 0, 0, 190, 191, 3, 14, 7, 0, 191, 17, 1, 0, 0, 0, 192, 193, 5, 93, 0, 0, - 193, 19, 1, 0, 0, 0, 194, 195, 3, 94, 47, 0, 195, 201, 5, 3, 0, 0, 196, - 198, 5, 37, 0, 0, 197, 196, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, - 1, 0, 0, 0, 199, 202, 3, 30, 15, 0, 200, 202, 5, 9, 0, 0, 201, 197, 1, - 0, 0, 0, 201, 200, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 203, 1, 0, 0, - 0, 203, 204, 5, 4, 0, 0, 204, 218, 1, 0, 0, 0, 205, 206, 5, 92, 0, 0, 206, - 207, 5, 5, 0, 0, 207, 208, 3, 26, 13, 0, 208, 209, 5, 7, 0, 0, 209, 210, - 3, 26, 13, 0, 210, 211, 5, 6, 0, 0, 211, 213, 5, 3, 0, 0, 212, 214, 3, - 30, 15, 0, 213, 212, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 1, 0, - 0, 0, 215, 216, 5, 4, 0, 0, 216, 218, 1, 0, 0, 0, 217, 194, 1, 0, 0, 0, - 217, 205, 1, 0, 0, 0, 218, 21, 1, 0, 0, 0, 219, 220, 3, 96, 48, 0, 220, - 221, 5, 2, 0, 0, 221, 223, 1, 0, 0, 0, 222, 219, 1, 0, 0, 0, 222, 223, - 1, 0, 0, 0, 223, 224, 1, 0, 0, 0, 224, 225, 3, 100, 50, 0, 225, 23, 1, - 0, 0, 0, 226, 227, 5, 84, 0, 0, 227, 228, 3, 26, 13, 0, 228, 229, 5, 79, - 0, 0, 229, 230, 3, 26, 13, 0, 230, 25, 1, 0, 0, 0, 231, 232, 6, 13, -1, - 0, 232, 234, 5, 90, 0, 0, 233, 235, 3, 36, 18, 0, 234, 233, 1, 0, 0, 0, - 234, 235, 1, 0, 0, 0, 235, 301, 1, 0, 0, 0, 236, 238, 5, 87, 0, 0, 237, - 239, 3, 36, 18, 0, 238, 237, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 301, - 1, 0, 0, 0, 240, 242, 5, 88, 0, 0, 241, 243, 3, 36, 18, 0, 242, 241, 1, - 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 301, 1, 0, 0, 0, 244, 246, 5, 91, 0, - 0, 245, 247, 3, 36, 18, 0, 246, 245, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, - 247, 301, 1, 0, 0, 0, 248, 250, 5, 89, 0, 0, 249, 251, 3, 36, 18, 0, 250, - 249, 1, 0, 0, 0, 250, 251, 1, 0, 0, 0, 251, 301, 1, 0, 0, 0, 252, 254, - 3, 18, 9, 0, 253, 255, 3, 36, 18, 0, 254, 253, 1, 0, 0, 0, 254, 255, 1, - 0, 0, 0, 255, 301, 1, 0, 0, 0, 256, 258, 3, 22, 11, 0, 257, 259, 3, 36, - 18, 0, 258, 257, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 301, 1, 0, 0, 0, - 260, 261, 7, 0, 0, 0, 261, 301, 3, 26, 13, 19, 262, 263, 5, 3, 0, 0, 263, - 264, 3, 26, 13, 0, 264, 266, 5, 4, 0, 0, 265, 267, 3, 36, 18, 0, 266, 265, - 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 301, 1, 0, 0, 0, 268, 270, 5, 65, - 0, 0, 269, 268, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, - 271, 273, 5, 43, 0, 0, 272, 269, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, - 274, 1, 0, 0, 0, 274, 301, 3, 28, 14, 0, 275, 277, 5, 28, 0, 0, 276, 278, - 3, 26, 13, 0, 277, 276, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 280, 1, - 0, 0, 0, 279, 281, 3, 24, 12, 0, 280, 279, 1, 0, 0, 0, 281, 282, 1, 0, - 0, 0, 282, 280, 1, 0, 0, 0, 282, 283, 1, 0, 0, 0, 283, 286, 1, 0, 0, 0, - 284, 285, 5, 39, 0, 0, 285, 287, 3, 26, 13, 0, 286, 284, 1, 0, 0, 0, 286, - 287, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 5, 40, 0, 0, 289, 301, - 1, 0, 0, 0, 290, 291, 5, 3, 0, 0, 291, 292, 3, 30, 15, 0, 292, 293, 5, - 4, 0, 0, 293, 301, 1, 0, 0, 0, 294, 296, 3, 20, 10, 0, 295, 297, 3, 36, - 18, 0, 296, 295, 1, 0, 0, 0, 296, 297, 1, 0, 0, 0, 297, 301, 1, 0, 0, 0, - 298, 299, 5, 65, 0, 0, 299, 301, 3, 26, 13, 3, 300, 231, 1, 0, 0, 0, 300, - 236, 1, 0, 0, 0, 300, 240, 1, 0, 0, 0, 300, 244, 1, 0, 0, 0, 300, 248, - 1, 0, 0, 0, 300, 252, 1, 0, 0, 0, 300, 256, 1, 0, 0, 0, 300, 260, 1, 0, - 0, 0, 300, 262, 1, 0, 0, 0, 300, 272, 1, 0, 0, 0, 300, 275, 1, 0, 0, 0, - 300, 290, 1, 0, 0, 0, 300, 294, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 301, - 371, 1, 0, 0, 0, 302, 303, 10, 12, 0, 0, 303, 304, 7, 1, 0, 0, 304, 370, - 3, 26, 13, 13, 305, 306, 10, 11, 0, 0, 306, 307, 7, 0, 0, 0, 307, 370, - 3, 26, 13, 12, 308, 310, 10, 8, 0, 0, 309, 311, 5, 65, 0, 0, 310, 309, - 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 313, 5, 26, - 0, 0, 313, 314, 3, 26, 13, 0, 314, 315, 5, 23, 0, 0, 315, 316, 3, 26, 13, - 9, 316, 370, 1, 0, 0, 0, 317, 318, 10, 6, 0, 0, 318, 319, 3, 32, 16, 0, - 319, 320, 3, 26, 13, 7, 320, 370, 1, 0, 0, 0, 321, 322, 10, 2, 0, 0, 322, - 323, 5, 23, 0, 0, 323, 370, 3, 26, 13, 3, 324, 325, 10, 1, 0, 0, 325, 326, - 5, 71, 0, 0, 326, 370, 3, 26, 13, 2, 327, 328, 10, 18, 0, 0, 328, 329, - 5, 29, 0, 0, 329, 370, 3, 104, 52, 0, 330, 332, 10, 10, 0, 0, 331, 333, - 5, 65, 0, 0, 332, 331, 1, 0, 0, 0, 332, 333, 1, 0, 0, 0, 333, 334, 1, 0, - 0, 0, 334, 335, 5, 55, 0, 0, 335, 370, 3, 28, 14, 0, 336, 338, 10, 9, 0, - 0, 337, 339, 5, 65, 0, 0, 338, 337, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 339, - 340, 1, 0, 0, 0, 340, 341, 5, 55, 0, 0, 341, 342, 5, 3, 0, 0, 342, 343, - 3, 30, 15, 0, 343, 344, 5, 4, 0, 0, 344, 370, 1, 0, 0, 0, 345, 347, 10, - 7, 0, 0, 346, 348, 5, 65, 0, 0, 347, 346, 1, 0, 0, 0, 347, 348, 1, 0, 0, - 0, 348, 349, 1, 0, 0, 0, 349, 350, 5, 61, 0, 0, 350, 353, 3, 26, 13, 0, - 351, 352, 5, 41, 0, 0, 352, 354, 3, 26, 13, 0, 353, 351, 1, 0, 0, 0, 353, - 354, 1, 0, 0, 0, 354, 370, 1, 0, 0, 0, 355, 356, 10, 5, 0, 0, 356, 358, - 5, 57, 0, 0, 357, 359, 5, 65, 0, 0, 358, 357, 1, 0, 0, 0, 358, 359, 1, - 0, 0, 0, 359, 365, 1, 0, 0, 0, 360, 361, 5, 37, 0, 0, 361, 362, 5, 46, - 0, 0, 362, 366, 3, 26, 13, 0, 363, 366, 5, 87, 0, 0, 364, 366, 5, 91, 0, - 0, 365, 360, 1, 0, 0, 0, 365, 363, 1, 0, 0, 0, 365, 364, 1, 0, 0, 0, 366, - 370, 1, 0, 0, 0, 367, 368, 10, 4, 0, 0, 368, 370, 7, 2, 0, 0, 369, 302, - 1, 0, 0, 0, 369, 305, 1, 0, 0, 0, 369, 308, 1, 0, 0, 0, 369, 317, 1, 0, - 0, 0, 369, 321, 1, 0, 0, 0, 369, 324, 1, 0, 0, 0, 369, 327, 1, 0, 0, 0, - 369, 330, 1, 0, 0, 0, 369, 336, 1, 0, 0, 0, 369, 345, 1, 0, 0, 0, 369, - 355, 1, 0, 0, 0, 369, 367, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, - 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 27, 1, 0, 0, 0, 373, 371, 1, 0, - 0, 0, 374, 375, 5, 3, 0, 0, 375, 376, 3, 52, 26, 0, 376, 377, 5, 4, 0, - 0, 377, 29, 1, 0, 0, 0, 378, 383, 3, 26, 13, 0, 379, 380, 5, 7, 0, 0, 380, - 382, 3, 26, 13, 0, 381, 379, 1, 0, 0, 0, 382, 385, 1, 0, 0, 0, 383, 381, - 1, 0, 0, 0, 383, 384, 1, 0, 0, 0, 384, 31, 1, 0, 0, 0, 385, 383, 1, 0, - 0, 0, 386, 387, 7, 3, 0, 0, 387, 33, 1, 0, 0, 0, 388, 391, 5, 92, 0, 0, - 389, 390, 5, 5, 0, 0, 390, 392, 5, 6, 0, 0, 391, 389, 1, 0, 0, 0, 391, - 392, 1, 0, 0, 0, 392, 35, 1, 0, 0, 0, 393, 394, 5, 20, 0, 0, 394, 395, - 3, 34, 17, 0, 395, 37, 1, 0, 0, 0, 396, 397, 5, 3, 0, 0, 397, 402, 3, 26, - 13, 0, 398, 399, 5, 7, 0, 0, 399, 401, 3, 26, 13, 0, 400, 398, 1, 0, 0, - 0, 401, 404, 1, 0, 0, 0, 402, 400, 1, 0, 0, 0, 402, 403, 1, 0, 0, 0, 403, - 405, 1, 0, 0, 0, 404, 402, 1, 0, 0, 0, 405, 406, 5, 4, 0, 0, 406, 39, 1, - 0, 0, 0, 407, 408, 5, 83, 0, 0, 408, 413, 3, 38, 19, 0, 409, 410, 5, 7, - 0, 0, 410, 412, 3, 38, 19, 0, 411, 409, 1, 0, 0, 0, 412, 415, 1, 0, 0, - 0, 413, 411, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 41, 1, 0, 0, 0, 415, - 413, 1, 0, 0, 0, 416, 417, 5, 52, 0, 0, 417, 418, 5, 54, 0, 0, 418, 421, - 3, 96, 48, 0, 419, 420, 5, 25, 0, 0, 420, 422, 3, 98, 49, 0, 421, 419, - 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 434, 1, 0, 0, 0, 423, 424, 5, 3, - 0, 0, 424, 429, 3, 100, 50, 0, 425, 426, 5, 7, 0, 0, 426, 428, 3, 100, - 50, 0, 427, 425, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, - 429, 430, 1, 0, 0, 0, 430, 432, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, - 433, 5, 4, 0, 0, 433, 435, 1, 0, 0, 0, 434, 423, 1, 0, 0, 0, 434, 435, - 1, 0, 0, 0, 435, 436, 1, 0, 0, 0, 436, 438, 3, 40, 20, 0, 437, 439, 3, - 50, 25, 0, 438, 437, 1, 0, 0, 0, 438, 439, 1, 0, 0, 0, 439, 441, 1, 0, - 0, 0, 440, 442, 3, 46, 23, 0, 441, 440, 1, 0, 0, 0, 441, 442, 1, 0, 0, - 0, 442, 43, 1, 0, 0, 0, 443, 445, 3, 12, 6, 0, 444, 443, 1, 0, 0, 0, 444, - 445, 1, 0, 0, 0, 445, 446, 1, 0, 0, 0, 446, 447, 3, 42, 21, 0, 447, 45, - 1, 0, 0, 0, 448, 449, 5, 75, 0, 0, 449, 454, 3, 66, 33, 0, 450, 451, 5, - 7, 0, 0, 451, 453, 3, 66, 33, 0, 452, 450, 1, 0, 0, 0, 453, 456, 1, 0, - 0, 0, 454, 452, 1, 0, 0, 0, 454, 455, 1, 0, 0, 0, 455, 47, 1, 0, 0, 0, - 456, 454, 1, 0, 0, 0, 457, 460, 3, 100, 50, 0, 458, 460, 3, 80, 40, 0, - 459, 457, 1, 0, 0, 0, 459, 458, 1, 0, 0, 0, 460, 461, 1, 0, 0, 0, 461, - 462, 5, 8, 0, 0, 462, 463, 3, 26, 13, 0, 463, 49, 1, 0, 0, 0, 464, 465, - 5, 69, 0, 0, 465, 480, 5, 31, 0, 0, 466, 467, 5, 3, 0, 0, 467, 472, 3, - 6, 3, 0, 468, 469, 5, 7, 0, 0, 469, 471, 3, 6, 3, 0, 470, 468, 1, 0, 0, - 0, 471, 474, 1, 0, 0, 0, 472, 470, 1, 0, 0, 0, 472, 473, 1, 0, 0, 0, 473, - 475, 1, 0, 0, 0, 474, 472, 1, 0, 0, 0, 475, 478, 5, 4, 0, 0, 476, 477, - 5, 85, 0, 0, 477, 479, 3, 26, 13, 0, 478, 476, 1, 0, 0, 0, 478, 479, 1, - 0, 0, 0, 479, 481, 1, 0, 0, 0, 480, 466, 1, 0, 0, 0, 480, 481, 1, 0, 0, - 0, 481, 482, 1, 0, 0, 0, 482, 498, 5, 38, 0, 0, 483, 499, 5, 63, 0, 0, - 484, 485, 5, 81, 0, 0, 485, 486, 5, 78, 0, 0, 486, 491, 3, 48, 24, 0, 487, - 488, 5, 7, 0, 0, 488, 490, 3, 48, 24, 0, 489, 487, 1, 0, 0, 0, 490, 493, - 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 491, 492, 1, 0, 0, 0, 492, 496, 1, 0, - 0, 0, 493, 491, 1, 0, 0, 0, 494, 495, 5, 85, 0, 0, 495, 497, 3, 26, 13, - 0, 496, 494, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 499, 1, 0, 0, 0, 498, - 483, 1, 0, 0, 0, 498, 484, 1, 0, 0, 0, 499, 51, 1, 0, 0, 0, 500, 506, 3, - 60, 30, 0, 501, 502, 3, 72, 36, 0, 502, 503, 3, 60, 30, 0, 503, 505, 1, - 0, 0, 0, 504, 501, 1, 0, 0, 0, 505, 508, 1, 0, 0, 0, 506, 504, 1, 0, 0, - 0, 506, 507, 1, 0, 0, 0, 507, 510, 1, 0, 0, 0, 508, 506, 1, 0, 0, 0, 509, - 511, 3, 84, 42, 0, 510, 509, 1, 0, 0, 0, 510, 511, 1, 0, 0, 0, 511, 513, - 1, 0, 0, 0, 512, 514, 3, 86, 43, 0, 513, 512, 1, 0, 0, 0, 513, 514, 1, - 0, 0, 0, 514, 53, 1, 0, 0, 0, 515, 517, 3, 12, 6, 0, 516, 515, 1, 0, 0, - 0, 516, 517, 1, 0, 0, 0, 517, 518, 1, 0, 0, 0, 518, 519, 3, 52, 26, 0, - 519, 55, 1, 0, 0, 0, 520, 521, 3, 68, 34, 0, 521, 522, 3, 62, 31, 0, 522, - 523, 3, 70, 35, 0, 523, 57, 1, 0, 0, 0, 524, 528, 3, 62, 31, 0, 525, 527, - 3, 56, 28, 0, 526, 525, 1, 0, 0, 0, 527, 530, 1, 0, 0, 0, 528, 526, 1, - 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 59, 1, 0, 0, 0, 530, 528, 1, 0, 0, - 0, 531, 533, 5, 77, 0, 0, 532, 534, 5, 37, 0, 0, 533, 532, 1, 0, 0, 0, - 533, 534, 1, 0, 0, 0, 534, 535, 1, 0, 0, 0, 535, 540, 3, 64, 32, 0, 536, - 537, 5, 7, 0, 0, 537, 539, 3, 64, 32, 0, 538, 536, 1, 0, 0, 0, 539, 542, - 1, 0, 0, 0, 540, 538, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 545, 1, 0, - 0, 0, 542, 540, 1, 0, 0, 0, 543, 544, 5, 46, 0, 0, 544, 546, 3, 58, 29, - 0, 545, 543, 1, 0, 0, 0, 545, 546, 1, 0, 0, 0, 546, 549, 1, 0, 0, 0, 547, - 548, 5, 85, 0, 0, 548, 550, 3, 26, 13, 0, 549, 547, 1, 0, 0, 0, 549, 550, - 1, 0, 0, 0, 550, 565, 1, 0, 0, 0, 551, 552, 5, 49, 0, 0, 552, 553, 5, 27, - 0, 0, 553, 558, 3, 26, 13, 0, 554, 555, 5, 7, 0, 0, 555, 557, 3, 26, 13, - 0, 556, 554, 1, 0, 0, 0, 557, 560, 1, 0, 0, 0, 558, 556, 1, 0, 0, 0, 558, - 559, 1, 0, 0, 0, 559, 563, 1, 0, 0, 0, 560, 558, 1, 0, 0, 0, 561, 562, - 5, 50, 0, 0, 562, 564, 3, 26, 13, 0, 563, 561, 1, 0, 0, 0, 563, 564, 1, - 0, 0, 0, 564, 566, 1, 0, 0, 0, 565, 551, 1, 0, 0, 0, 565, 566, 1, 0, 0, - 0, 566, 61, 1, 0, 0, 0, 567, 570, 3, 20, 10, 0, 568, 569, 5, 25, 0, 0, - 569, 571, 3, 98, 49, 0, 570, 568, 1, 0, 0, 0, 570, 571, 1, 0, 0, 0, 571, - 585, 1, 0, 0, 0, 572, 575, 3, 96, 48, 0, 573, 574, 5, 25, 0, 0, 574, 576, - 3, 98, 49, 0, 575, 573, 1, 0, 0, 0, 575, 576, 1, 0, 0, 0, 576, 585, 1, - 0, 0, 0, 577, 578, 5, 3, 0, 0, 578, 579, 3, 52, 26, 0, 579, 582, 5, 4, - 0, 0, 580, 581, 5, 25, 0, 0, 581, 583, 3, 98, 49, 0, 582, 580, 1, 0, 0, - 0, 582, 583, 1, 0, 0, 0, 583, 585, 1, 0, 0, 0, 584, 567, 1, 0, 0, 0, 584, - 572, 1, 0, 0, 0, 584, 577, 1, 0, 0, 0, 585, 63, 1, 0, 0, 0, 586, 597, 5, - 9, 0, 0, 587, 588, 3, 96, 48, 0, 588, 589, 5, 2, 0, 0, 589, 590, 5, 9, - 0, 0, 590, 597, 1, 0, 0, 0, 591, 594, 3, 26, 13, 0, 592, 593, 5, 25, 0, - 0, 593, 595, 3, 102, 51, 0, 594, 592, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, - 595, 597, 1, 0, 0, 0, 596, 586, 1, 0, 0, 0, 596, 587, 1, 0, 0, 0, 596, - 591, 1, 0, 0, 0, 597, 65, 1, 0, 0, 0, 598, 605, 5, 9, 0, 0, 599, 602, 3, - 26, 13, 0, 600, 601, 5, 25, 0, 0, 601, 603, 3, 102, 51, 0, 602, 600, 1, - 0, 0, 0, 602, 603, 1, 0, 0, 0, 603, 605, 1, 0, 0, 0, 604, 598, 1, 0, 0, - 0, 604, 599, 1, 0, 0, 0, 605, 67, 1, 0, 0, 0, 606, 608, 7, 4, 0, 0, 607, - 609, 5, 72, 0, 0, 608, 607, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 612, - 1, 0, 0, 0, 610, 612, 5, 51, 0, 0, 611, 606, 1, 0, 0, 0, 611, 610, 1, 0, - 0, 0, 611, 612, 1, 0, 0, 0, 612, 613, 1, 0, 0, 0, 613, 614, 5, 58, 0, 0, - 614, 69, 1, 0, 0, 0, 615, 616, 5, 69, 0, 0, 616, 617, 3, 26, 13, 0, 617, - 71, 1, 0, 0, 0, 618, 620, 5, 80, 0, 0, 619, 621, 5, 22, 0, 0, 620, 619, - 1, 0, 0, 0, 620, 621, 1, 0, 0, 0, 621, 625, 1, 0, 0, 0, 622, 625, 5, 53, - 0, 0, 623, 625, 5, 42, 0, 0, 624, 618, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, - 624, 623, 1, 0, 0, 0, 625, 73, 1, 0, 0, 0, 626, 629, 3, 100, 50, 0, 627, - 629, 3, 80, 40, 0, 628, 626, 1, 0, 0, 0, 628, 627, 1, 0, 0, 0, 629, 630, - 1, 0, 0, 0, 630, 631, 5, 8, 0, 0, 631, 632, 3, 26, 13, 0, 632, 75, 1, 0, - 0, 0, 633, 634, 5, 81, 0, 0, 634, 635, 3, 82, 41, 0, 635, 636, 5, 78, 0, - 0, 636, 641, 3, 74, 37, 0, 637, 638, 5, 7, 0, 0, 638, 640, 3, 74, 37, 0, - 639, 637, 1, 0, 0, 0, 640, 643, 1, 0, 0, 0, 641, 639, 1, 0, 0, 0, 641, - 642, 1, 0, 0, 0, 642, 646, 1, 0, 0, 0, 643, 641, 1, 0, 0, 0, 644, 645, - 5, 46, 0, 0, 645, 647, 3, 58, 29, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, - 0, 0, 0, 647, 650, 1, 0, 0, 0, 648, 649, 5, 85, 0, 0, 649, 651, 3, 26, - 13, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 653, 1, 0, 0, 0, - 652, 654, 3, 46, 23, 0, 653, 652, 1, 0, 0, 0, 653, 654, 1, 0, 0, 0, 654, - 77, 1, 0, 0, 0, 655, 657, 3, 12, 6, 0, 656, 655, 1, 0, 0, 0, 656, 657, - 1, 0, 0, 0, 657, 658, 1, 0, 0, 0, 658, 659, 3, 76, 38, 0, 659, 79, 1, 0, - 0, 0, 660, 661, 5, 3, 0, 0, 661, 666, 3, 100, 50, 0, 662, 663, 5, 7, 0, - 0, 663, 665, 3, 100, 50, 0, 664, 662, 1, 0, 0, 0, 665, 668, 1, 0, 0, 0, - 666, 664, 1, 0, 0, 0, 666, 667, 1, 0, 0, 0, 667, 669, 1, 0, 0, 0, 668, - 666, 1, 0, 0, 0, 669, 670, 5, 4, 0, 0, 670, 81, 1, 0, 0, 0, 671, 674, 3, - 96, 48, 0, 672, 673, 5, 25, 0, 0, 673, 675, 3, 98, 49, 0, 674, 672, 1, - 0, 0, 0, 674, 675, 1, 0, 0, 0, 675, 83, 1, 0, 0, 0, 676, 677, 5, 70, 0, - 0, 677, 678, 5, 27, 0, 0, 678, 683, 3, 88, 44, 0, 679, 680, 5, 7, 0, 0, - 680, 682, 3, 88, 44, 0, 681, 679, 1, 0, 0, 0, 682, 685, 1, 0, 0, 0, 683, - 681, 1, 0, 0, 0, 683, 684, 1, 0, 0, 0, 684, 85, 1, 0, 0, 0, 685, 683, 1, - 0, 0, 0, 686, 687, 5, 62, 0, 0, 687, 690, 3, 26, 13, 0, 688, 689, 5, 67, - 0, 0, 689, 691, 3, 26, 13, 0, 690, 688, 1, 0, 0, 0, 690, 691, 1, 0, 0, - 0, 691, 87, 1, 0, 0, 0, 692, 694, 3, 26, 13, 0, 693, 695, 3, 90, 45, 0, - 694, 693, 1, 0, 0, 0, 694, 695, 1, 0, 0, 0, 695, 698, 1, 0, 0, 0, 696, - 697, 5, 66, 0, 0, 697, 699, 7, 5, 0, 0, 698, 696, 1, 0, 0, 0, 698, 699, - 1, 0, 0, 0, 699, 89, 1, 0, 0, 0, 700, 701, 7, 6, 0, 0, 701, 91, 1, 0, 0, - 0, 702, 703, 7, 7, 0, 0, 703, 93, 1, 0, 0, 0, 704, 707, 5, 92, 0, 0, 705, - 707, 3, 92, 46, 0, 706, 704, 1, 0, 0, 0, 706, 705, 1, 0, 0, 0, 707, 95, - 1, 0, 0, 0, 708, 709, 5, 92, 0, 0, 709, 97, 1, 0, 0, 0, 710, 711, 5, 92, - 0, 0, 711, 99, 1, 0, 0, 0, 712, 713, 5, 92, 0, 0, 713, 101, 1, 0, 0, 0, - 714, 715, 5, 92, 0, 0, 715, 103, 1, 0, 0, 0, 716, 717, 5, 92, 0, 0, 717, - 105, 1, 0, 0, 0, 718, 719, 5, 92, 0, 0, 719, 107, 1, 0, 0, 0, 96, 111, - 119, 126, 131, 137, 144, 155, 160, 174, 182, 185, 188, 197, 201, 213, 217, - 222, 234, 238, 242, 246, 250, 254, 258, 266, 269, 272, 277, 282, 286, 296, - 300, 310, 332, 338, 347, 353, 358, 365, 369, 371, 383, 391, 402, 413, 421, - 429, 434, 438, 441, 444, 454, 459, 472, 478, 480, 491, 496, 498, 506, 510, - 513, 516, 528, 533, 540, 545, 549, 558, 563, 565, 570, 575, 582, 584, 594, - 596, 602, 604, 608, 611, 620, 624, 628, 641, 646, 650, 653, 656, 666, 674, - 683, 690, 694, 698, 706, - } - deserializer := antlr.NewATNDeserializer(nil) - staticData.atn = deserializer.Deserialize(staticData.serializedATN) - atn := staticData.atn - staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) - decisionToDFA := staticData.decisionToDFA - for index, state := range atn.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(state, index) - } -} - -// SQLParserInit initializes any static state used to implement SQLParser. By default the -// static state used to implement the parser is lazily initialized during the first call to -// NewSQLParser(). You can call this function if you wish to initialize the static state ahead -// of time. -func SQLParserInit() { - staticData := &SQLParserParserStaticData - staticData.once.Do(sqlparserParserInit) -} - -// NewSQLParser produces a new parser instance for the optional input antlr.TokenStream. -func NewSQLParser(input antlr.TokenStream) *SQLParser { - SQLParserInit() - this := new(SQLParser) - this.BaseParser = antlr.NewBaseParser(input) - staticData := &SQLParserParserStaticData - this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache) - this.RuleNames = staticData.RuleNames - this.LiteralNames = staticData.LiteralNames - this.SymbolicNames = staticData.SymbolicNames - this.GrammarFileName = "SQLParser.g4" - - return this -} - -// SQLParser tokens. -const ( - SQLParserEOF = antlr.TokenEOF - SQLParserSCOL = 1 - SQLParserDOT = 2 - SQLParserOPEN_PAR = 3 - SQLParserCLOSE_PAR = 4 - SQLParserL_BRACKET = 5 - SQLParserR_BRACKET = 6 - SQLParserCOMMA = 7 - SQLParserASSIGN = 8 - SQLParserSTAR = 9 - SQLParserPLUS = 10 - SQLParserMINUS = 11 - SQLParserDIV = 12 - SQLParserMOD = 13 - SQLParserLT = 14 - SQLParserLT_EQ = 15 - SQLParserGT = 16 - SQLParserGT_EQ = 17 - SQLParserNOT_EQ1 = 18 - SQLParserNOT_EQ2 = 19 - SQLParserTYPE_CAST = 20 - SQLParserADD_ = 21 - SQLParserALL_ = 22 - SQLParserAND_ = 23 - SQLParserASC_ = 24 - SQLParserAS_ = 25 - SQLParserBETWEEN_ = 26 - SQLParserBY_ = 27 - SQLParserCASE_ = 28 - SQLParserCOLLATE_ = 29 - SQLParserCOMMIT_ = 30 - SQLParserCONFLICT_ = 31 - SQLParserCREATE_ = 32 - SQLParserCROSS_ = 33 - SQLParserDEFAULT_ = 34 - SQLParserDELETE_ = 35 - SQLParserDESC_ = 36 - SQLParserDISTINCT_ = 37 - SQLParserDO_ = 38 - SQLParserELSE_ = 39 - SQLParserEND_ = 40 - SQLParserESCAPE_ = 41 - SQLParserEXCEPT_ = 42 - SQLParserEXISTS_ = 43 - SQLParserFILTER_ = 44 - SQLParserFIRST_ = 45 - SQLParserFROM_ = 46 - SQLParserFULL_ = 47 - SQLParserGROUPS_ = 48 - SQLParserGROUP_ = 49 - SQLParserHAVING_ = 50 - SQLParserINNER_ = 51 - SQLParserINSERT_ = 52 - SQLParserINTERSECT_ = 53 - SQLParserINTO_ = 54 - SQLParserIN_ = 55 - SQLParserISNULL_ = 56 - SQLParserIS_ = 57 - SQLParserJOIN_ = 58 - SQLParserLAST_ = 59 - SQLParserLEFT_ = 60 - SQLParserLIKE_ = 61 - SQLParserLIMIT_ = 62 - SQLParserNOTHING_ = 63 - SQLParserNOTNULL_ = 64 - SQLParserNOT_ = 65 - SQLParserNULLS_ = 66 - SQLParserOFFSET_ = 67 - SQLParserOF_ = 68 - SQLParserON_ = 69 - SQLParserORDER_ = 70 - SQLParserOR_ = 71 - SQLParserOUTER_ = 72 - SQLParserRAISE_ = 73 - SQLParserREPLACE_ = 74 - SQLParserRETURNING_ = 75 - SQLParserRIGHT_ = 76 - SQLParserSELECT_ = 77 - SQLParserSET_ = 78 - SQLParserTHEN_ = 79 - SQLParserUNION_ = 80 - SQLParserUPDATE_ = 81 - SQLParserUSING_ = 82 - SQLParserVALUES_ = 83 - SQLParserWHEN_ = 84 - SQLParserWHERE_ = 85 - SQLParserWITH_ = 86 - SQLParserBOOLEAN_LITERAL = 87 - SQLParserNUMERIC_LITERAL = 88 - SQLParserBLOB_LITERAL = 89 - SQLParserTEXT_LITERAL = 90 - SQLParserNULL_LITERAL = 91 - SQLParserIDENTIFIER = 92 - SQLParserBIND_PARAMETER = 93 - SQLParserSINGLE_LINE_COMMENT = 94 - SQLParserMULTILINE_COMMENT = 95 - SQLParserSPACES = 96 - SQLParserUNEXPECTED_CHAR = 97 -) - -// SQLParser rules. -const ( - SQLParserRULE_statements = 0 - SQLParserRULE_sql_stmt_list = 1 - SQLParserRULE_sql_stmt = 2 - SQLParserRULE_indexed_column = 3 - SQLParserRULE_cte_table_name = 4 - SQLParserRULE_common_table_expression = 5 - SQLParserRULE_common_table_stmt = 6 - SQLParserRULE_delete_core = 7 - SQLParserRULE_delete_stmt = 8 - SQLParserRULE_variable = 9 - SQLParserRULE_function_call = 10 - SQLParserRULE_column_ref = 11 - SQLParserRULE_when_clause = 12 - SQLParserRULE_expr = 13 - SQLParserRULE_subquery = 14 - SQLParserRULE_expr_list = 15 - SQLParserRULE_comparisonOperator = 16 - SQLParserRULE_cast_type = 17 - SQLParserRULE_type_cast = 18 - SQLParserRULE_value_row = 19 - SQLParserRULE_values_clause = 20 - SQLParserRULE_insert_core = 21 - SQLParserRULE_insert_stmt = 22 - SQLParserRULE_returning_clause = 23 - SQLParserRULE_upsert_update = 24 - SQLParserRULE_upsert_clause = 25 - SQLParserRULE_select_core = 26 - SQLParserRULE_select_stmt = 27 - SQLParserRULE_join_relation = 28 - SQLParserRULE_relation = 29 - SQLParserRULE_simple_select = 30 - SQLParserRULE_table_or_subquery = 31 - SQLParserRULE_result_column = 32 - SQLParserRULE_returning_clause_result_column = 33 - SQLParserRULE_join_operator = 34 - SQLParserRULE_join_constraint = 35 - SQLParserRULE_compound_operator = 36 - SQLParserRULE_update_set_subclause = 37 - SQLParserRULE_update_core = 38 - SQLParserRULE_update_stmt = 39 - SQLParserRULE_column_name_list = 40 - SQLParserRULE_qualified_table_name = 41 - SQLParserRULE_order_by_stmt = 42 - SQLParserRULE_limit_stmt = 43 - SQLParserRULE_ordering_term = 44 - SQLParserRULE_asc_desc = 45 - SQLParserRULE_function_keyword = 46 - SQLParserRULE_function_name = 47 - SQLParserRULE_table_name = 48 - SQLParserRULE_table_alias = 49 - SQLParserRULE_column_name = 50 - SQLParserRULE_column_alias = 51 - SQLParserRULE_collation_name = 52 - SQLParserRULE_index_name = 53 -) - -// IStatementsContext is an interface to support dynamic dispatch. -type IStatementsContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - EOF() antlr.TerminalNode - AllSql_stmt_list() []ISql_stmt_listContext - Sql_stmt_list(i int) ISql_stmt_listContext - - // IsStatementsContext differentiates from other interfaces. - IsStatementsContext() -} - -type StatementsContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyStatementsContext() *StatementsContext { - var p = new(StatementsContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_statements - return p -} - -func InitEmptyStatementsContext(p *StatementsContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_statements -} - -func (*StatementsContext) IsStatementsContext() {} - -func NewStatementsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StatementsContext { - var p = new(StatementsContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_statements - - return p -} - -func (s *StatementsContext) GetParser() antlr.Parser { return s.parser } - -func (s *StatementsContext) EOF() antlr.TerminalNode { - return s.GetToken(SQLParserEOF, 0) -} - -func (s *StatementsContext) AllSql_stmt_list() []ISql_stmt_listContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ISql_stmt_listContext); ok { - len++ - } - } - - tst := make([]ISql_stmt_listContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ISql_stmt_listContext); ok { - tst[i] = t.(ISql_stmt_listContext) - i++ - } - } - - return tst -} - -func (s *StatementsContext) Sql_stmt_list(i int) ISql_stmt_listContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISql_stmt_listContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ISql_stmt_listContext) -} - -func (s *StatementsContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *StatementsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *StatementsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitStatements(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Statements() (localctx IStatementsContext) { - localctx = NewStatementsContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 0, SQLParserRULE_statements) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(111) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&4503633987108866) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&529) != 0) { - { - p.SetState(108) - p.Sql_stmt_list() - } - - p.SetState(113) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(114) - p.Match(SQLParserEOF) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISql_stmt_listContext is an interface to support dynamic dispatch. -type ISql_stmt_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllSql_stmt() []ISql_stmtContext - Sql_stmt(i int) ISql_stmtContext - AllSCOL() []antlr.TerminalNode - SCOL(i int) antlr.TerminalNode - - // IsSql_stmt_listContext differentiates from other interfaces. - IsSql_stmt_listContext() -} - -type Sql_stmt_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySql_stmt_listContext() *Sql_stmt_listContext { - var p = new(Sql_stmt_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_sql_stmt_list - return p -} - -func InitEmptySql_stmt_listContext(p *Sql_stmt_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_sql_stmt_list -} - -func (*Sql_stmt_listContext) IsSql_stmt_listContext() {} - -func NewSql_stmt_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_stmt_listContext { - var p = new(Sql_stmt_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_sql_stmt_list - - return p -} - -func (s *Sql_stmt_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Sql_stmt_listContext) AllSql_stmt() []ISql_stmtContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ISql_stmtContext); ok { - len++ - } - } - - tst := make([]ISql_stmtContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ISql_stmtContext); ok { - tst[i] = t.(ISql_stmtContext) - i++ - } - } - - return tst -} - -func (s *Sql_stmt_listContext) Sql_stmt(i int) ISql_stmtContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISql_stmtContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ISql_stmtContext) -} - -func (s *Sql_stmt_listContext) AllSCOL() []antlr.TerminalNode { - return s.GetTokens(SQLParserSCOL) -} - -func (s *Sql_stmt_listContext) SCOL(i int) antlr.TerminalNode { - return s.GetToken(SQLParserSCOL, i) -} - -func (s *Sql_stmt_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Sql_stmt_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Sql_stmt_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSql_stmt_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Sql_stmt_list() (localctx ISql_stmt_listContext) { - localctx = NewSql_stmt_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 2, SQLParserRULE_sql_stmt_list) - var _la int - - var _alt int - - p.EnterOuterAlt(localctx, 1) - p.SetState(119) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserSCOL { - { - p.SetState(116) - p.Match(SQLParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(121) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(122) - p.Sql_stmt() - } - p.SetState(131) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - p.SetState(124) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ok := true; ok; ok = _la == SQLParserSCOL { - { - p.SetState(123) - p.Match(SQLParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - p.SetState(126) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(128) - p.Sql_stmt() - } - - } - p.SetState(133) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - } - p.SetState(137) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - { - p.SetState(134) - p.Match(SQLParserSCOL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - p.SetState(139) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISql_stmtContext is an interface to support dynamic dispatch. -type ISql_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Delete_stmt() IDelete_stmtContext - Insert_stmt() IInsert_stmtContext - Select_stmt() ISelect_stmtContext - Update_stmt() IUpdate_stmtContext - - // IsSql_stmtContext differentiates from other interfaces. - IsSql_stmtContext() -} - -type Sql_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySql_stmtContext() *Sql_stmtContext { - var p = new(Sql_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_sql_stmt - return p -} - -func InitEmptySql_stmtContext(p *Sql_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_sql_stmt -} - -func (*Sql_stmtContext) IsSql_stmtContext() {} - -func NewSql_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Sql_stmtContext { - var p = new(Sql_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_sql_stmt - - return p -} - -func (s *Sql_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Sql_stmtContext) Delete_stmt() IDelete_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IDelete_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IDelete_stmtContext) -} - -func (s *Sql_stmtContext) Insert_stmt() IInsert_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IInsert_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IInsert_stmtContext) -} - -func (s *Sql_stmtContext) Select_stmt() ISelect_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISelect_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISelect_stmtContext) -} - -func (s *Sql_stmtContext) Update_stmt() IUpdate_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUpdate_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IUpdate_stmtContext) -} - -func (s *Sql_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Sql_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Sql_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSql_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Sql_stmt() (localctx ISql_stmtContext) { - localctx = NewSql_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 4, SQLParserRULE_sql_stmt) - p.EnterOuterAlt(localctx, 1) - p.SetState(144) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 5, p.GetParserRuleContext()) { - case 1: - { - p.SetState(140) - p.Delete_stmt() - } - - case 2: - { - p.SetState(141) - p.Insert_stmt() - } - - case 3: - { - p.SetState(142) - p.Select_stmt() - } - - case 4: - { - p.SetState(143) - p.Update_stmt() - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IIndexed_columnContext is an interface to support dynamic dispatch. -type IIndexed_columnContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Column_name() IColumn_nameContext - - // IsIndexed_columnContext differentiates from other interfaces. - IsIndexed_columnContext() -} - -type Indexed_columnContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyIndexed_columnContext() *Indexed_columnContext { - var p = new(Indexed_columnContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_indexed_column - return p -} - -func InitEmptyIndexed_columnContext(p *Indexed_columnContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_indexed_column -} - -func (*Indexed_columnContext) IsIndexed_columnContext() {} - -func NewIndexed_columnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Indexed_columnContext { - var p = new(Indexed_columnContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_indexed_column - - return p -} - -func (s *Indexed_columnContext) GetParser() antlr.Parser { return s.parser } - -func (s *Indexed_columnContext) Column_name() IColumn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Indexed_columnContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Indexed_columnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Indexed_columnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitIndexed_column(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Indexed_column() (localctx IIndexed_columnContext) { - localctx = NewIndexed_columnContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 6, SQLParserRULE_indexed_column) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(146) - p.Column_name() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICte_table_nameContext is an interface to support dynamic dispatch. -type ICte_table_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Table_name() ITable_nameContext - OPEN_PAR() antlr.TerminalNode - AllColumn_name() []IColumn_nameContext - Column_name(i int) IColumn_nameContext - CLOSE_PAR() antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsCte_table_nameContext differentiates from other interfaces. - IsCte_table_nameContext() -} - -type Cte_table_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCte_table_nameContext() *Cte_table_nameContext { - var p = new(Cte_table_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_cte_table_name - return p -} - -func InitEmptyCte_table_nameContext(p *Cte_table_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_cte_table_name -} - -func (*Cte_table_nameContext) IsCte_table_nameContext() {} - -func NewCte_table_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Cte_table_nameContext { - var p = new(Cte_table_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_cte_table_name - - return p -} - -func (s *Cte_table_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Cte_table_nameContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Cte_table_nameContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Cte_table_nameContext) AllColumn_name() []IColumn_nameContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IColumn_nameContext); ok { - len++ - } - } - - tst := make([]IColumn_nameContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IColumn_nameContext); ok { - tst[i] = t.(IColumn_nameContext) - i++ - } - } - - return tst -} - -func (s *Cte_table_nameContext) Column_name(i int) IColumn_nameContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Cte_table_nameContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Cte_table_nameContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Cte_table_nameContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Cte_table_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Cte_table_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Cte_table_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCte_table_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Cte_table_name() (localctx ICte_table_nameContext) { - localctx = NewCte_table_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 8, SQLParserRULE_cte_table_name) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(148) - p.Table_name() - } - p.SetState(160) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserOPEN_PAR { - { - p.SetState(149) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(150) - p.Column_name() - } - p.SetState(155) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(151) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(152) - p.Column_name() - } - - p.SetState(157) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(158) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICommon_table_expressionContext is an interface to support dynamic dispatch. -type ICommon_table_expressionContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Cte_table_name() ICte_table_nameContext - AS_() antlr.TerminalNode - OPEN_PAR() antlr.TerminalNode - Select_core() ISelect_coreContext - CLOSE_PAR() antlr.TerminalNode - - // IsCommon_table_expressionContext differentiates from other interfaces. - IsCommon_table_expressionContext() -} - -type Common_table_expressionContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCommon_table_expressionContext() *Common_table_expressionContext { - var p = new(Common_table_expressionContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_common_table_expression - return p -} - -func InitEmptyCommon_table_expressionContext(p *Common_table_expressionContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_common_table_expression -} - -func (*Common_table_expressionContext) IsCommon_table_expressionContext() {} - -func NewCommon_table_expressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Common_table_expressionContext { - var p = new(Common_table_expressionContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_common_table_expression - - return p -} - -func (s *Common_table_expressionContext) GetParser() antlr.Parser { return s.parser } - -func (s *Common_table_expressionContext) Cte_table_name() ICte_table_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICte_table_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICte_table_nameContext) -} - -func (s *Common_table_expressionContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Common_table_expressionContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Common_table_expressionContext) Select_core() ISelect_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISelect_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISelect_coreContext) -} - -func (s *Common_table_expressionContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Common_table_expressionContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Common_table_expressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Common_table_expressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCommon_table_expression(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Common_table_expression() (localctx ICommon_table_expressionContext) { - localctx = NewCommon_table_expressionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 10, SQLParserRULE_common_table_expression) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(162) - p.Cte_table_name() - } - { - p.SetState(163) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(164) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(165) - p.Select_core() - } - { - p.SetState(166) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICommon_table_stmtContext is an interface to support dynamic dispatch. -type ICommon_table_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - WITH_() antlr.TerminalNode - AllCommon_table_expression() []ICommon_table_expressionContext - Common_table_expression(i int) ICommon_table_expressionContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsCommon_table_stmtContext differentiates from other interfaces. - IsCommon_table_stmtContext() -} - -type Common_table_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCommon_table_stmtContext() *Common_table_stmtContext { - var p = new(Common_table_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_common_table_stmt - return p -} - -func InitEmptyCommon_table_stmtContext(p *Common_table_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_common_table_stmt -} - -func (*Common_table_stmtContext) IsCommon_table_stmtContext() {} - -func NewCommon_table_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Common_table_stmtContext { - var p = new(Common_table_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_common_table_stmt - - return p -} - -func (s *Common_table_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Common_table_stmtContext) WITH_() antlr.TerminalNode { - return s.GetToken(SQLParserWITH_, 0) -} - -func (s *Common_table_stmtContext) AllCommon_table_expression() []ICommon_table_expressionContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ICommon_table_expressionContext); ok { - len++ - } - } - - tst := make([]ICommon_table_expressionContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ICommon_table_expressionContext); ok { - tst[i] = t.(ICommon_table_expressionContext) - i++ - } - } - - return tst -} - -func (s *Common_table_stmtContext) Common_table_expression(i int) ICommon_table_expressionContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICommon_table_expressionContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ICommon_table_expressionContext) -} - -func (s *Common_table_stmtContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Common_table_stmtContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Common_table_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Common_table_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Common_table_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCommon_table_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Common_table_stmt() (localctx ICommon_table_stmtContext) { - localctx = NewCommon_table_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 12, SQLParserRULE_common_table_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(168) - p.Match(SQLParserWITH_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(169) - p.Common_table_expression() - } - p.SetState(174) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(170) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(171) - p.Common_table_expression() - } - - p.SetState(176) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IDelete_coreContext is an interface to support dynamic dispatch. -type IDelete_coreContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - DELETE_() antlr.TerminalNode - FROM_() antlr.TerminalNode - Qualified_table_name() IQualified_table_nameContext - WHERE_() antlr.TerminalNode - Expr() IExprContext - Returning_clause() IReturning_clauseContext - - // IsDelete_coreContext differentiates from other interfaces. - IsDelete_coreContext() -} - -type Delete_coreContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyDelete_coreContext() *Delete_coreContext { - var p = new(Delete_coreContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_delete_core - return p -} - -func InitEmptyDelete_coreContext(p *Delete_coreContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_delete_core -} - -func (*Delete_coreContext) IsDelete_coreContext() {} - -func NewDelete_coreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Delete_coreContext { - var p = new(Delete_coreContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_delete_core - - return p -} - -func (s *Delete_coreContext) GetParser() antlr.Parser { return s.parser } - -func (s *Delete_coreContext) DELETE_() antlr.TerminalNode { - return s.GetToken(SQLParserDELETE_, 0) -} - -func (s *Delete_coreContext) FROM_() antlr.TerminalNode { - return s.GetToken(SQLParserFROM_, 0) -} - -func (s *Delete_coreContext) Qualified_table_name() IQualified_table_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IQualified_table_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IQualified_table_nameContext) -} - -func (s *Delete_coreContext) WHERE_() antlr.TerminalNode { - return s.GetToken(SQLParserWHERE_, 0) -} - -func (s *Delete_coreContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Delete_coreContext) Returning_clause() IReturning_clauseContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IReturning_clauseContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IReturning_clauseContext) -} - -func (s *Delete_coreContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Delete_coreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Delete_coreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitDelete_core(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Delete_core() (localctx IDelete_coreContext) { - localctx = NewDelete_coreContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 14, SQLParserRULE_delete_core) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(177) - p.Match(SQLParserDELETE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(178) - p.Match(SQLParserFROM_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(179) - p.Qualified_table_name() - } - p.SetState(182) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWHERE_ { - { - p.SetState(180) - p.Match(SQLParserWHERE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(181) - p.expr(0) - } - - } - p.SetState(185) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserRETURNING_ { - { - p.SetState(184) - p.Returning_clause() - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IDelete_stmtContext is an interface to support dynamic dispatch. -type IDelete_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Delete_core() IDelete_coreContext - Common_table_stmt() ICommon_table_stmtContext - - // IsDelete_stmtContext differentiates from other interfaces. - IsDelete_stmtContext() -} - -type Delete_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyDelete_stmtContext() *Delete_stmtContext { - var p = new(Delete_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_delete_stmt - return p -} - -func InitEmptyDelete_stmtContext(p *Delete_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_delete_stmt -} - -func (*Delete_stmtContext) IsDelete_stmtContext() {} - -func NewDelete_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Delete_stmtContext { - var p = new(Delete_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_delete_stmt - - return p -} - -func (s *Delete_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Delete_stmtContext) Delete_core() IDelete_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IDelete_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IDelete_coreContext) -} - -func (s *Delete_stmtContext) Common_table_stmt() ICommon_table_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICommon_table_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICommon_table_stmtContext) -} - -func (s *Delete_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Delete_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Delete_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitDelete_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Delete_stmt() (localctx IDelete_stmtContext) { - localctx = NewDelete_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 16, SQLParserRULE_delete_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(188) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWITH_ { - { - p.SetState(187) - p.Common_table_stmt() - } - - } - { - p.SetState(190) - p.Delete_core() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IVariableContext is an interface to support dynamic dispatch. -type IVariableContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - BIND_PARAMETER() antlr.TerminalNode - - // IsVariableContext differentiates from other interfaces. - IsVariableContext() -} - -type VariableContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyVariableContext() *VariableContext { - var p = new(VariableContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_variable - return p -} - -func InitEmptyVariableContext(p *VariableContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_variable -} - -func (*VariableContext) IsVariableContext() {} - -func NewVariableContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableContext { - var p = new(VariableContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_variable - - return p -} - -func (s *VariableContext) GetParser() antlr.Parser { return s.parser } - -func (s *VariableContext) BIND_PARAMETER() antlr.TerminalNode { - return s.GetToken(SQLParserBIND_PARAMETER, 0) -} - -func (s *VariableContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *VariableContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *VariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitVariable(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Variable() (localctx IVariableContext) { - localctx = NewVariableContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 18, SQLParserRULE_variable) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(192) - p.Match(SQLParserBIND_PARAMETER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFunction_callContext is an interface to support dynamic dispatch. -type IFunction_callContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsFunction_callContext differentiates from other interfaces. - IsFunction_callContext() -} - -type Function_callContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyFunction_callContext() *Function_callContext { - var p = new(Function_callContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_call - return p -} - -func InitEmptyFunction_callContext(p *Function_callContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_call -} - -func (*Function_callContext) IsFunction_callContext() {} - -func NewFunction_callContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Function_callContext { - var p = new(Function_callContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_function_call - - return p -} - -func (s *Function_callContext) GetParser() antlr.Parser { return s.parser } - -func (s *Function_callContext) CopyAll(ctx *Function_callContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *Function_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Function_callContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type Normal_function_callContext struct { - Function_callContext -} - -func NewNormal_function_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Normal_function_callContext { - var p = new(Normal_function_callContext) - - InitEmptyFunction_callContext(&p.Function_callContext) - p.parser = parser - p.CopyAll(ctx.(*Function_callContext)) - - return p -} - -func (s *Normal_function_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Normal_function_callContext) Function_name() IFunction_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFunction_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFunction_nameContext) -} - -func (s *Normal_function_callContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Normal_function_callContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Normal_function_callContext) STAR() antlr.TerminalNode { - return s.GetToken(SQLParserSTAR, 0) -} - -func (s *Normal_function_callContext) Expr_list() IExpr_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpr_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpr_listContext) -} - -func (s *Normal_function_callContext) DISTINCT_() antlr.TerminalNode { - return s.GetToken(SQLParserDISTINCT_, 0) -} - -func (s *Normal_function_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitNormal_function_call(s) - - default: - return t.VisitChildren(s) - } -} - -type Foreign_function_callContext struct { - Function_callContext - dbid IExprContext - procedure IExprContext -} - -func NewForeign_function_callContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Foreign_function_callContext { - var p = new(Foreign_function_callContext) - - InitEmptyFunction_callContext(&p.Function_callContext) - p.parser = parser - p.CopyAll(ctx.(*Function_callContext)) - - return p -} - -func (s *Foreign_function_callContext) GetDbid() IExprContext { return s.dbid } - -func (s *Foreign_function_callContext) GetProcedure() IExprContext { return s.procedure } - -func (s *Foreign_function_callContext) SetDbid(v IExprContext) { s.dbid = v } - -func (s *Foreign_function_callContext) SetProcedure(v IExprContext) { s.procedure = v } - -func (s *Foreign_function_callContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Foreign_function_callContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Foreign_function_callContext) L_BRACKET() antlr.TerminalNode { - return s.GetToken(SQLParserL_BRACKET, 0) -} - -func (s *Foreign_function_callContext) COMMA() antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, 0) -} - -func (s *Foreign_function_callContext) R_BRACKET() antlr.TerminalNode { - return s.GetToken(SQLParserR_BRACKET, 0) -} - -func (s *Foreign_function_callContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Foreign_function_callContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Foreign_function_callContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Foreign_function_callContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Foreign_function_callContext) Expr_list() IExpr_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpr_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpr_listContext) -} - -func (s *Foreign_function_callContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitForeign_function_call(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Function_call() (localctx IFunction_callContext) { - localctx = NewFunction_callContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 20, SQLParserRULE_function_call) - var _la int - - p.SetState(217) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 15, p.GetParserRuleContext()) { - case 1: - localctx = NewNormal_function_callContext(p, localctx) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(194) - p.Function_name() - } - { - p.SetState(195) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(201) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - switch p.GetTokenStream().LA(1) { - case SQLParserOPEN_PAR, SQLParserPLUS, SQLParserMINUS, SQLParserCASE_, SQLParserDISTINCT_, SQLParserEXISTS_, SQLParserLIKE_, SQLParserNOT_, SQLParserREPLACE_, SQLParserBOOLEAN_LITERAL, SQLParserNUMERIC_LITERAL, SQLParserBLOB_LITERAL, SQLParserTEXT_LITERAL, SQLParserNULL_LITERAL, SQLParserIDENTIFIER, SQLParserBIND_PARAMETER: - p.SetState(197) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserDISTINCT_ { - { - p.SetState(196) - p.Match(SQLParserDISTINCT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(199) - p.Expr_list() - } - - case SQLParserSTAR: - { - p.SetState(200) - p.Match(SQLParserSTAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserCLOSE_PAR: - - default: - } - { - p.SetState(203) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 2: - localctx = NewForeign_function_callContext(p, localctx) - p.EnterOuterAlt(localctx, 2) - { - p.SetState(205) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(206) - p.Match(SQLParserL_BRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(207) - - var _x = p.expr(0) - - localctx.(*Foreign_function_callContext).dbid = _x - } - { - p.SetState(208) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(209) - - var _x = p.expr(0) - - localctx.(*Foreign_function_callContext).procedure = _x - } - { - p.SetState(210) - p.Match(SQLParserR_BRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(211) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(213) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2305851805575154696) != 0) || ((int64((_la-65)) & ^0x3f) == 0 && ((int64(1)<<(_la-65))&532677121) != 0) { - { - p.SetState(212) - p.Expr_list() - } - - } - { - p.SetState(215) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IColumn_refContext is an interface to support dynamic dispatch. -type IColumn_refContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Column_name() IColumn_nameContext - Table_name() ITable_nameContext - DOT() antlr.TerminalNode - - // IsColumn_refContext differentiates from other interfaces. - IsColumn_refContext() -} - -type Column_refContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyColumn_refContext() *Column_refContext { - var p = new(Column_refContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_ref - return p -} - -func InitEmptyColumn_refContext(p *Column_refContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_ref -} - -func (*Column_refContext) IsColumn_refContext() {} - -func NewColumn_refContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_refContext { - var p = new(Column_refContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_column_ref - - return p -} - -func (s *Column_refContext) GetParser() antlr.Parser { return s.parser } - -func (s *Column_refContext) Column_name() IColumn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Column_refContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Column_refContext) DOT() antlr.TerminalNode { - return s.GetToken(SQLParserDOT, 0) -} - -func (s *Column_refContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_refContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Column_refContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitColumn_ref(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Column_ref() (localctx IColumn_refContext) { - localctx = NewColumn_refContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 22, SQLParserRULE_column_ref) - p.EnterOuterAlt(localctx, 1) - p.SetState(222) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 16, p.GetParserRuleContext()) == 1 { - { - p.SetState(219) - p.Table_name() - } - { - p.SetState(220) - p.Match(SQLParserDOT) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } else if p.HasError() { // JIM - goto errorExit - } - { - p.SetState(224) - p.Column_name() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IWhen_clauseContext is an interface to support dynamic dispatch. -type IWhen_clauseContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetCondition returns the condition rule contexts. - GetCondition() IExprContext - - // GetResult returns the result rule contexts. - GetResult() IExprContext - - // SetCondition sets the condition rule contexts. - SetCondition(IExprContext) - - // SetResult sets the result rule contexts. - SetResult(IExprContext) - - // Getter signatures - WHEN_() antlr.TerminalNode - THEN_() antlr.TerminalNode - AllExpr() []IExprContext - Expr(i int) IExprContext - - // IsWhen_clauseContext differentiates from other interfaces. - IsWhen_clauseContext() -} - -type When_clauseContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - condition IExprContext - result IExprContext -} - -func NewEmptyWhen_clauseContext() *When_clauseContext { - var p = new(When_clauseContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_when_clause - return p -} - -func InitEmptyWhen_clauseContext(p *When_clauseContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_when_clause -} - -func (*When_clauseContext) IsWhen_clauseContext() {} - -func NewWhen_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *When_clauseContext { - var p = new(When_clauseContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_when_clause - - return p -} - -func (s *When_clauseContext) GetParser() antlr.Parser { return s.parser } - -func (s *When_clauseContext) GetCondition() IExprContext { return s.condition } - -func (s *When_clauseContext) GetResult() IExprContext { return s.result } - -func (s *When_clauseContext) SetCondition(v IExprContext) { s.condition = v } - -func (s *When_clauseContext) SetResult(v IExprContext) { s.result = v } - -func (s *When_clauseContext) WHEN_() antlr.TerminalNode { - return s.GetToken(SQLParserWHEN_, 0) -} - -func (s *When_clauseContext) THEN_() antlr.TerminalNode { - return s.GetToken(SQLParserTHEN_, 0) -} - -func (s *When_clauseContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *When_clauseContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *When_clauseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *When_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *When_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitWhen_clause(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) When_clause() (localctx IWhen_clauseContext) { - localctx = NewWhen_clauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 24, SQLParserRULE_when_clause) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(226) - p.Match(SQLParserWHEN_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(227) - - var _x = p.expr(0) - - localctx.(*When_clauseContext).condition = _x - } - { - p.SetState(228) - p.Match(SQLParserTHEN_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(229) - - var _x = p.expr(0) - - localctx.(*When_clauseContext).result = _x - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExprContext is an interface to support dynamic dispatch. -type IExprContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - // IsExprContext differentiates from other interfaces. - IsExprContext() -} - -type ExprContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExprContext() *ExprContext { - var p = new(ExprContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_expr - return p -} - -func InitEmptyExprContext(p *ExprContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_expr -} - -func (*ExprContext) IsExprContext() {} - -func NewExprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExprContext { - var p = new(ExprContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_expr - - return p -} - -func (s *ExprContext) GetParser() antlr.Parser { return s.parser } - -func (s *ExprContext) CopyAll(ctx *ExprContext) { - s.CopyFrom(&ctx.BaseParserRuleContext) -} - -func (s *ExprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -type Subquery_exprContext struct { - ExprContext -} - -func NewSubquery_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Subquery_exprContext { - var p = new(Subquery_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Subquery_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Subquery_exprContext) Subquery() ISubqueryContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISubqueryContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISubqueryContext) -} - -func (s *Subquery_exprContext) EXISTS_() antlr.TerminalNode { - return s.GetToken(SQLParserEXISTS_, 0) -} - -func (s *Subquery_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *Subquery_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSubquery_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Logical_not_exprContext struct { - ExprContext -} - -func NewLogical_not_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Logical_not_exprContext { - var p = new(Logical_not_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Logical_not_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Logical_not_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *Logical_not_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Logical_not_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitLogical_not_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Boolean_literal_exprContext struct { - ExprContext -} - -func NewBoolean_literal_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Boolean_literal_exprContext { - var p = new(Boolean_literal_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Boolean_literal_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Boolean_literal_exprContext) BOOLEAN_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserBOOLEAN_LITERAL, 0) -} - -func (s *Boolean_literal_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Boolean_literal_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitBoolean_literal_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Comparison_exprContext struct { - ExprContext - left IExprContext - right IExprContext -} - -func NewComparison_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Comparison_exprContext { - var p = new(Comparison_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Comparison_exprContext) GetLeft() IExprContext { return s.left } - -func (s *Comparison_exprContext) GetRight() IExprContext { return s.right } - -func (s *Comparison_exprContext) SetLeft(v IExprContext) { s.left = v } - -func (s *Comparison_exprContext) SetRight(v IExprContext) { s.right = v } - -func (s *Comparison_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Comparison_exprContext) ComparisonOperator() IComparisonOperatorContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IComparisonOperatorContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IComparisonOperatorContext) -} - -func (s *Comparison_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Comparison_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Comparison_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitComparison_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Like_exprContext struct { - ExprContext - elem IExprContext - operator antlr.Token - pattern IExprContext - escape IExprContext -} - -func NewLike_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Like_exprContext { - var p = new(Like_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Like_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *Like_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Like_exprContext) GetElem() IExprContext { return s.elem } - -func (s *Like_exprContext) GetPattern() IExprContext { return s.pattern } - -func (s *Like_exprContext) GetEscape() IExprContext { return s.escape } - -func (s *Like_exprContext) SetElem(v IExprContext) { s.elem = v } - -func (s *Like_exprContext) SetPattern(v IExprContext) { s.pattern = v } - -func (s *Like_exprContext) SetEscape(v IExprContext) { s.escape = v } - -func (s *Like_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Like_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Like_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Like_exprContext) LIKE_() antlr.TerminalNode { - return s.GetToken(SQLParserLIKE_, 0) -} - -func (s *Like_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *Like_exprContext) ESCAPE_() antlr.TerminalNode { - return s.GetToken(SQLParserESCAPE_, 0) -} - -func (s *Like_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitLike_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Null_exprContext struct { - ExprContext -} - -func NewNull_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Null_exprContext { - var p = new(Null_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Null_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Null_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Null_exprContext) ISNULL_() antlr.TerminalNode { - return s.GetToken(SQLParserISNULL_, 0) -} - -func (s *Null_exprContext) NOTNULL_() antlr.TerminalNode { - return s.GetToken(SQLParserNOTNULL_, 0) -} - -func (s *Null_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitNull_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Column_exprContext struct { - ExprContext -} - -func NewColumn_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Column_exprContext { - var p = new(Column_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Column_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_exprContext) Column_ref() IColumn_refContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_refContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_refContext) -} - -func (s *Column_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Column_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitColumn_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type In_subquery_exprContext struct { - ExprContext - elem IExprContext - operator antlr.Token -} - -func NewIn_subquery_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *In_subquery_exprContext { - var p = new(In_subquery_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *In_subquery_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *In_subquery_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *In_subquery_exprContext) GetElem() IExprContext { return s.elem } - -func (s *In_subquery_exprContext) SetElem(v IExprContext) { s.elem = v } - -func (s *In_subquery_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *In_subquery_exprContext) Subquery() ISubqueryContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISubqueryContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISubqueryContext) -} - -func (s *In_subquery_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *In_subquery_exprContext) IN_() antlr.TerminalNode { - return s.GetToken(SQLParserIN_, 0) -} - -func (s *In_subquery_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *In_subquery_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitIn_subquery_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Arithmetic_exprContext struct { - ExprContext - left IExprContext - operator antlr.Token - right IExprContext -} - -func NewArithmetic_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Arithmetic_exprContext { - var p = new(Arithmetic_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Arithmetic_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *Arithmetic_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Arithmetic_exprContext) GetLeft() IExprContext { return s.left } - -func (s *Arithmetic_exprContext) GetRight() IExprContext { return s.right } - -func (s *Arithmetic_exprContext) SetLeft(v IExprContext) { s.left = v } - -func (s *Arithmetic_exprContext) SetRight(v IExprContext) { s.right = v } - -func (s *Arithmetic_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Arithmetic_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Arithmetic_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Arithmetic_exprContext) STAR() antlr.TerminalNode { - return s.GetToken(SQLParserSTAR, 0) -} - -func (s *Arithmetic_exprContext) DIV() antlr.TerminalNode { - return s.GetToken(SQLParserDIV, 0) -} - -func (s *Arithmetic_exprContext) MOD() antlr.TerminalNode { - return s.GetToken(SQLParserMOD, 0) -} - -func (s *Arithmetic_exprContext) PLUS() antlr.TerminalNode { - return s.GetToken(SQLParserPLUS, 0) -} - -func (s *Arithmetic_exprContext) MINUS() antlr.TerminalNode { - return s.GetToken(SQLParserMINUS, 0) -} - -func (s *Arithmetic_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitArithmetic_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Logical_binary_exprContext struct { - ExprContext - left IExprContext - operator antlr.Token - right IExprContext -} - -func NewLogical_binary_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Logical_binary_exprContext { - var p = new(Logical_binary_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Logical_binary_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *Logical_binary_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Logical_binary_exprContext) GetLeft() IExprContext { return s.left } - -func (s *Logical_binary_exprContext) GetRight() IExprContext { return s.right } - -func (s *Logical_binary_exprContext) SetLeft(v IExprContext) { s.left = v } - -func (s *Logical_binary_exprContext) SetRight(v IExprContext) { s.right = v } - -func (s *Logical_binary_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Logical_binary_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Logical_binary_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Logical_binary_exprContext) AND_() antlr.TerminalNode { - return s.GetToken(SQLParserAND_, 0) -} - -func (s *Logical_binary_exprContext) OR_() antlr.TerminalNode { - return s.GetToken(SQLParserOR_, 0) -} - -func (s *Logical_binary_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitLogical_binary_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Variable_exprContext struct { - ExprContext -} - -func NewVariable_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Variable_exprContext { - var p = new(Variable_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Variable_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Variable_exprContext) Variable() IVariableContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IVariableContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IVariableContext) -} - -func (s *Variable_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Variable_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitVariable_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Text_literal_exprContext struct { - ExprContext -} - -func NewText_literal_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Text_literal_exprContext { - var p = new(Text_literal_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Text_literal_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Text_literal_exprContext) TEXT_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserTEXT_LITERAL, 0) -} - -func (s *Text_literal_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Text_literal_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitText_literal_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Unary_exprContext struct { - ExprContext - operator antlr.Token -} - -func NewUnary_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Unary_exprContext { - var p = new(Unary_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Unary_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *Unary_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Unary_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Unary_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Unary_exprContext) MINUS() antlr.TerminalNode { - return s.GetToken(SQLParserMINUS, 0) -} - -func (s *Unary_exprContext) PLUS() antlr.TerminalNode { - return s.GetToken(SQLParserPLUS, 0) -} - -func (s *Unary_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUnary_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Collate_exprContext struct { - ExprContext -} - -func NewCollate_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Collate_exprContext { - var p = new(Collate_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Collate_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Collate_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Collate_exprContext) COLLATE_() antlr.TerminalNode { - return s.GetToken(SQLParserCOLLATE_, 0) -} - -func (s *Collate_exprContext) Collation_name() ICollation_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICollation_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICollation_nameContext) -} - -func (s *Collate_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCollate_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Parenthesized_exprContext struct { - ExprContext -} - -func NewParenthesized_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Parenthesized_exprContext { - var p = new(Parenthesized_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Parenthesized_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Parenthesized_exprContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Parenthesized_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Parenthesized_exprContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Parenthesized_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Parenthesized_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitParenthesized_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Between_exprContext struct { - ExprContext - elem IExprContext - operator antlr.Token - low IExprContext - high IExprContext -} - -func NewBetween_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Between_exprContext { - var p = new(Between_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Between_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *Between_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *Between_exprContext) GetElem() IExprContext { return s.elem } - -func (s *Between_exprContext) GetLow() IExprContext { return s.low } - -func (s *Between_exprContext) GetHigh() IExprContext { return s.high } - -func (s *Between_exprContext) SetElem(v IExprContext) { s.elem = v } - -func (s *Between_exprContext) SetLow(v IExprContext) { s.low = v } - -func (s *Between_exprContext) SetHigh(v IExprContext) { s.high = v } - -func (s *Between_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Between_exprContext) AND_() antlr.TerminalNode { - return s.GetToken(SQLParserAND_, 0) -} - -func (s *Between_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Between_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Between_exprContext) BETWEEN_() antlr.TerminalNode { - return s.GetToken(SQLParserBETWEEN_, 0) -} - -func (s *Between_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *Between_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitBetween_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Expr_list_exprContext struct { - ExprContext -} - -func NewExpr_list_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Expr_list_exprContext { - var p = new(Expr_list_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Expr_list_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_list_exprContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Expr_list_exprContext) Expr_list() IExpr_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpr_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpr_listContext) -} - -func (s *Expr_list_exprContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Expr_list_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitExpr_list_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Numeric_literal_exprContext struct { - ExprContext -} - -func NewNumeric_literal_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Numeric_literal_exprContext { - var p = new(Numeric_literal_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Numeric_literal_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Numeric_literal_exprContext) NUMERIC_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserNUMERIC_LITERAL, 0) -} - -func (s *Numeric_literal_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Numeric_literal_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitNumeric_literal_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Null_literal_exprContext struct { - ExprContext -} - -func NewNull_literal_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Null_literal_exprContext { - var p = new(Null_literal_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Null_literal_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Null_literal_exprContext) NULL_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserNULL_LITERAL, 0) -} - -func (s *Null_literal_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Null_literal_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitNull_literal_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type In_list_exprContext struct { - ExprContext - elem IExprContext - operator antlr.Token -} - -func NewIn_list_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *In_list_exprContext { - var p = new(In_list_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *In_list_exprContext) GetOperator() antlr.Token { return s.operator } - -func (s *In_list_exprContext) SetOperator(v antlr.Token) { s.operator = v } - -func (s *In_list_exprContext) GetElem() IExprContext { return s.elem } - -func (s *In_list_exprContext) SetElem(v IExprContext) { s.elem = v } - -func (s *In_list_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *In_list_exprContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *In_list_exprContext) Expr_list() IExpr_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExpr_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExpr_listContext) -} - -func (s *In_list_exprContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *In_list_exprContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *In_list_exprContext) IN_() antlr.TerminalNode { - return s.GetToken(SQLParserIN_, 0) -} - -func (s *In_list_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *In_list_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitIn_list_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Is_exprContext struct { - ExprContext -} - -func NewIs_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Is_exprContext { - var p = new(Is_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Is_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Is_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Is_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Is_exprContext) IS_() antlr.TerminalNode { - return s.GetToken(SQLParserIS_, 0) -} - -func (s *Is_exprContext) BOOLEAN_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserBOOLEAN_LITERAL, 0) -} - -func (s *Is_exprContext) NULL_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserNULL_LITERAL, 0) -} - -func (s *Is_exprContext) NOT_() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_, 0) -} - -func (s *Is_exprContext) DISTINCT_() antlr.TerminalNode { - return s.GetToken(SQLParserDISTINCT_, 0) -} - -func (s *Is_exprContext) FROM_() antlr.TerminalNode { - return s.GetToken(SQLParserFROM_, 0) -} - -func (s *Is_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitIs_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Case_exprContext struct { - ExprContext - case_clause IExprContext - else_clause IExprContext -} - -func NewCase_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Case_exprContext { - var p = new(Case_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Case_exprContext) GetCase_clause() IExprContext { return s.case_clause } - -func (s *Case_exprContext) GetElse_clause() IExprContext { return s.else_clause } - -func (s *Case_exprContext) SetCase_clause(v IExprContext) { s.case_clause = v } - -func (s *Case_exprContext) SetElse_clause(v IExprContext) { s.else_clause = v } - -func (s *Case_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Case_exprContext) CASE_() antlr.TerminalNode { - return s.GetToken(SQLParserCASE_, 0) -} - -func (s *Case_exprContext) END_() antlr.TerminalNode { - return s.GetToken(SQLParserEND_, 0) -} - -func (s *Case_exprContext) AllWhen_clause() []IWhen_clauseContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IWhen_clauseContext); ok { - len++ - } - } - - tst := make([]IWhen_clauseContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IWhen_clauseContext); ok { - tst[i] = t.(IWhen_clauseContext) - i++ - } - } - - return tst -} - -func (s *Case_exprContext) When_clause(i int) IWhen_clauseContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IWhen_clauseContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IWhen_clauseContext) -} - -func (s *Case_exprContext) ELSE_() antlr.TerminalNode { - return s.GetToken(SQLParserELSE_, 0) -} - -func (s *Case_exprContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Case_exprContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Case_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCase_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Function_exprContext struct { - ExprContext -} - -func NewFunction_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Function_exprContext { - var p = new(Function_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Function_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Function_exprContext) Function_call() IFunction_callContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFunction_callContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFunction_callContext) -} - -func (s *Function_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Function_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitFunction_expr(s) - - default: - return t.VisitChildren(s) - } -} - -type Blob_literal_exprContext struct { - ExprContext -} - -func NewBlob_literal_exprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *Blob_literal_exprContext { - var p = new(Blob_literal_exprContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *Blob_literal_exprContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Blob_literal_exprContext) BLOB_LITERAL() antlr.TerminalNode { - return s.GetToken(SQLParserBLOB_LITERAL, 0) -} - -func (s *Blob_literal_exprContext) Type_cast() IType_castContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IType_castContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IType_castContext) -} - -func (s *Blob_literal_exprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitBlob_literal_expr(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Expr() (localctx IExprContext) { - return p.expr(0) -} - -func (p *SQLParser) expr(_p int) (localctx IExprContext) { - var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() - - _parentState := p.GetState() - localctx = NewExprContext(p, p.GetParserRuleContext(), _parentState) - var _prevctx IExprContext = localctx - var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. - _startState := 26 - p.EnterRecursionRule(localctx, 26, SQLParserRULE_expr, _p) - var _la int - - var _alt int - - p.EnterOuterAlt(localctx, 1) - p.SetState(300) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 31, p.GetParserRuleContext()) { - case 1: - localctx = NewText_literal_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - - { - p.SetState(232) - p.Match(SQLParserTEXT_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(234) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 17, p.GetParserRuleContext()) == 1 { - { - p.SetState(233) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 2: - localctx = NewBoolean_literal_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(236) - p.Match(SQLParserBOOLEAN_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(238) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 18, p.GetParserRuleContext()) == 1 { - { - p.SetState(237) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 3: - localctx = NewNumeric_literal_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(240) - p.Match(SQLParserNUMERIC_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(242) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 19, p.GetParserRuleContext()) == 1 { - { - p.SetState(241) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 4: - localctx = NewNull_literal_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(244) - p.Match(SQLParserNULL_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(246) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 20, p.GetParserRuleContext()) == 1 { - { - p.SetState(245) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 5: - localctx = NewBlob_literal_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(248) - p.Match(SQLParserBLOB_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(250) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 21, p.GetParserRuleContext()) == 1 { - { - p.SetState(249) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 6: - localctx = NewVariable_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(252) - p.Variable() - } - p.SetState(254) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 22, p.GetParserRuleContext()) == 1 { - { - p.SetState(253) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 7: - localctx = NewColumn_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(256) - p.Column_ref() - } - p.SetState(258) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 23, p.GetParserRuleContext()) == 1 { - { - p.SetState(257) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 8: - localctx = NewUnary_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(260) - - var _lt = p.GetTokenStream().LT(1) - - localctx.(*Unary_exprContext).operator = _lt - - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserPLUS || _la == SQLParserMINUS) { - var _ri = p.GetErrorHandler().RecoverInline(p) - - localctx.(*Unary_exprContext).operator = _ri - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(261) - p.expr(19) - } - - case 9: - localctx = NewParenthesized_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(262) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(263) - p.expr(0) - } - { - p.SetState(264) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(266) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) == 1 { - { - p.SetState(265) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 10: - localctx = NewSubquery_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - p.SetState(272) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserEXISTS_ || _la == SQLParserNOT_ { - p.SetState(269) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(268) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(271) - p.Match(SQLParserEXISTS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(274) - p.Subquery() - } - - case 11: - localctx = NewCase_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(275) - p.Match(SQLParserCASE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(277) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2305851805575154696) != 0) || ((int64((_la-65)) & ^0x3f) == 0 && ((int64(1)<<(_la-65))&532677121) != 0) { - { - p.SetState(276) - - var _x = p.expr(0) - - localctx.(*Case_exprContext).case_clause = _x - } - - } - p.SetState(280) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for ok := true; ok; ok = _la == SQLParserWHEN_ { - { - p.SetState(279) - p.When_clause() - } - - p.SetState(282) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(286) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserELSE_ { - { - p.SetState(284) - p.Match(SQLParserELSE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(285) - - var _x = p.expr(0) - - localctx.(*Case_exprContext).else_clause = _x - } - - } - { - p.SetState(288) - p.Match(SQLParserEND_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 12: - localctx = NewExpr_list_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(290) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(291) - p.Expr_list() - } - { - p.SetState(292) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 13: - localctx = NewFunction_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(294) - p.Function_call() - } - p.SetState(296) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 30, p.GetParserRuleContext()) == 1 { - { - p.SetState(295) - p.Type_cast() - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 14: - localctx = NewLogical_not_exprContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(298) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(299) - p.expr(3) - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(371) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 40, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - if p.GetParseListeners() != nil { - p.TriggerExitRuleEvent() - } - _prevctx = localctx - p.SetState(369) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 39, p.GetParserRuleContext()) { - case 1: - localctx = NewArithmetic_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Arithmetic_exprContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(302) - - if !(p.Precpred(p.GetParserRuleContext(), 12)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 12)", "")) - goto errorExit - } - { - p.SetState(303) - - var _lt = p.GetTokenStream().LT(1) - - localctx.(*Arithmetic_exprContext).operator = _lt - - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&12800) != 0) { - var _ri = p.GetErrorHandler().RecoverInline(p) - - localctx.(*Arithmetic_exprContext).operator = _ri - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(304) - - var _x = p.expr(13) - - localctx.(*Arithmetic_exprContext).right = _x - } - - case 2: - localctx = NewArithmetic_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Arithmetic_exprContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(305) - - if !(p.Precpred(p.GetParserRuleContext(), 11)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 11)", "")) - goto errorExit - } - { - p.SetState(306) - - var _lt = p.GetTokenStream().LT(1) - - localctx.(*Arithmetic_exprContext).operator = _lt - - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserPLUS || _la == SQLParserMINUS) { - var _ri = p.GetErrorHandler().RecoverInline(p) - - localctx.(*Arithmetic_exprContext).operator = _ri - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(307) - - var _x = p.expr(12) - - localctx.(*Arithmetic_exprContext).right = _x - } - - case 3: - localctx = NewBetween_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Between_exprContext).elem = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(308) - - if !(p.Precpred(p.GetParserRuleContext(), 8)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) - goto errorExit - } - p.SetState(310) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(309) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(312) - - var _m = p.Match(SQLParserBETWEEN_) - - localctx.(*Between_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(313) - - var _x = p.expr(0) - - localctx.(*Between_exprContext).low = _x - } - { - p.SetState(314) - p.Match(SQLParserAND_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(315) - - var _x = p.expr(9) - - localctx.(*Between_exprContext).high = _x - } - - case 4: - localctx = NewComparison_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Comparison_exprContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(317) - - if !(p.Precpred(p.GetParserRuleContext(), 6)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) - goto errorExit - } - { - p.SetState(318) - p.ComparisonOperator() - } - { - p.SetState(319) - - var _x = p.expr(7) - - localctx.(*Comparison_exprContext).right = _x - } - - case 5: - localctx = NewLogical_binary_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Logical_binary_exprContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(321) - - if !(p.Precpred(p.GetParserRuleContext(), 2)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) - goto errorExit - } - { - p.SetState(322) - - var _m = p.Match(SQLParserAND_) - - localctx.(*Logical_binary_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(323) - - var _x = p.expr(3) - - localctx.(*Logical_binary_exprContext).right = _x - } - - case 6: - localctx = NewLogical_binary_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Logical_binary_exprContext).left = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(324) - - if !(p.Precpred(p.GetParserRuleContext(), 1)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) - goto errorExit - } - { - p.SetState(325) - - var _m = p.Match(SQLParserOR_) - - localctx.(*Logical_binary_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(326) - - var _x = p.expr(2) - - localctx.(*Logical_binary_exprContext).right = _x - } - - case 7: - localctx = NewCollate_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(327) - - if !(p.Precpred(p.GetParserRuleContext(), 18)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 18)", "")) - goto errorExit - } - { - p.SetState(328) - p.Match(SQLParserCOLLATE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(329) - p.Collation_name() - } - - case 8: - localctx = NewIn_subquery_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*In_subquery_exprContext).elem = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(330) - - if !(p.Precpred(p.GetParserRuleContext(), 10)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 10)", "")) - goto errorExit - } - p.SetState(332) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(331) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(334) - - var _m = p.Match(SQLParserIN_) - - localctx.(*In_subquery_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(335) - p.Subquery() - } - - case 9: - localctx = NewIn_list_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*In_list_exprContext).elem = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(336) - - if !(p.Precpred(p.GetParserRuleContext(), 9)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) - goto errorExit - } - p.SetState(338) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(337) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(340) - - var _m = p.Match(SQLParserIN_) - - localctx.(*In_list_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(341) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(342) - p.Expr_list() - } - { - p.SetState(343) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 10: - localctx = NewLike_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - localctx.(*Like_exprContext).elem = _prevctx - - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(345) - - if !(p.Precpred(p.GetParserRuleContext(), 7)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 7)", "")) - goto errorExit - } - p.SetState(347) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(346) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(349) - - var _m = p.Match(SQLParserLIKE_) - - localctx.(*Like_exprContext).operator = _m - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(350) - - var _x = p.expr(0) - - localctx.(*Like_exprContext).pattern = _x - } - p.SetState(353) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 36, p.GetParserRuleContext()) == 1 { - { - p.SetState(351) - p.Match(SQLParserESCAPE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(352) - - var _x = p.expr(0) - - localctx.(*Like_exprContext).escape = _x - } - - } else if p.HasError() { // JIM - goto errorExit - } - - case 11: - localctx = NewIs_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(355) - - if !(p.Precpred(p.GetParserRuleContext(), 5)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) - goto errorExit - } - { - p.SetState(356) - p.Match(SQLParserIS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(358) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNOT_ { - { - p.SetState(357) - p.Match(SQLParserNOT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - p.SetState(365) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserDISTINCT_: - { - p.SetState(360) - p.Match(SQLParserDISTINCT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(361) - p.Match(SQLParserFROM_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(362) - p.expr(0) - } - - case SQLParserBOOLEAN_LITERAL: - { - p.SetState(363) - p.Match(SQLParserBOOLEAN_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserNULL_LITERAL: - { - p.SetState(364) - p.Match(SQLParserNULL_LITERAL) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - - case 12: - localctx = NewNull_exprContext(p, NewExprContext(p, _parentctx, _parentState)) - p.PushNewRecursionContext(localctx, _startState, SQLParserRULE_expr) - p.SetState(367) - - if !(p.Precpred(p.GetParserRuleContext(), 4)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) - goto errorExit - } - { - p.SetState(368) - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserISNULL_ || _la == SQLParserNOTNULL_) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - - } - p.SetState(373) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 40, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.UnrollRecursionContexts(_parentctx) - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISubqueryContext is an interface to support dynamic dispatch. -type ISubqueryContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - OPEN_PAR() antlr.TerminalNode - Select_core() ISelect_coreContext - CLOSE_PAR() antlr.TerminalNode - - // IsSubqueryContext differentiates from other interfaces. - IsSubqueryContext() -} - -type SubqueryContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySubqueryContext() *SubqueryContext { - var p = new(SubqueryContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_subquery - return p -} - -func InitEmptySubqueryContext(p *SubqueryContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_subquery -} - -func (*SubqueryContext) IsSubqueryContext() {} - -func NewSubqueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SubqueryContext { - var p = new(SubqueryContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_subquery - - return p -} - -func (s *SubqueryContext) GetParser() antlr.Parser { return s.parser } - -func (s *SubqueryContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *SubqueryContext) Select_core() ISelect_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISelect_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISelect_coreContext) -} - -func (s *SubqueryContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *SubqueryContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *SubqueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *SubqueryContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSubquery(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Subquery() (localctx ISubqueryContext) { - localctx = NewSubqueryContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 28, SQLParserRULE_subquery) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(374) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(375) - p.Select_core() - } - { - p.SetState(376) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IExpr_listContext is an interface to support dynamic dispatch. -type IExpr_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllExpr() []IExprContext - Expr(i int) IExprContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsExpr_listContext differentiates from other interfaces. - IsExpr_listContext() -} - -type Expr_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyExpr_listContext() *Expr_listContext { - var p = new(Expr_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_expr_list - return p -} - -func InitEmptyExpr_listContext(p *Expr_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_expr_list -} - -func (*Expr_listContext) IsExpr_listContext() {} - -func NewExpr_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Expr_listContext { - var p = new(Expr_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_expr_list - - return p -} - -func (s *Expr_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Expr_listContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Expr_listContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Expr_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Expr_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Expr_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Expr_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Expr_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitExpr_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Expr_list() (localctx IExpr_listContext) { - localctx = NewExpr_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 30, SQLParserRULE_expr_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(378) - p.expr(0) - } - p.SetState(383) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(379) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(380) - p.expr(0) - } - - p.SetState(385) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IComparisonOperatorContext is an interface to support dynamic dispatch. -type IComparisonOperatorContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - LT() antlr.TerminalNode - LT_EQ() antlr.TerminalNode - GT() antlr.TerminalNode - GT_EQ() antlr.TerminalNode - ASSIGN() antlr.TerminalNode - NOT_EQ1() antlr.TerminalNode - NOT_EQ2() antlr.TerminalNode - - // IsComparisonOperatorContext differentiates from other interfaces. - IsComparisonOperatorContext() -} - -type ComparisonOperatorContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyComparisonOperatorContext() *ComparisonOperatorContext { - var p = new(ComparisonOperatorContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_comparisonOperator - return p -} - -func InitEmptyComparisonOperatorContext(p *ComparisonOperatorContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_comparisonOperator -} - -func (*ComparisonOperatorContext) IsComparisonOperatorContext() {} - -func NewComparisonOperatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ComparisonOperatorContext { - var p = new(ComparisonOperatorContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_comparisonOperator - - return p -} - -func (s *ComparisonOperatorContext) GetParser() antlr.Parser { return s.parser } - -func (s *ComparisonOperatorContext) LT() antlr.TerminalNode { - return s.GetToken(SQLParserLT, 0) -} - -func (s *ComparisonOperatorContext) LT_EQ() antlr.TerminalNode { - return s.GetToken(SQLParserLT_EQ, 0) -} - -func (s *ComparisonOperatorContext) GT() antlr.TerminalNode { - return s.GetToken(SQLParserGT, 0) -} - -func (s *ComparisonOperatorContext) GT_EQ() antlr.TerminalNode { - return s.GetToken(SQLParserGT_EQ, 0) -} - -func (s *ComparisonOperatorContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(SQLParserASSIGN, 0) -} - -func (s *ComparisonOperatorContext) NOT_EQ1() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_EQ1, 0) -} - -func (s *ComparisonOperatorContext) NOT_EQ2() antlr.TerminalNode { - return s.GetToken(SQLParserNOT_EQ2, 0) -} - -func (s *ComparisonOperatorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ComparisonOperatorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *ComparisonOperatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitComparisonOperator(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) ComparisonOperator() (localctx IComparisonOperatorContext) { - localctx = NewComparisonOperatorContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 32, SQLParserRULE_comparisonOperator) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(386) - _la = p.GetTokenStream().LA(1) - - if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1032448) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICast_typeContext is an interface to support dynamic dispatch. -type ICast_typeContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - L_BRACKET() antlr.TerminalNode - R_BRACKET() antlr.TerminalNode - - // IsCast_typeContext differentiates from other interfaces. - IsCast_typeContext() -} - -type Cast_typeContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCast_typeContext() *Cast_typeContext { - var p = new(Cast_typeContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_cast_type - return p -} - -func InitEmptyCast_typeContext(p *Cast_typeContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_cast_type -} - -func (*Cast_typeContext) IsCast_typeContext() {} - -func NewCast_typeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Cast_typeContext { - var p = new(Cast_typeContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_cast_type - - return p -} - -func (s *Cast_typeContext) GetParser() antlr.Parser { return s.parser } - -func (s *Cast_typeContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Cast_typeContext) L_BRACKET() antlr.TerminalNode { - return s.GetToken(SQLParserL_BRACKET, 0) -} - -func (s *Cast_typeContext) R_BRACKET() antlr.TerminalNode { - return s.GetToken(SQLParserR_BRACKET, 0) -} - -func (s *Cast_typeContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Cast_typeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Cast_typeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCast_type(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Cast_type() (localctx ICast_typeContext) { - localctx = NewCast_typeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 34, SQLParserRULE_cast_type) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(388) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(391) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 42, p.GetParserRuleContext()) == 1 { - { - p.SetState(389) - p.Match(SQLParserL_BRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(390) - p.Match(SQLParserR_BRACKET) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } else if p.HasError() { // JIM - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IType_castContext is an interface to support dynamic dispatch. -type IType_castContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - TYPE_CAST() antlr.TerminalNode - Cast_type() ICast_typeContext - - // IsType_castContext differentiates from other interfaces. - IsType_castContext() -} - -type Type_castContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyType_castContext() *Type_castContext { - var p = new(Type_castContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_type_cast - return p -} - -func InitEmptyType_castContext(p *Type_castContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_type_cast -} - -func (*Type_castContext) IsType_castContext() {} - -func NewType_castContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Type_castContext { - var p = new(Type_castContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_type_cast - - return p -} - -func (s *Type_castContext) GetParser() antlr.Parser { return s.parser } - -func (s *Type_castContext) TYPE_CAST() antlr.TerminalNode { - return s.GetToken(SQLParserTYPE_CAST, 0) -} - -func (s *Type_castContext) Cast_type() ICast_typeContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICast_typeContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICast_typeContext) -} - -func (s *Type_castContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Type_castContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Type_castContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitType_cast(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Type_cast() (localctx IType_castContext) { - localctx = NewType_castContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 36, SQLParserRULE_type_cast) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(393) - p.Match(SQLParserTYPE_CAST) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(394) - p.Cast_type() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IValue_rowContext is an interface to support dynamic dispatch. -type IValue_rowContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - OPEN_PAR() antlr.TerminalNode - AllExpr() []IExprContext - Expr(i int) IExprContext - CLOSE_PAR() antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsValue_rowContext differentiates from other interfaces. - IsValue_rowContext() -} - -type Value_rowContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyValue_rowContext() *Value_rowContext { - var p = new(Value_rowContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_value_row - return p -} - -func InitEmptyValue_rowContext(p *Value_rowContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_value_row -} - -func (*Value_rowContext) IsValue_rowContext() {} - -func NewValue_rowContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Value_rowContext { - var p = new(Value_rowContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_value_row - - return p -} - -func (s *Value_rowContext) GetParser() antlr.Parser { return s.parser } - -func (s *Value_rowContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Value_rowContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Value_rowContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Value_rowContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Value_rowContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Value_rowContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Value_rowContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Value_rowContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Value_rowContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitValue_row(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Value_row() (localctx IValue_rowContext) { - localctx = NewValue_rowContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 38, SQLParserRULE_value_row) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(396) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(397) - p.expr(0) - } - p.SetState(402) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(398) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(399) - p.expr(0) - } - - p.SetState(404) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(405) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IValues_clauseContext is an interface to support dynamic dispatch. -type IValues_clauseContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - VALUES_() antlr.TerminalNode - AllValue_row() []IValue_rowContext - Value_row(i int) IValue_rowContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsValues_clauseContext differentiates from other interfaces. - IsValues_clauseContext() -} - -type Values_clauseContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyValues_clauseContext() *Values_clauseContext { - var p = new(Values_clauseContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_values_clause - return p -} - -func InitEmptyValues_clauseContext(p *Values_clauseContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_values_clause -} - -func (*Values_clauseContext) IsValues_clauseContext() {} - -func NewValues_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Values_clauseContext { - var p = new(Values_clauseContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_values_clause - - return p -} - -func (s *Values_clauseContext) GetParser() antlr.Parser { return s.parser } - -func (s *Values_clauseContext) VALUES_() antlr.TerminalNode { - return s.GetToken(SQLParserVALUES_, 0) -} - -func (s *Values_clauseContext) AllValue_row() []IValue_rowContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IValue_rowContext); ok { - len++ - } - } - - tst := make([]IValue_rowContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IValue_rowContext); ok { - tst[i] = t.(IValue_rowContext) - i++ - } - } - - return tst -} - -func (s *Values_clauseContext) Value_row(i int) IValue_rowContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IValue_rowContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IValue_rowContext) -} - -func (s *Values_clauseContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Values_clauseContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Values_clauseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Values_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Values_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitValues_clause(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Values_clause() (localctx IValues_clauseContext) { - localctx = NewValues_clauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 40, SQLParserRULE_values_clause) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(407) - p.Match(SQLParserVALUES_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(408) - p.Value_row() - } - p.SetState(413) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(409) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(410) - p.Value_row() - } - - p.SetState(415) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IInsert_coreContext is an interface to support dynamic dispatch. -type IInsert_coreContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - INSERT_() antlr.TerminalNode - INTO_() antlr.TerminalNode - Table_name() ITable_nameContext - Values_clause() IValues_clauseContext - AS_() antlr.TerminalNode - Table_alias() ITable_aliasContext - OPEN_PAR() antlr.TerminalNode - AllColumn_name() []IColumn_nameContext - Column_name(i int) IColumn_nameContext - CLOSE_PAR() antlr.TerminalNode - Upsert_clause() IUpsert_clauseContext - Returning_clause() IReturning_clauseContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsInsert_coreContext differentiates from other interfaces. - IsInsert_coreContext() -} - -type Insert_coreContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyInsert_coreContext() *Insert_coreContext { - var p = new(Insert_coreContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_insert_core - return p -} - -func InitEmptyInsert_coreContext(p *Insert_coreContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_insert_core -} - -func (*Insert_coreContext) IsInsert_coreContext() {} - -func NewInsert_coreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Insert_coreContext { - var p = new(Insert_coreContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_insert_core - - return p -} - -func (s *Insert_coreContext) GetParser() antlr.Parser { return s.parser } - -func (s *Insert_coreContext) INSERT_() antlr.TerminalNode { - return s.GetToken(SQLParserINSERT_, 0) -} - -func (s *Insert_coreContext) INTO_() antlr.TerminalNode { - return s.GetToken(SQLParserINTO_, 0) -} - -func (s *Insert_coreContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Insert_coreContext) Values_clause() IValues_clauseContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IValues_clauseContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IValues_clauseContext) -} - -func (s *Insert_coreContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Insert_coreContext) Table_alias() ITable_aliasContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_aliasContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_aliasContext) -} - -func (s *Insert_coreContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Insert_coreContext) AllColumn_name() []IColumn_nameContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IColumn_nameContext); ok { - len++ - } - } - - tst := make([]IColumn_nameContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IColumn_nameContext); ok { - tst[i] = t.(IColumn_nameContext) - i++ - } - } - - return tst -} - -func (s *Insert_coreContext) Column_name(i int) IColumn_nameContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Insert_coreContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Insert_coreContext) Upsert_clause() IUpsert_clauseContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUpsert_clauseContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IUpsert_clauseContext) -} - -func (s *Insert_coreContext) Returning_clause() IReturning_clauseContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IReturning_clauseContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IReturning_clauseContext) -} - -func (s *Insert_coreContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Insert_coreContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Insert_coreContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Insert_coreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Insert_coreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitInsert_core(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Insert_core() (localctx IInsert_coreContext) { - localctx = NewInsert_coreContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 42, SQLParserRULE_insert_core) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(416) - p.Match(SQLParserINSERT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(417) - p.Match(SQLParserINTO_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(418) - p.Table_name() - } - p.SetState(421) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(419) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(420) - p.Table_alias() - } - - } - p.SetState(434) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserOPEN_PAR { - { - p.SetState(423) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(424) - p.Column_name() - } - p.SetState(429) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(425) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(426) - p.Column_name() - } - - p.SetState(431) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(432) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(436) - p.Values_clause() - } - p.SetState(438) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserON_ { - { - p.SetState(437) - p.Upsert_clause() - } - - } - p.SetState(441) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserRETURNING_ { - { - p.SetState(440) - p.Returning_clause() - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IInsert_stmtContext is an interface to support dynamic dispatch. -type IInsert_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Insert_core() IInsert_coreContext - Common_table_stmt() ICommon_table_stmtContext - - // IsInsert_stmtContext differentiates from other interfaces. - IsInsert_stmtContext() -} - -type Insert_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyInsert_stmtContext() *Insert_stmtContext { - var p = new(Insert_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_insert_stmt - return p -} - -func InitEmptyInsert_stmtContext(p *Insert_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_insert_stmt -} - -func (*Insert_stmtContext) IsInsert_stmtContext() {} - -func NewInsert_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Insert_stmtContext { - var p = new(Insert_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_insert_stmt - - return p -} - -func (s *Insert_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Insert_stmtContext) Insert_core() IInsert_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IInsert_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IInsert_coreContext) -} - -func (s *Insert_stmtContext) Common_table_stmt() ICommon_table_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICommon_table_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICommon_table_stmtContext) -} - -func (s *Insert_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Insert_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Insert_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitInsert_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Insert_stmt() (localctx IInsert_stmtContext) { - localctx = NewInsert_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 44, SQLParserRULE_insert_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(444) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWITH_ { - { - p.SetState(443) - p.Common_table_stmt() - } - - } - { - p.SetState(446) - p.Insert_core() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IReturning_clauseContext is an interface to support dynamic dispatch. -type IReturning_clauseContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - RETURNING_() antlr.TerminalNode - AllReturning_clause_result_column() []IReturning_clause_result_columnContext - Returning_clause_result_column(i int) IReturning_clause_result_columnContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsReturning_clauseContext differentiates from other interfaces. - IsReturning_clauseContext() -} - -type Returning_clauseContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyReturning_clauseContext() *Returning_clauseContext { - var p = new(Returning_clauseContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_returning_clause - return p -} - -func InitEmptyReturning_clauseContext(p *Returning_clauseContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_returning_clause -} - -func (*Returning_clauseContext) IsReturning_clauseContext() {} - -func NewReturning_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Returning_clauseContext { - var p = new(Returning_clauseContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_returning_clause - - return p -} - -func (s *Returning_clauseContext) GetParser() antlr.Parser { return s.parser } - -func (s *Returning_clauseContext) RETURNING_() antlr.TerminalNode { - return s.GetToken(SQLParserRETURNING_, 0) -} - -func (s *Returning_clauseContext) AllReturning_clause_result_column() []IReturning_clause_result_columnContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IReturning_clause_result_columnContext); ok { - len++ - } - } - - tst := make([]IReturning_clause_result_columnContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IReturning_clause_result_columnContext); ok { - tst[i] = t.(IReturning_clause_result_columnContext) - i++ - } - } - - return tst -} - -func (s *Returning_clauseContext) Returning_clause_result_column(i int) IReturning_clause_result_columnContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IReturning_clause_result_columnContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IReturning_clause_result_columnContext) -} - -func (s *Returning_clauseContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Returning_clauseContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Returning_clauseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Returning_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Returning_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitReturning_clause(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Returning_clause() (localctx IReturning_clauseContext) { - localctx = NewReturning_clauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 46, SQLParserRULE_returning_clause) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(448) - p.Match(SQLParserRETURNING_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(449) - p.Returning_clause_result_column() - } - p.SetState(454) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(450) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(451) - p.Returning_clause_result_column() - } - - p.SetState(456) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUpsert_updateContext is an interface to support dynamic dispatch. -type IUpsert_updateContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ASSIGN() antlr.TerminalNode - Expr() IExprContext - Column_name() IColumn_nameContext - Column_name_list() IColumn_name_listContext - - // IsUpsert_updateContext differentiates from other interfaces. - IsUpsert_updateContext() -} - -type Upsert_updateContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyUpsert_updateContext() *Upsert_updateContext { - var p = new(Upsert_updateContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_upsert_update - return p -} - -func InitEmptyUpsert_updateContext(p *Upsert_updateContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_upsert_update -} - -func (*Upsert_updateContext) IsUpsert_updateContext() {} - -func NewUpsert_updateContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Upsert_updateContext { - var p = new(Upsert_updateContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_upsert_update - - return p -} - -func (s *Upsert_updateContext) GetParser() antlr.Parser { return s.parser } - -func (s *Upsert_updateContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(SQLParserASSIGN, 0) -} - -func (s *Upsert_updateContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Upsert_updateContext) Column_name() IColumn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Upsert_updateContext) Column_name_list() IColumn_name_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_name_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_name_listContext) -} - -func (s *Upsert_updateContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Upsert_updateContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Upsert_updateContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUpsert_update(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Upsert_update() (localctx IUpsert_updateContext) { - localctx = NewUpsert_updateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 48, SQLParserRULE_upsert_update) - p.EnterOuterAlt(localctx, 1) - p.SetState(459) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserIDENTIFIER: - { - p.SetState(457) - p.Column_name() - } - - case SQLParserOPEN_PAR: - { - p.SetState(458) - p.Column_name_list() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - { - p.SetState(461) - p.Match(SQLParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(462) - p.expr(0) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUpsert_clauseContext is an interface to support dynamic dispatch. -type IUpsert_clauseContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetTarget_expr returns the target_expr rule contexts. - GetTarget_expr() IExprContext - - // GetUpdate_expr returns the update_expr rule contexts. - GetUpdate_expr() IExprContext - - // SetTarget_expr sets the target_expr rule contexts. - SetTarget_expr(IExprContext) - - // SetUpdate_expr sets the update_expr rule contexts. - SetUpdate_expr(IExprContext) - - // Getter signatures - ON_() antlr.TerminalNode - CONFLICT_() antlr.TerminalNode - DO_() antlr.TerminalNode - NOTHING_() antlr.TerminalNode - UPDATE_() antlr.TerminalNode - SET_() antlr.TerminalNode - OPEN_PAR() antlr.TerminalNode - AllIndexed_column() []IIndexed_columnContext - Indexed_column(i int) IIndexed_columnContext - CLOSE_PAR() antlr.TerminalNode - AllUpsert_update() []IUpsert_updateContext - Upsert_update(i int) IUpsert_updateContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - AllWHERE_() []antlr.TerminalNode - WHERE_(i int) antlr.TerminalNode - AllExpr() []IExprContext - Expr(i int) IExprContext - - // IsUpsert_clauseContext differentiates from other interfaces. - IsUpsert_clauseContext() -} - -type Upsert_clauseContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - target_expr IExprContext - update_expr IExprContext -} - -func NewEmptyUpsert_clauseContext() *Upsert_clauseContext { - var p = new(Upsert_clauseContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_upsert_clause - return p -} - -func InitEmptyUpsert_clauseContext(p *Upsert_clauseContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_upsert_clause -} - -func (*Upsert_clauseContext) IsUpsert_clauseContext() {} - -func NewUpsert_clauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Upsert_clauseContext { - var p = new(Upsert_clauseContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_upsert_clause - - return p -} - -func (s *Upsert_clauseContext) GetParser() antlr.Parser { return s.parser } - -func (s *Upsert_clauseContext) GetTarget_expr() IExprContext { return s.target_expr } - -func (s *Upsert_clauseContext) GetUpdate_expr() IExprContext { return s.update_expr } - -func (s *Upsert_clauseContext) SetTarget_expr(v IExprContext) { s.target_expr = v } - -func (s *Upsert_clauseContext) SetUpdate_expr(v IExprContext) { s.update_expr = v } - -func (s *Upsert_clauseContext) ON_() antlr.TerminalNode { - return s.GetToken(SQLParserON_, 0) -} - -func (s *Upsert_clauseContext) CONFLICT_() antlr.TerminalNode { - return s.GetToken(SQLParserCONFLICT_, 0) -} - -func (s *Upsert_clauseContext) DO_() antlr.TerminalNode { - return s.GetToken(SQLParserDO_, 0) -} - -func (s *Upsert_clauseContext) NOTHING_() antlr.TerminalNode { - return s.GetToken(SQLParserNOTHING_, 0) -} - -func (s *Upsert_clauseContext) UPDATE_() antlr.TerminalNode { - return s.GetToken(SQLParserUPDATE_, 0) -} - -func (s *Upsert_clauseContext) SET_() antlr.TerminalNode { - return s.GetToken(SQLParserSET_, 0) -} - -func (s *Upsert_clauseContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Upsert_clauseContext) AllIndexed_column() []IIndexed_columnContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IIndexed_columnContext); ok { - len++ - } - } - - tst := make([]IIndexed_columnContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IIndexed_columnContext); ok { - tst[i] = t.(IIndexed_columnContext) - i++ - } - } - - return tst -} - -func (s *Upsert_clauseContext) Indexed_column(i int) IIndexed_columnContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IIndexed_columnContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IIndexed_columnContext) -} - -func (s *Upsert_clauseContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Upsert_clauseContext) AllUpsert_update() []IUpsert_updateContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IUpsert_updateContext); ok { - len++ - } - } - - tst := make([]IUpsert_updateContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IUpsert_updateContext); ok { - tst[i] = t.(IUpsert_updateContext) - i++ - } - } - - return tst -} - -func (s *Upsert_clauseContext) Upsert_update(i int) IUpsert_updateContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUpsert_updateContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IUpsert_updateContext) -} - -func (s *Upsert_clauseContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Upsert_clauseContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Upsert_clauseContext) AllWHERE_() []antlr.TerminalNode { - return s.GetTokens(SQLParserWHERE_) -} - -func (s *Upsert_clauseContext) WHERE_(i int) antlr.TerminalNode { - return s.GetToken(SQLParserWHERE_, i) -} - -func (s *Upsert_clauseContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Upsert_clauseContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Upsert_clauseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Upsert_clauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Upsert_clauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUpsert_clause(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Upsert_clause() (localctx IUpsert_clauseContext) { - localctx = NewUpsert_clauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 50, SQLParserRULE_upsert_clause) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(464) - p.Match(SQLParserON_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(465) - p.Match(SQLParserCONFLICT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(480) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserOPEN_PAR { - { - p.SetState(466) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(467) - p.Indexed_column() - } - p.SetState(472) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(468) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(469) - p.Indexed_column() - } - - p.SetState(474) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(475) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(478) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWHERE_ { - { - p.SetState(476) - p.Match(SQLParserWHERE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(477) - - var _x = p.expr(0) - - localctx.(*Upsert_clauseContext).target_expr = _x - } - - } - - } - { - p.SetState(482) - p.Match(SQLParserDO_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(498) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserNOTHING_: - { - p.SetState(483) - p.Match(SQLParserNOTHING_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserUPDATE_: - { - p.SetState(484) - p.Match(SQLParserUPDATE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(485) - p.Match(SQLParserSET_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - { - p.SetState(486) - p.Upsert_update() - } - p.SetState(491) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(487) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(488) - p.Upsert_update() - } - - p.SetState(493) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(496) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWHERE_ { - { - p.SetState(494) - p.Match(SQLParserWHERE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(495) - - var _x = p.expr(0) - - localctx.(*Upsert_clauseContext).update_expr = _x - } - - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISelect_coreContext is an interface to support dynamic dispatch. -type ISelect_coreContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - AllSimple_select() []ISimple_selectContext - Simple_select(i int) ISimple_selectContext - AllCompound_operator() []ICompound_operatorContext - Compound_operator(i int) ICompound_operatorContext - Order_by_stmt() IOrder_by_stmtContext - Limit_stmt() ILimit_stmtContext - - // IsSelect_coreContext differentiates from other interfaces. - IsSelect_coreContext() -} - -type Select_coreContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySelect_coreContext() *Select_coreContext { - var p = new(Select_coreContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_select_core - return p -} - -func InitEmptySelect_coreContext(p *Select_coreContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_select_core -} - -func (*Select_coreContext) IsSelect_coreContext() {} - -func NewSelect_coreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Select_coreContext { - var p = new(Select_coreContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_select_core - - return p -} - -func (s *Select_coreContext) GetParser() antlr.Parser { return s.parser } - -func (s *Select_coreContext) AllSimple_select() []ISimple_selectContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ISimple_selectContext); ok { - len++ - } - } - - tst := make([]ISimple_selectContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ISimple_selectContext); ok { - tst[i] = t.(ISimple_selectContext) - i++ - } - } - - return tst -} - -func (s *Select_coreContext) Simple_select(i int) ISimple_selectContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISimple_selectContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ISimple_selectContext) -} - -func (s *Select_coreContext) AllCompound_operator() []ICompound_operatorContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(ICompound_operatorContext); ok { - len++ - } - } - - tst := make([]ICompound_operatorContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(ICompound_operatorContext); ok { - tst[i] = t.(ICompound_operatorContext) - i++ - } - } - - return tst -} - -func (s *Select_coreContext) Compound_operator(i int) ICompound_operatorContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICompound_operatorContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(ICompound_operatorContext) -} - -func (s *Select_coreContext) Order_by_stmt() IOrder_by_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IOrder_by_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IOrder_by_stmtContext) -} - -func (s *Select_coreContext) Limit_stmt() ILimit_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ILimit_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ILimit_stmtContext) -} - -func (s *Select_coreContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Select_coreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Select_coreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSelect_core(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Select_core() (localctx ISelect_coreContext) { - localctx = NewSelect_coreContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 52, SQLParserRULE_select_core) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(500) - p.Simple_select() - } - p.SetState(506) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64((_la-42)) & ^0x3f) == 0 && ((int64(1)<<(_la-42))&274877908993) != 0 { - { - p.SetState(501) - p.Compound_operator() - } - { - p.SetState(502) - p.Simple_select() - } - - p.SetState(508) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(510) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserORDER_ { - { - p.SetState(509) - p.Order_by_stmt() - } - - } - p.SetState(513) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserLIMIT_ { - { - p.SetState(512) - p.Limit_stmt() - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISelect_stmtContext is an interface to support dynamic dispatch. -type ISelect_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Select_core() ISelect_coreContext - Common_table_stmt() ICommon_table_stmtContext - - // IsSelect_stmtContext differentiates from other interfaces. - IsSelect_stmtContext() -} - -type Select_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySelect_stmtContext() *Select_stmtContext { - var p = new(Select_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_select_stmt - return p -} - -func InitEmptySelect_stmtContext(p *Select_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_select_stmt -} - -func (*Select_stmtContext) IsSelect_stmtContext() {} - -func NewSelect_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Select_stmtContext { - var p = new(Select_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_select_stmt - - return p -} - -func (s *Select_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Select_stmtContext) Select_core() ISelect_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISelect_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISelect_coreContext) -} - -func (s *Select_stmtContext) Common_table_stmt() ICommon_table_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICommon_table_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICommon_table_stmtContext) -} - -func (s *Select_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Select_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Select_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSelect_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Select_stmt() (localctx ISelect_stmtContext) { - localctx = NewSelect_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 54, SQLParserRULE_select_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(516) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWITH_ { - { - p.SetState(515) - p.Common_table_stmt() - } - - } - { - p.SetState(518) - p.Select_core() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IJoin_relationContext is an interface to support dynamic dispatch. -type IJoin_relationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetRight_relation returns the right_relation rule contexts. - GetRight_relation() ITable_or_subqueryContext - - // SetRight_relation sets the right_relation rule contexts. - SetRight_relation(ITable_or_subqueryContext) - - // Getter signatures - Join_operator() IJoin_operatorContext - Join_constraint() IJoin_constraintContext - Table_or_subquery() ITable_or_subqueryContext - - // IsJoin_relationContext differentiates from other interfaces. - IsJoin_relationContext() -} - -type Join_relationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - right_relation ITable_or_subqueryContext -} - -func NewEmptyJoin_relationContext() *Join_relationContext { - var p = new(Join_relationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_relation - return p -} - -func InitEmptyJoin_relationContext(p *Join_relationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_relation -} - -func (*Join_relationContext) IsJoin_relationContext() {} - -func NewJoin_relationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Join_relationContext { - var p = new(Join_relationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_join_relation - - return p -} - -func (s *Join_relationContext) GetParser() antlr.Parser { return s.parser } - -func (s *Join_relationContext) GetRight_relation() ITable_or_subqueryContext { return s.right_relation } - -func (s *Join_relationContext) SetRight_relation(v ITable_or_subqueryContext) { s.right_relation = v } - -func (s *Join_relationContext) Join_operator() IJoin_operatorContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IJoin_operatorContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IJoin_operatorContext) -} - -func (s *Join_relationContext) Join_constraint() IJoin_constraintContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IJoin_constraintContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IJoin_constraintContext) -} - -func (s *Join_relationContext) Table_or_subquery() ITable_or_subqueryContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_or_subqueryContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_or_subqueryContext) -} - -func (s *Join_relationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Join_relationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Join_relationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitJoin_relation(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Join_relation() (localctx IJoin_relationContext) { - localctx = NewJoin_relationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 56, SQLParserRULE_join_relation) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(520) - p.Join_operator() - } - { - p.SetState(521) - - var _x = p.Table_or_subquery() - - localctx.(*Join_relationContext).right_relation = _x - } - { - p.SetState(522) - p.Join_constraint() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IRelationContext is an interface to support dynamic dispatch. -type IRelationContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Table_or_subquery() ITable_or_subqueryContext - AllJoin_relation() []IJoin_relationContext - Join_relation(i int) IJoin_relationContext - - // IsRelationContext differentiates from other interfaces. - IsRelationContext() -} - -type RelationContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyRelationContext() *RelationContext { - var p = new(RelationContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_relation - return p -} - -func InitEmptyRelationContext(p *RelationContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_relation -} - -func (*RelationContext) IsRelationContext() {} - -func NewRelationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationContext { - var p = new(RelationContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_relation - - return p -} - -func (s *RelationContext) GetParser() antlr.Parser { return s.parser } - -func (s *RelationContext) Table_or_subquery() ITable_or_subqueryContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_or_subqueryContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_or_subqueryContext) -} - -func (s *RelationContext) AllJoin_relation() []IJoin_relationContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IJoin_relationContext); ok { - len++ - } - } - - tst := make([]IJoin_relationContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IJoin_relationContext); ok { - tst[i] = t.(IJoin_relationContext) - i++ - } - } - - return tst -} - -func (s *RelationContext) Join_relation(i int) IJoin_relationContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IJoin_relationContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IJoin_relationContext) -} - -func (s *RelationContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *RelationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *RelationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitRelation(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Relation() (localctx IRelationContext) { - localctx = NewRelationContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 58, SQLParserRULE_relation) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(524) - p.Table_or_subquery() - } - p.SetState(528) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for (int64((_la-47)) & ^0x3f) == 0 && ((int64(1)<<(_la-47))&536881169) != 0 { - { - p.SetState(525) - p.Join_relation() - } - - p.SetState(530) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ISimple_selectContext is an interface to support dynamic dispatch. -type ISimple_selectContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // GetWhereExpr returns the whereExpr rule contexts. - GetWhereExpr() IExprContext - - // Get_expr returns the _expr rule contexts. - Get_expr() IExprContext - - // GetHavingExpr returns the havingExpr rule contexts. - GetHavingExpr() IExprContext - - // SetWhereExpr sets the whereExpr rule contexts. - SetWhereExpr(IExprContext) - - // Set_expr sets the _expr rule contexts. - Set_expr(IExprContext) - - // SetHavingExpr sets the havingExpr rule contexts. - SetHavingExpr(IExprContext) - - // GetGroupByExpr returns the groupByExpr rule context list. - GetGroupByExpr() []IExprContext - - // SetGroupByExpr sets the groupByExpr rule context list. - SetGroupByExpr([]IExprContext) - - // Getter signatures - SELECT_() antlr.TerminalNode - AllResult_column() []IResult_columnContext - Result_column(i int) IResult_columnContext - DISTINCT_() antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - FROM_() antlr.TerminalNode - Relation() IRelationContext - WHERE_() antlr.TerminalNode - GROUP_() antlr.TerminalNode - BY_() antlr.TerminalNode - AllExpr() []IExprContext - Expr(i int) IExprContext - HAVING_() antlr.TerminalNode - - // IsSimple_selectContext differentiates from other interfaces. - IsSimple_selectContext() -} - -type Simple_selectContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser - whereExpr IExprContext - _expr IExprContext - groupByExpr []IExprContext - havingExpr IExprContext -} - -func NewEmptySimple_selectContext() *Simple_selectContext { - var p = new(Simple_selectContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_simple_select - return p -} - -func InitEmptySimple_selectContext(p *Simple_selectContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_simple_select -} - -func (*Simple_selectContext) IsSimple_selectContext() {} - -func NewSimple_selectContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Simple_selectContext { - var p = new(Simple_selectContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_simple_select - - return p -} - -func (s *Simple_selectContext) GetParser() antlr.Parser { return s.parser } - -func (s *Simple_selectContext) GetWhereExpr() IExprContext { return s.whereExpr } - -func (s *Simple_selectContext) Get_expr() IExprContext { return s._expr } - -func (s *Simple_selectContext) GetHavingExpr() IExprContext { return s.havingExpr } - -func (s *Simple_selectContext) SetWhereExpr(v IExprContext) { s.whereExpr = v } - -func (s *Simple_selectContext) Set_expr(v IExprContext) { s._expr = v } - -func (s *Simple_selectContext) SetHavingExpr(v IExprContext) { s.havingExpr = v } - -func (s *Simple_selectContext) GetGroupByExpr() []IExprContext { return s.groupByExpr } - -func (s *Simple_selectContext) SetGroupByExpr(v []IExprContext) { s.groupByExpr = v } - -func (s *Simple_selectContext) SELECT_() antlr.TerminalNode { - return s.GetToken(SQLParserSELECT_, 0) -} - -func (s *Simple_selectContext) AllResult_column() []IResult_columnContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IResult_columnContext); ok { - len++ - } - } - - tst := make([]IResult_columnContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IResult_columnContext); ok { - tst[i] = t.(IResult_columnContext) - i++ - } - } - - return tst -} - -func (s *Simple_selectContext) Result_column(i int) IResult_columnContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IResult_columnContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IResult_columnContext) -} - -func (s *Simple_selectContext) DISTINCT_() antlr.TerminalNode { - return s.GetToken(SQLParserDISTINCT_, 0) -} - -func (s *Simple_selectContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Simple_selectContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Simple_selectContext) FROM_() antlr.TerminalNode { - return s.GetToken(SQLParserFROM_, 0) -} - -func (s *Simple_selectContext) Relation() IRelationContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IRelationContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IRelationContext) -} - -func (s *Simple_selectContext) WHERE_() antlr.TerminalNode { - return s.GetToken(SQLParserWHERE_, 0) -} - -func (s *Simple_selectContext) GROUP_() antlr.TerminalNode { - return s.GetToken(SQLParserGROUP_, 0) -} - -func (s *Simple_selectContext) BY_() antlr.TerminalNode { - return s.GetToken(SQLParserBY_, 0) -} - -func (s *Simple_selectContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Simple_selectContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Simple_selectContext) HAVING_() antlr.TerminalNode { - return s.GetToken(SQLParserHAVING_, 0) -} - -func (s *Simple_selectContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Simple_selectContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Simple_selectContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitSimple_select(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Simple_select() (localctx ISimple_selectContext) { - localctx = NewSimple_selectContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 60, SQLParserRULE_simple_select) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(531) - p.Match(SQLParserSELECT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(533) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserDISTINCT_ { - { - p.SetState(532) - p.Match(SQLParserDISTINCT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - { - p.SetState(535) - p.Result_column() - } - p.SetState(540) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(536) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(537) - p.Result_column() - } - - p.SetState(542) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(545) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserFROM_ { - { - p.SetState(543) - p.Match(SQLParserFROM_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(544) - p.Relation() - } - - } - p.SetState(549) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWHERE_ { - { - p.SetState(547) - p.Match(SQLParserWHERE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(548) - - var _x = p.expr(0) - - localctx.(*Simple_selectContext).whereExpr = _x - } - - } - p.SetState(565) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserGROUP_ { - { - p.SetState(551) - p.Match(SQLParserGROUP_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(552) - p.Match(SQLParserBY_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(553) - - var _x = p.expr(0) - - localctx.(*Simple_selectContext)._expr = _x - } - localctx.(*Simple_selectContext).groupByExpr = append(localctx.(*Simple_selectContext).groupByExpr, localctx.(*Simple_selectContext)._expr) - p.SetState(558) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(554) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(555) - - var _x = p.expr(0) - - localctx.(*Simple_selectContext)._expr = _x - } - localctx.(*Simple_selectContext).groupByExpr = append(localctx.(*Simple_selectContext).groupByExpr, localctx.(*Simple_selectContext)._expr) - - p.SetState(560) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(563) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserHAVING_ { - { - p.SetState(561) - p.Match(SQLParserHAVING_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(562) - - var _x = p.expr(0) - - localctx.(*Simple_selectContext).havingExpr = _x - } - - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITable_or_subqueryContext is an interface to support dynamic dispatch. -type ITable_or_subqueryContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Function_call() IFunction_callContext - AS_() antlr.TerminalNode - Table_alias() ITable_aliasContext - Table_name() ITable_nameContext - OPEN_PAR() antlr.TerminalNode - Select_core() ISelect_coreContext - CLOSE_PAR() antlr.TerminalNode - - // IsTable_or_subqueryContext differentiates from other interfaces. - IsTable_or_subqueryContext() -} - -type Table_or_subqueryContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTable_or_subqueryContext() *Table_or_subqueryContext { - var p = new(Table_or_subqueryContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_or_subquery - return p -} - -func InitEmptyTable_or_subqueryContext(p *Table_or_subqueryContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_or_subquery -} - -func (*Table_or_subqueryContext) IsTable_or_subqueryContext() {} - -func NewTable_or_subqueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Table_or_subqueryContext { - var p = new(Table_or_subqueryContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_table_or_subquery - - return p -} - -func (s *Table_or_subqueryContext) GetParser() antlr.Parser { return s.parser } - -func (s *Table_or_subqueryContext) Function_call() IFunction_callContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFunction_callContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFunction_callContext) -} - -func (s *Table_or_subqueryContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Table_or_subqueryContext) Table_alias() ITable_aliasContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_aliasContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_aliasContext) -} - -func (s *Table_or_subqueryContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Table_or_subqueryContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Table_or_subqueryContext) Select_core() ISelect_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ISelect_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ISelect_coreContext) -} - -func (s *Table_or_subqueryContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Table_or_subqueryContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Table_or_subqueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Table_or_subqueryContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitTable_or_subquery(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Table_or_subquery() (localctx ITable_or_subqueryContext) { - localctx = NewTable_or_subqueryContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 62, SQLParserRULE_table_or_subquery) - var _la int - - p.SetState(584) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 74, p.GetParserRuleContext()) { - case 1: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(567) - p.Function_call() - } - p.SetState(570) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(568) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(569) - p.Table_alias() - } - - } - - case 2: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(572) - p.Table_name() - } - p.SetState(575) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(573) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(574) - p.Table_alias() - } - - } - - case 3: - p.EnterOuterAlt(localctx, 3) - { - p.SetState(577) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(578) - p.Select_core() - } - { - p.SetState(579) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(582) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(580) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(581) - p.Table_alias() - } - - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IResult_columnContext is an interface to support dynamic dispatch. -type IResult_columnContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - STAR() antlr.TerminalNode - Table_name() ITable_nameContext - DOT() antlr.TerminalNode - Expr() IExprContext - AS_() antlr.TerminalNode - Column_alias() IColumn_aliasContext - - // IsResult_columnContext differentiates from other interfaces. - IsResult_columnContext() -} - -type Result_columnContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyResult_columnContext() *Result_columnContext { - var p = new(Result_columnContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_result_column - return p -} - -func InitEmptyResult_columnContext(p *Result_columnContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_result_column -} - -func (*Result_columnContext) IsResult_columnContext() {} - -func NewResult_columnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Result_columnContext { - var p = new(Result_columnContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_result_column - - return p -} - -func (s *Result_columnContext) GetParser() antlr.Parser { return s.parser } - -func (s *Result_columnContext) STAR() antlr.TerminalNode { - return s.GetToken(SQLParserSTAR, 0) -} - -func (s *Result_columnContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Result_columnContext) DOT() antlr.TerminalNode { - return s.GetToken(SQLParserDOT, 0) -} - -func (s *Result_columnContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Result_columnContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Result_columnContext) Column_alias() IColumn_aliasContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_aliasContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_aliasContext) -} - -func (s *Result_columnContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Result_columnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Result_columnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitResult_column(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Result_column() (localctx IResult_columnContext) { - localctx = NewResult_columnContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 64, SQLParserRULE_result_column) - var _la int - - p.SetState(596) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 76, p.GetParserRuleContext()) { - case 1: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(586) - p.Match(SQLParserSTAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 2: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(587) - p.Table_name() - } - { - p.SetState(588) - p.Match(SQLParserDOT) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(589) - p.Match(SQLParserSTAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 3: - p.EnterOuterAlt(localctx, 3) - { - p.SetState(591) - p.expr(0) - } - p.SetState(594) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(592) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(593) - p.Column_alias() - } - - } - - case antlr.ATNInvalidAltNumber: - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IReturning_clause_result_columnContext is an interface to support dynamic dispatch. -type IReturning_clause_result_columnContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - STAR() antlr.TerminalNode - Expr() IExprContext - AS_() antlr.TerminalNode - Column_alias() IColumn_aliasContext - - // IsReturning_clause_result_columnContext differentiates from other interfaces. - IsReturning_clause_result_columnContext() -} - -type Returning_clause_result_columnContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyReturning_clause_result_columnContext() *Returning_clause_result_columnContext { - var p = new(Returning_clause_result_columnContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_returning_clause_result_column - return p -} - -func InitEmptyReturning_clause_result_columnContext(p *Returning_clause_result_columnContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_returning_clause_result_column -} - -func (*Returning_clause_result_columnContext) IsReturning_clause_result_columnContext() {} - -func NewReturning_clause_result_columnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Returning_clause_result_columnContext { - var p = new(Returning_clause_result_columnContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_returning_clause_result_column - - return p -} - -func (s *Returning_clause_result_columnContext) GetParser() antlr.Parser { return s.parser } - -func (s *Returning_clause_result_columnContext) STAR() antlr.TerminalNode { - return s.GetToken(SQLParserSTAR, 0) -} - -func (s *Returning_clause_result_columnContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Returning_clause_result_columnContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Returning_clause_result_columnContext) Column_alias() IColumn_aliasContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_aliasContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_aliasContext) -} - -func (s *Returning_clause_result_columnContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Returning_clause_result_columnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Returning_clause_result_columnContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitReturning_clause_result_column(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Returning_clause_result_column() (localctx IReturning_clause_result_columnContext) { - localctx = NewReturning_clause_result_columnContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 66, SQLParserRULE_returning_clause_result_column) - var _la int - - p.SetState(604) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserSTAR: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(598) - p.Match(SQLParserSTAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserOPEN_PAR, SQLParserPLUS, SQLParserMINUS, SQLParserCASE_, SQLParserEXISTS_, SQLParserLIKE_, SQLParserNOT_, SQLParserREPLACE_, SQLParserBOOLEAN_LITERAL, SQLParserNUMERIC_LITERAL, SQLParserBLOB_LITERAL, SQLParserTEXT_LITERAL, SQLParserNULL_LITERAL, SQLParserIDENTIFIER, SQLParserBIND_PARAMETER: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(599) - p.expr(0) - } - p.SetState(602) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(600) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(601) - p.Column_alias() - } - - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IJoin_operatorContext is an interface to support dynamic dispatch. -type IJoin_operatorContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - JOIN_() antlr.TerminalNode - INNER_() antlr.TerminalNode - LEFT_() antlr.TerminalNode - RIGHT_() antlr.TerminalNode - FULL_() antlr.TerminalNode - OUTER_() antlr.TerminalNode - - // IsJoin_operatorContext differentiates from other interfaces. - IsJoin_operatorContext() -} - -type Join_operatorContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyJoin_operatorContext() *Join_operatorContext { - var p = new(Join_operatorContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_operator - return p -} - -func InitEmptyJoin_operatorContext(p *Join_operatorContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_operator -} - -func (*Join_operatorContext) IsJoin_operatorContext() {} - -func NewJoin_operatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Join_operatorContext { - var p = new(Join_operatorContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_join_operator - - return p -} - -func (s *Join_operatorContext) GetParser() antlr.Parser { return s.parser } - -func (s *Join_operatorContext) JOIN_() antlr.TerminalNode { - return s.GetToken(SQLParserJOIN_, 0) -} - -func (s *Join_operatorContext) INNER_() antlr.TerminalNode { - return s.GetToken(SQLParserINNER_, 0) -} - -func (s *Join_operatorContext) LEFT_() antlr.TerminalNode { - return s.GetToken(SQLParserLEFT_, 0) -} - -func (s *Join_operatorContext) RIGHT_() antlr.TerminalNode { - return s.GetToken(SQLParserRIGHT_, 0) -} - -func (s *Join_operatorContext) FULL_() antlr.TerminalNode { - return s.GetToken(SQLParserFULL_, 0) -} - -func (s *Join_operatorContext) OUTER_() antlr.TerminalNode { - return s.GetToken(SQLParserOUTER_, 0) -} - -func (s *Join_operatorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Join_operatorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Join_operatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitJoin_operator(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Join_operator() (localctx IJoin_operatorContext) { - localctx = NewJoin_operatorContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 68, SQLParserRULE_join_operator) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(611) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - switch p.GetTokenStream().LA(1) { - case SQLParserFULL_, SQLParserLEFT_, SQLParserRIGHT_: - { - p.SetState(606) - _la = p.GetTokenStream().LA(1) - - if !((int64((_la-47)) & ^0x3f) == 0 && ((int64(1)<<(_la-47))&536879105) != 0) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - p.SetState(608) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserOUTER_ { - { - p.SetState(607) - p.Match(SQLParserOUTER_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - - case SQLParserINNER_: - { - p.SetState(610) - p.Match(SQLParserINNER_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserJOIN_: - - default: - } - { - p.SetState(613) - p.Match(SQLParserJOIN_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IJoin_constraintContext is an interface to support dynamic dispatch. -type IJoin_constraintContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ON_() antlr.TerminalNode - Expr() IExprContext - - // IsJoin_constraintContext differentiates from other interfaces. - IsJoin_constraintContext() -} - -type Join_constraintContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyJoin_constraintContext() *Join_constraintContext { - var p = new(Join_constraintContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_constraint - return p -} - -func InitEmptyJoin_constraintContext(p *Join_constraintContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_join_constraint -} - -func (*Join_constraintContext) IsJoin_constraintContext() {} - -func NewJoin_constraintContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Join_constraintContext { - var p = new(Join_constraintContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_join_constraint - - return p -} - -func (s *Join_constraintContext) GetParser() antlr.Parser { return s.parser } - -func (s *Join_constraintContext) ON_() antlr.TerminalNode { - return s.GetToken(SQLParserON_, 0) -} - -func (s *Join_constraintContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Join_constraintContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Join_constraintContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Join_constraintContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitJoin_constraint(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Join_constraint() (localctx IJoin_constraintContext) { - localctx = NewJoin_constraintContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 70, SQLParserRULE_join_constraint) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(615) - p.Match(SQLParserON_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(616) - p.expr(0) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICompound_operatorContext is an interface to support dynamic dispatch. -type ICompound_operatorContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - UNION_() antlr.TerminalNode - ALL_() antlr.TerminalNode - INTERSECT_() antlr.TerminalNode - EXCEPT_() antlr.TerminalNode - - // IsCompound_operatorContext differentiates from other interfaces. - IsCompound_operatorContext() -} - -type Compound_operatorContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCompound_operatorContext() *Compound_operatorContext { - var p = new(Compound_operatorContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_compound_operator - return p -} - -func InitEmptyCompound_operatorContext(p *Compound_operatorContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_compound_operator -} - -func (*Compound_operatorContext) IsCompound_operatorContext() {} - -func NewCompound_operatorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Compound_operatorContext { - var p = new(Compound_operatorContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_compound_operator - - return p -} - -func (s *Compound_operatorContext) GetParser() antlr.Parser { return s.parser } - -func (s *Compound_operatorContext) UNION_() antlr.TerminalNode { - return s.GetToken(SQLParserUNION_, 0) -} - -func (s *Compound_operatorContext) ALL_() antlr.TerminalNode { - return s.GetToken(SQLParserALL_, 0) -} - -func (s *Compound_operatorContext) INTERSECT_() antlr.TerminalNode { - return s.GetToken(SQLParserINTERSECT_, 0) -} - -func (s *Compound_operatorContext) EXCEPT_() antlr.TerminalNode { - return s.GetToken(SQLParserEXCEPT_, 0) -} - -func (s *Compound_operatorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Compound_operatorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Compound_operatorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCompound_operator(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Compound_operator() (localctx ICompound_operatorContext) { - localctx = NewCompound_operatorContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 72, SQLParserRULE_compound_operator) - var _la int - - p.SetState(624) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserUNION_: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(618) - p.Match(SQLParserUNION_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(620) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserALL_ { - { - p.SetState(619) - p.Match(SQLParserALL_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - } - - case SQLParserINTERSECT_: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(622) - p.Match(SQLParserINTERSECT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserEXCEPT_: - p.EnterOuterAlt(localctx, 3) - { - p.SetState(623) - p.Match(SQLParserEXCEPT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUpdate_set_subclauseContext is an interface to support dynamic dispatch. -type IUpdate_set_subclauseContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ASSIGN() antlr.TerminalNode - Expr() IExprContext - Column_name() IColumn_nameContext - Column_name_list() IColumn_name_listContext - - // IsUpdate_set_subclauseContext differentiates from other interfaces. - IsUpdate_set_subclauseContext() -} - -type Update_set_subclauseContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyUpdate_set_subclauseContext() *Update_set_subclauseContext { - var p = new(Update_set_subclauseContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_set_subclause - return p -} - -func InitEmptyUpdate_set_subclauseContext(p *Update_set_subclauseContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_set_subclause -} - -func (*Update_set_subclauseContext) IsUpdate_set_subclauseContext() {} - -func NewUpdate_set_subclauseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Update_set_subclauseContext { - var p = new(Update_set_subclauseContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_update_set_subclause - - return p -} - -func (s *Update_set_subclauseContext) GetParser() antlr.Parser { return s.parser } - -func (s *Update_set_subclauseContext) ASSIGN() antlr.TerminalNode { - return s.GetToken(SQLParserASSIGN, 0) -} - -func (s *Update_set_subclauseContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Update_set_subclauseContext) Column_name() IColumn_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Update_set_subclauseContext) Column_name_list() IColumn_name_listContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_name_listContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IColumn_name_listContext) -} - -func (s *Update_set_subclauseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Update_set_subclauseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Update_set_subclauseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUpdate_set_subclause(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Update_set_subclause() (localctx IUpdate_set_subclauseContext) { - localctx = NewUpdate_set_subclauseContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 74, SQLParserRULE_update_set_subclause) - p.EnterOuterAlt(localctx, 1) - p.SetState(628) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserIDENTIFIER: - { - p.SetState(626) - p.Column_name() - } - - case SQLParserOPEN_PAR: - { - p.SetState(627) - p.Column_name_list() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - { - p.SetState(630) - p.Match(SQLParserASSIGN) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(631) - p.expr(0) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUpdate_coreContext is an interface to support dynamic dispatch. -type IUpdate_coreContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - UPDATE_() antlr.TerminalNode - Qualified_table_name() IQualified_table_nameContext - SET_() antlr.TerminalNode - AllUpdate_set_subclause() []IUpdate_set_subclauseContext - Update_set_subclause(i int) IUpdate_set_subclauseContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - FROM_() antlr.TerminalNode - Relation() IRelationContext - WHERE_() antlr.TerminalNode - Expr() IExprContext - Returning_clause() IReturning_clauseContext - - // IsUpdate_coreContext differentiates from other interfaces. - IsUpdate_coreContext() -} - -type Update_coreContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyUpdate_coreContext() *Update_coreContext { - var p = new(Update_coreContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_core - return p -} - -func InitEmptyUpdate_coreContext(p *Update_coreContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_core -} - -func (*Update_coreContext) IsUpdate_coreContext() {} - -func NewUpdate_coreContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Update_coreContext { - var p = new(Update_coreContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_update_core - - return p -} - -func (s *Update_coreContext) GetParser() antlr.Parser { return s.parser } - -func (s *Update_coreContext) UPDATE_() antlr.TerminalNode { - return s.GetToken(SQLParserUPDATE_, 0) -} - -func (s *Update_coreContext) Qualified_table_name() IQualified_table_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IQualified_table_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IQualified_table_nameContext) -} - -func (s *Update_coreContext) SET_() antlr.TerminalNode { - return s.GetToken(SQLParserSET_, 0) -} - -func (s *Update_coreContext) AllUpdate_set_subclause() []IUpdate_set_subclauseContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IUpdate_set_subclauseContext); ok { - len++ - } - } - - tst := make([]IUpdate_set_subclauseContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IUpdate_set_subclauseContext); ok { - tst[i] = t.(IUpdate_set_subclauseContext) - i++ - } - } - - return tst -} - -func (s *Update_coreContext) Update_set_subclause(i int) IUpdate_set_subclauseContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUpdate_set_subclauseContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IUpdate_set_subclauseContext) -} - -func (s *Update_coreContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Update_coreContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Update_coreContext) FROM_() antlr.TerminalNode { - return s.GetToken(SQLParserFROM_, 0) -} - -func (s *Update_coreContext) Relation() IRelationContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IRelationContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IRelationContext) -} - -func (s *Update_coreContext) WHERE_() antlr.TerminalNode { - return s.GetToken(SQLParserWHERE_, 0) -} - -func (s *Update_coreContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Update_coreContext) Returning_clause() IReturning_clauseContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IReturning_clauseContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IReturning_clauseContext) -} - -func (s *Update_coreContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Update_coreContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Update_coreContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUpdate_core(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Update_core() (localctx IUpdate_coreContext) { - localctx = NewUpdate_coreContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 76, SQLParserRULE_update_core) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(633) - p.Match(SQLParserUPDATE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(634) - p.Qualified_table_name() - } - { - p.SetState(635) - p.Match(SQLParserSET_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(636) - p.Update_set_subclause() - } - p.SetState(641) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(637) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(638) - p.Update_set_subclause() - } - - p.SetState(643) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - p.SetState(646) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserFROM_ { - { - p.SetState(644) - p.Match(SQLParserFROM_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(645) - p.Relation() - } - - } - p.SetState(650) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWHERE_ { - { - p.SetState(648) - p.Match(SQLParserWHERE_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(649) - p.expr(0) - } - - } - p.SetState(653) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserRETURNING_ { - { - p.SetState(652) - p.Returning_clause() - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IUpdate_stmtContext is an interface to support dynamic dispatch. -type IUpdate_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Update_core() IUpdate_coreContext - Common_table_stmt() ICommon_table_stmtContext - - // IsUpdate_stmtContext differentiates from other interfaces. - IsUpdate_stmtContext() -} - -type Update_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyUpdate_stmtContext() *Update_stmtContext { - var p = new(Update_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_stmt - return p -} - -func InitEmptyUpdate_stmtContext(p *Update_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_update_stmt -} - -func (*Update_stmtContext) IsUpdate_stmtContext() {} - -func NewUpdate_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Update_stmtContext { - var p = new(Update_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_update_stmt - - return p -} - -func (s *Update_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Update_stmtContext) Update_core() IUpdate_coreContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IUpdate_coreContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IUpdate_coreContext) -} - -func (s *Update_stmtContext) Common_table_stmt() ICommon_table_stmtContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ICommon_table_stmtContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ICommon_table_stmtContext) -} - -func (s *Update_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Update_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Update_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitUpdate_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Update_stmt() (localctx IUpdate_stmtContext) { - localctx = NewUpdate_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 78, SQLParserRULE_update_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - p.SetState(656) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserWITH_ { - { - p.SetState(655) - p.Common_table_stmt() - } - - } - { - p.SetState(658) - p.Update_core() - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IColumn_name_listContext is an interface to support dynamic dispatch. -type IColumn_name_listContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - OPEN_PAR() antlr.TerminalNode - AllColumn_name() []IColumn_nameContext - Column_name(i int) IColumn_nameContext - CLOSE_PAR() antlr.TerminalNode - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsColumn_name_listContext differentiates from other interfaces. - IsColumn_name_listContext() -} - -type Column_name_listContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyColumn_name_listContext() *Column_name_listContext { - var p = new(Column_name_listContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_name_list - return p -} - -func InitEmptyColumn_name_listContext(p *Column_name_listContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_name_list -} - -func (*Column_name_listContext) IsColumn_name_listContext() {} - -func NewColumn_name_listContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_name_listContext { - var p = new(Column_name_listContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_column_name_list - - return p -} - -func (s *Column_name_listContext) GetParser() antlr.Parser { return s.parser } - -func (s *Column_name_listContext) OPEN_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserOPEN_PAR, 0) -} - -func (s *Column_name_listContext) AllColumn_name() []IColumn_nameContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IColumn_nameContext); ok { - len++ - } - } - - tst := make([]IColumn_nameContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IColumn_nameContext); ok { - tst[i] = t.(IColumn_nameContext) - i++ - } - } - - return tst -} - -func (s *Column_name_listContext) Column_name(i int) IColumn_nameContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IColumn_nameContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IColumn_nameContext) -} - -func (s *Column_name_listContext) CLOSE_PAR() antlr.TerminalNode { - return s.GetToken(SQLParserCLOSE_PAR, 0) -} - -func (s *Column_name_listContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Column_name_listContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Column_name_listContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_name_listContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Column_name_listContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitColumn_name_list(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Column_name_list() (localctx IColumn_name_listContext) { - localctx = NewColumn_name_listContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 80, SQLParserRULE_column_name_list) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(660) - p.Match(SQLParserOPEN_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(661) - p.Column_name() - } - p.SetState(666) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(662) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(663) - p.Column_name() - } - - p.SetState(668) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - { - p.SetState(669) - p.Match(SQLParserCLOSE_PAR) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IQualified_table_nameContext is an interface to support dynamic dispatch. -type IQualified_table_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Table_name() ITable_nameContext - AS_() antlr.TerminalNode - Table_alias() ITable_aliasContext - - // IsQualified_table_nameContext differentiates from other interfaces. - IsQualified_table_nameContext() -} - -type Qualified_table_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyQualified_table_nameContext() *Qualified_table_nameContext { - var p = new(Qualified_table_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_qualified_table_name - return p -} - -func InitEmptyQualified_table_nameContext(p *Qualified_table_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_qualified_table_name -} - -func (*Qualified_table_nameContext) IsQualified_table_nameContext() {} - -func NewQualified_table_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Qualified_table_nameContext { - var p = new(Qualified_table_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_qualified_table_name - - return p -} - -func (s *Qualified_table_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Qualified_table_nameContext) Table_name() ITable_nameContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_nameContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_nameContext) -} - -func (s *Qualified_table_nameContext) AS_() antlr.TerminalNode { - return s.GetToken(SQLParserAS_, 0) -} - -func (s *Qualified_table_nameContext) Table_alias() ITable_aliasContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITable_aliasContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITable_aliasContext) -} - -func (s *Qualified_table_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Qualified_table_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Qualified_table_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitQualified_table_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Qualified_table_name() (localctx IQualified_table_nameContext) { - localctx = NewQualified_table_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 82, SQLParserRULE_qualified_table_name) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(671) - p.Table_name() - } - p.SetState(674) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserAS_ { - { - p.SetState(672) - p.Match(SQLParserAS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(673) - p.Table_alias() - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IOrder_by_stmtContext is an interface to support dynamic dispatch. -type IOrder_by_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ORDER_() antlr.TerminalNode - BY_() antlr.TerminalNode - AllOrdering_term() []IOrdering_termContext - Ordering_term(i int) IOrdering_termContext - AllCOMMA() []antlr.TerminalNode - COMMA(i int) antlr.TerminalNode - - // IsOrder_by_stmtContext differentiates from other interfaces. - IsOrder_by_stmtContext() -} - -type Order_by_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyOrder_by_stmtContext() *Order_by_stmtContext { - var p = new(Order_by_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_order_by_stmt - return p -} - -func InitEmptyOrder_by_stmtContext(p *Order_by_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_order_by_stmt -} - -func (*Order_by_stmtContext) IsOrder_by_stmtContext() {} - -func NewOrder_by_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Order_by_stmtContext { - var p = new(Order_by_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_order_by_stmt - - return p -} - -func (s *Order_by_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Order_by_stmtContext) ORDER_() antlr.TerminalNode { - return s.GetToken(SQLParserORDER_, 0) -} - -func (s *Order_by_stmtContext) BY_() antlr.TerminalNode { - return s.GetToken(SQLParserBY_, 0) -} - -func (s *Order_by_stmtContext) AllOrdering_term() []IOrdering_termContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IOrdering_termContext); ok { - len++ - } - } - - tst := make([]IOrdering_termContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IOrdering_termContext); ok { - tst[i] = t.(IOrdering_termContext) - i++ - } - } - - return tst -} - -func (s *Order_by_stmtContext) Ordering_term(i int) IOrdering_termContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IOrdering_termContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IOrdering_termContext) -} - -func (s *Order_by_stmtContext) AllCOMMA() []antlr.TerminalNode { - return s.GetTokens(SQLParserCOMMA) -} - -func (s *Order_by_stmtContext) COMMA(i int) antlr.TerminalNode { - return s.GetToken(SQLParserCOMMA, i) -} - -func (s *Order_by_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Order_by_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Order_by_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitOrder_by_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Order_by_stmt() (localctx IOrder_by_stmtContext) { - localctx = NewOrder_by_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 84, SQLParserRULE_order_by_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(676) - p.Match(SQLParserORDER_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(677) - p.Match(SQLParserBY_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(678) - p.Ordering_term() - } - p.SetState(683) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - for _la == SQLParserCOMMA { - { - p.SetState(679) - p.Match(SQLParserCOMMA) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(680) - p.Ordering_term() - } - - p.SetState(685) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ILimit_stmtContext is an interface to support dynamic dispatch. -type ILimit_stmtContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - LIMIT_() antlr.TerminalNode - AllExpr() []IExprContext - Expr(i int) IExprContext - OFFSET_() antlr.TerminalNode - - // IsLimit_stmtContext differentiates from other interfaces. - IsLimit_stmtContext() -} - -type Limit_stmtContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyLimit_stmtContext() *Limit_stmtContext { - var p = new(Limit_stmtContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_limit_stmt - return p -} - -func InitEmptyLimit_stmtContext(p *Limit_stmtContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_limit_stmt -} - -func (*Limit_stmtContext) IsLimit_stmtContext() {} - -func NewLimit_stmtContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Limit_stmtContext { - var p = new(Limit_stmtContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_limit_stmt - - return p -} - -func (s *Limit_stmtContext) GetParser() antlr.Parser { return s.parser } - -func (s *Limit_stmtContext) LIMIT_() antlr.TerminalNode { - return s.GetToken(SQLParserLIMIT_, 0) -} - -func (s *Limit_stmtContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *Limit_stmtContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Limit_stmtContext) OFFSET_() antlr.TerminalNode { - return s.GetToken(SQLParserOFFSET_, 0) -} - -func (s *Limit_stmtContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Limit_stmtContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Limit_stmtContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitLimit_stmt(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Limit_stmt() (localctx ILimit_stmtContext) { - localctx = NewLimit_stmtContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 86, SQLParserRULE_limit_stmt) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(686) - p.Match(SQLParserLIMIT_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(687) - p.expr(0) - } - p.SetState(690) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserOFFSET_ { - { - p.SetState(688) - p.Match(SQLParserOFFSET_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(689) - p.expr(0) - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IOrdering_termContext is an interface to support dynamic dispatch. -type IOrdering_termContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - Expr() IExprContext - Asc_desc() IAsc_descContext - NULLS_() antlr.TerminalNode - FIRST_() antlr.TerminalNode - LAST_() antlr.TerminalNode - - // IsOrdering_termContext differentiates from other interfaces. - IsOrdering_termContext() -} - -type Ordering_termContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyOrdering_termContext() *Ordering_termContext { - var p = new(Ordering_termContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_ordering_term - return p -} - -func InitEmptyOrdering_termContext(p *Ordering_termContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_ordering_term -} - -func (*Ordering_termContext) IsOrdering_termContext() {} - -func NewOrdering_termContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Ordering_termContext { - var p = new(Ordering_termContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_ordering_term - - return p -} - -func (s *Ordering_termContext) GetParser() antlr.Parser { return s.parser } - -func (s *Ordering_termContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *Ordering_termContext) Asc_desc() IAsc_descContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IAsc_descContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IAsc_descContext) -} - -func (s *Ordering_termContext) NULLS_() antlr.TerminalNode { - return s.GetToken(SQLParserNULLS_, 0) -} - -func (s *Ordering_termContext) FIRST_() antlr.TerminalNode { - return s.GetToken(SQLParserFIRST_, 0) -} - -func (s *Ordering_termContext) LAST_() antlr.TerminalNode { - return s.GetToken(SQLParserLAST_, 0) -} - -func (s *Ordering_termContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Ordering_termContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Ordering_termContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitOrdering_term(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Ordering_term() (localctx IOrdering_termContext) { - localctx = NewOrdering_termContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 88, SQLParserRULE_ordering_term) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(692) - p.expr(0) - } - p.SetState(694) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserASC_ || _la == SQLParserDESC_ { - { - p.SetState(693) - p.Asc_desc() - } - - } - p.SetState(698) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == SQLParserNULLS_ { - { - p.SetState(696) - p.Match(SQLParserNULLS_) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(697) - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserFIRST_ || _la == SQLParserLAST_) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IAsc_descContext is an interface to support dynamic dispatch. -type IAsc_descContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - ASC_() antlr.TerminalNode - DESC_() antlr.TerminalNode - - // IsAsc_descContext differentiates from other interfaces. - IsAsc_descContext() -} - -type Asc_descContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyAsc_descContext() *Asc_descContext { - var p = new(Asc_descContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_asc_desc - return p -} - -func InitEmptyAsc_descContext(p *Asc_descContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_asc_desc -} - -func (*Asc_descContext) IsAsc_descContext() {} - -func NewAsc_descContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Asc_descContext { - var p = new(Asc_descContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_asc_desc - - return p -} - -func (s *Asc_descContext) GetParser() antlr.Parser { return s.parser } - -func (s *Asc_descContext) ASC_() antlr.TerminalNode { - return s.GetToken(SQLParserASC_, 0) -} - -func (s *Asc_descContext) DESC_() antlr.TerminalNode { - return s.GetToken(SQLParserDESC_, 0) -} - -func (s *Asc_descContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Asc_descContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Asc_descContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitAsc_desc(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Asc_desc() (localctx IAsc_descContext) { - localctx = NewAsc_descContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 90, SQLParserRULE_asc_desc) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(700) - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserASC_ || _la == SQLParserDESC_) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFunction_keywordContext is an interface to support dynamic dispatch. -type IFunction_keywordContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - LIKE_() antlr.TerminalNode - REPLACE_() antlr.TerminalNode - - // IsFunction_keywordContext differentiates from other interfaces. - IsFunction_keywordContext() -} - -type Function_keywordContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyFunction_keywordContext() *Function_keywordContext { - var p = new(Function_keywordContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_keyword - return p -} - -func InitEmptyFunction_keywordContext(p *Function_keywordContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_keyword -} - -func (*Function_keywordContext) IsFunction_keywordContext() {} - -func NewFunction_keywordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Function_keywordContext { - var p = new(Function_keywordContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_function_keyword - - return p -} - -func (s *Function_keywordContext) GetParser() antlr.Parser { return s.parser } - -func (s *Function_keywordContext) LIKE_() antlr.TerminalNode { - return s.GetToken(SQLParserLIKE_, 0) -} - -func (s *Function_keywordContext) REPLACE_() antlr.TerminalNode { - return s.GetToken(SQLParserREPLACE_, 0) -} - -func (s *Function_keywordContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Function_keywordContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Function_keywordContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitFunction_keyword(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Function_keyword() (localctx IFunction_keywordContext) { - localctx = NewFunction_keywordContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 92, SQLParserRULE_function_keyword) - var _la int - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(702) - _la = p.GetTokenStream().LA(1) - - if !(_la == SQLParserLIKE_ || _la == SQLParserREPLACE_) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IFunction_nameContext is an interface to support dynamic dispatch. -type IFunction_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - Function_keyword() IFunction_keywordContext - - // IsFunction_nameContext differentiates from other interfaces. - IsFunction_nameContext() -} - -type Function_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyFunction_nameContext() *Function_nameContext { - var p = new(Function_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_name - return p -} - -func InitEmptyFunction_nameContext(p *Function_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_function_name -} - -func (*Function_nameContext) IsFunction_nameContext() {} - -func NewFunction_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Function_nameContext { - var p = new(Function_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_function_name - - return p -} - -func (s *Function_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Function_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Function_nameContext) Function_keyword() IFunction_keywordContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IFunction_keywordContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IFunction_keywordContext) -} - -func (s *Function_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Function_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Function_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitFunction_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Function_name() (localctx IFunction_nameContext) { - localctx = NewFunction_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 94, SQLParserRULE_function_name) - p.SetState(706) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - - switch p.GetTokenStream().LA(1) { - case SQLParserIDENTIFIER: - p.EnterOuterAlt(localctx, 1) - { - p.SetState(704) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case SQLParserLIKE_, SQLParserREPLACE_: - p.EnterOuterAlt(localctx, 2) - { - p.SetState(705) - p.Function_keyword() - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITable_nameContext is an interface to support dynamic dispatch. -type ITable_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsTable_nameContext differentiates from other interfaces. - IsTable_nameContext() -} - -type Table_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTable_nameContext() *Table_nameContext { - var p = new(Table_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_name - return p -} - -func InitEmptyTable_nameContext(p *Table_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_name -} - -func (*Table_nameContext) IsTable_nameContext() {} - -func NewTable_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Table_nameContext { - var p = new(Table_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_table_name - - return p -} - -func (s *Table_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Table_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Table_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Table_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Table_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitTable_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Table_name() (localctx ITable_nameContext) { - localctx = NewTable_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 96, SQLParserRULE_table_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(708) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ITable_aliasContext is an interface to support dynamic dispatch. -type ITable_aliasContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsTable_aliasContext differentiates from other interfaces. - IsTable_aliasContext() -} - -type Table_aliasContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyTable_aliasContext() *Table_aliasContext { - var p = new(Table_aliasContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_alias - return p -} - -func InitEmptyTable_aliasContext(p *Table_aliasContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_table_alias -} - -func (*Table_aliasContext) IsTable_aliasContext() {} - -func NewTable_aliasContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Table_aliasContext { - var p = new(Table_aliasContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_table_alias - - return p -} - -func (s *Table_aliasContext) GetParser() antlr.Parser { return s.parser } - -func (s *Table_aliasContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Table_aliasContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Table_aliasContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Table_aliasContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitTable_alias(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Table_alias() (localctx ITable_aliasContext) { - localctx = NewTable_aliasContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 98, SQLParserRULE_table_alias) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(710) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IColumn_nameContext is an interface to support dynamic dispatch. -type IColumn_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsColumn_nameContext differentiates from other interfaces. - IsColumn_nameContext() -} - -type Column_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyColumn_nameContext() *Column_nameContext { - var p = new(Column_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_name - return p -} - -func InitEmptyColumn_nameContext(p *Column_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_name -} - -func (*Column_nameContext) IsColumn_nameContext() {} - -func NewColumn_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_nameContext { - var p = new(Column_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_column_name - - return p -} - -func (s *Column_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Column_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Column_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Column_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitColumn_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Column_name() (localctx IColumn_nameContext) { - localctx = NewColumn_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 100, SQLParserRULE_column_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(712) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IColumn_aliasContext is an interface to support dynamic dispatch. -type IColumn_aliasContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsColumn_aliasContext differentiates from other interfaces. - IsColumn_aliasContext() -} - -type Column_aliasContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyColumn_aliasContext() *Column_aliasContext { - var p = new(Column_aliasContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_alias - return p -} - -func InitEmptyColumn_aliasContext(p *Column_aliasContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_column_alias -} - -func (*Column_aliasContext) IsColumn_aliasContext() {} - -func NewColumn_aliasContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Column_aliasContext { - var p = new(Column_aliasContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_column_alias - - return p -} - -func (s *Column_aliasContext) GetParser() antlr.Parser { return s.parser } - -func (s *Column_aliasContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Column_aliasContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Column_aliasContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Column_aliasContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitColumn_alias(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Column_alias() (localctx IColumn_aliasContext) { - localctx = NewColumn_aliasContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 102, SQLParserRULE_column_alias) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(714) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// ICollation_nameContext is an interface to support dynamic dispatch. -type ICollation_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsCollation_nameContext differentiates from other interfaces. - IsCollation_nameContext() -} - -type Collation_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCollation_nameContext() *Collation_nameContext { - var p = new(Collation_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_collation_name - return p -} - -func InitEmptyCollation_nameContext(p *Collation_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_collation_name -} - -func (*Collation_nameContext) IsCollation_nameContext() {} - -func NewCollation_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Collation_nameContext { - var p = new(Collation_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_collation_name - - return p -} - -func (s *Collation_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Collation_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Collation_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Collation_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Collation_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitCollation_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Collation_name() (localctx ICollation_nameContext) { - localctx = NewCollation_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 104, SQLParserRULE_collation_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(716) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -// IIndex_nameContext is an interface to support dynamic dispatch. -type IIndex_nameContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // Getter signatures - IDENTIFIER() antlr.TerminalNode - - // IsIndex_nameContext differentiates from other interfaces. - IsIndex_nameContext() -} - -type Index_nameContext struct { - antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyIndex_nameContext() *Index_nameContext { - var p = new(Index_nameContext) - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_index_name - return p -} - -func InitEmptyIndex_nameContext(p *Index_nameContext) { - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1) - p.RuleIndex = SQLParserRULE_index_name -} - -func (*Index_nameContext) IsIndex_nameContext() {} - -func NewIndex_nameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *Index_nameContext { - var p = new(Index_nameContext) - - antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState) - - p.parser = parser - p.RuleIndex = SQLParserRULE_index_name - - return p -} - -func (s *Index_nameContext) GetParser() antlr.Parser { return s.parser } - -func (s *Index_nameContext) IDENTIFIER() antlr.TerminalNode { - return s.GetToken(SQLParserIDENTIFIER, 0) -} - -func (s *Index_nameContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *Index_nameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *Index_nameContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case SQLParserVisitor: - return t.VisitIndex_name(s) - - default: - return t.VisitChildren(s) - } -} - -func (p *SQLParser) Index_name() (localctx IIndex_nameContext) { - localctx = NewIndex_nameContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 106, SQLParserRULE_index_name) - p.EnterOuterAlt(localctx, 1) - { - p.SetState(718) - p.Match(SQLParserIDENTIFIER) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - -errorExit: - if p.HasError() { - v := p.GetError() - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - p.SetError(nil) - } - p.ExitRule() - return localctx - goto errorExit // Trick to prevent compiler error if the label is not used -} - -func (p *SQLParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { - switch ruleIndex { - case 13: - var t *ExprContext = nil - if localctx != nil { - t = localctx.(*ExprContext) - } - return p.Expr_Sempred(t, predIndex) - - default: - panic("No predicate with index: " + fmt.Sprint(ruleIndex)) - } -} - -func (p *SQLParser) Expr_Sempred(localctx antlr.RuleContext, predIndex int) bool { - switch predIndex { - case 0: - return p.Precpred(p.GetParserRuleContext(), 12) - - case 1: - return p.Precpred(p.GetParserRuleContext(), 11) - - case 2: - return p.Precpred(p.GetParserRuleContext(), 8) - - case 3: - return p.Precpred(p.GetParserRuleContext(), 6) - - case 4: - return p.Precpred(p.GetParserRuleContext(), 2) - - case 5: - return p.Precpred(p.GetParserRuleContext(), 1) - - case 6: - return p.Precpred(p.GetParserRuleContext(), 18) - - case 7: - return p.Precpred(p.GetParserRuleContext(), 10) - - case 8: - return p.Precpred(p.GetParserRuleContext(), 9) - - case 9: - return p.Precpred(p.GetParserRuleContext(), 7) - - case 10: - return p.Precpred(p.GetParserRuleContext(), 5) - - case 11: - return p.Precpred(p.GetParserRuleContext(), 4) - - default: - panic("No predicate with index: " + fmt.Sprint(predIndex)) - } -} diff --git a/parse/sql/gen/sqlparser_base_visitor.go b/parse/sql/gen/sqlparser_base_visitor.go deleted file mode 100644 index 6dd7e8f09..000000000 --- a/parse/sql/gen/sqlparser_base_visitor.go +++ /dev/null @@ -1,320 +0,0 @@ -// Code generated from SQLParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package sqlgrammar // SQLParser -import "github.com/antlr4-go/antlr/v4" - -type BaseSQLParserVisitor struct { - *antlr.BaseParseTreeVisitor -} - -func (v *BaseSQLParserVisitor) VisitStatements(ctx *StatementsContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSql_stmt_list(ctx *Sql_stmt_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSql_stmt(ctx *Sql_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitIndexed_column(ctx *Indexed_columnContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCte_table_name(ctx *Cte_table_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCommon_table_expression(ctx *Common_table_expressionContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCommon_table_stmt(ctx *Common_table_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitDelete_core(ctx *Delete_coreContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitDelete_stmt(ctx *Delete_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitVariable(ctx *VariableContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitNormal_function_call(ctx *Normal_function_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitForeign_function_call(ctx *Foreign_function_callContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitColumn_ref(ctx *Column_refContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitWhen_clause(ctx *When_clauseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSubquery_expr(ctx *Subquery_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitLogical_not_expr(ctx *Logical_not_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitBoolean_literal_expr(ctx *Boolean_literal_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitComparison_expr(ctx *Comparison_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitLike_expr(ctx *Like_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitNull_expr(ctx *Null_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitColumn_expr(ctx *Column_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitIn_subquery_expr(ctx *In_subquery_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitArithmetic_expr(ctx *Arithmetic_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitLogical_binary_expr(ctx *Logical_binary_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitVariable_expr(ctx *Variable_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitText_literal_expr(ctx *Text_literal_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUnary_expr(ctx *Unary_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCollate_expr(ctx *Collate_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitParenthesized_expr(ctx *Parenthesized_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitBetween_expr(ctx *Between_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitExpr_list_expr(ctx *Expr_list_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitNumeric_literal_expr(ctx *Numeric_literal_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitNull_literal_expr(ctx *Null_literal_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitIn_list_expr(ctx *In_list_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitIs_expr(ctx *Is_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCase_expr(ctx *Case_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitFunction_expr(ctx *Function_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitBlob_literal_expr(ctx *Blob_literal_exprContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSubquery(ctx *SubqueryContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitExpr_list(ctx *Expr_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitComparisonOperator(ctx *ComparisonOperatorContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCast_type(ctx *Cast_typeContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitType_cast(ctx *Type_castContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitValue_row(ctx *Value_rowContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitValues_clause(ctx *Values_clauseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitInsert_core(ctx *Insert_coreContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitInsert_stmt(ctx *Insert_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitReturning_clause(ctx *Returning_clauseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUpsert_update(ctx *Upsert_updateContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUpsert_clause(ctx *Upsert_clauseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSelect_core(ctx *Select_coreContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSelect_stmt(ctx *Select_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitJoin_relation(ctx *Join_relationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitRelation(ctx *RelationContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitSimple_select(ctx *Simple_selectContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitTable_or_subquery(ctx *Table_or_subqueryContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitResult_column(ctx *Result_columnContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitReturning_clause_result_column(ctx *Returning_clause_result_columnContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitJoin_operator(ctx *Join_operatorContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitJoin_constraint(ctx *Join_constraintContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCompound_operator(ctx *Compound_operatorContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUpdate_set_subclause(ctx *Update_set_subclauseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUpdate_core(ctx *Update_coreContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitUpdate_stmt(ctx *Update_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitColumn_name_list(ctx *Column_name_listContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitQualified_table_name(ctx *Qualified_table_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitOrder_by_stmt(ctx *Order_by_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitLimit_stmt(ctx *Limit_stmtContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitOrdering_term(ctx *Ordering_termContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitAsc_desc(ctx *Asc_descContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitFunction_keyword(ctx *Function_keywordContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitFunction_name(ctx *Function_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitTable_name(ctx *Table_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitTable_alias(ctx *Table_aliasContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitColumn_name(ctx *Column_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitColumn_alias(ctx *Column_aliasContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitCollation_name(ctx *Collation_nameContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BaseSQLParserVisitor) VisitIndex_name(ctx *Index_nameContext) interface{} { - return v.VisitChildren(ctx) -} diff --git a/parse/sql/gen/sqlparser_visitor.go b/parse/sql/gen/sqlparser_visitor.go deleted file mode 100644 index 8e090c2b4..000000000 --- a/parse/sql/gen/sqlparser_visitor.go +++ /dev/null @@ -1,243 +0,0 @@ -// Code generated from SQLParser.g4 by ANTLR 4.13.1. DO NOT EDIT. - -package sqlgrammar // SQLParser -import "github.com/antlr4-go/antlr/v4" - -// A complete Visitor for a parse tree produced by SQLParser. -type SQLParserVisitor interface { - antlr.ParseTreeVisitor - - // Visit a parse tree produced by SQLParser#statements. - VisitStatements(ctx *StatementsContext) interface{} - - // Visit a parse tree produced by SQLParser#sql_stmt_list. - VisitSql_stmt_list(ctx *Sql_stmt_listContext) interface{} - - // Visit a parse tree produced by SQLParser#sql_stmt. - VisitSql_stmt(ctx *Sql_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#indexed_column. - VisitIndexed_column(ctx *Indexed_columnContext) interface{} - - // Visit a parse tree produced by SQLParser#cte_table_name. - VisitCte_table_name(ctx *Cte_table_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#common_table_expression. - VisitCommon_table_expression(ctx *Common_table_expressionContext) interface{} - - // Visit a parse tree produced by SQLParser#common_table_stmt. - VisitCommon_table_stmt(ctx *Common_table_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#delete_core. - VisitDelete_core(ctx *Delete_coreContext) interface{} - - // Visit a parse tree produced by SQLParser#delete_stmt. - VisitDelete_stmt(ctx *Delete_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#variable. - VisitVariable(ctx *VariableContext) interface{} - - // Visit a parse tree produced by SQLParser#normal_function_call. - VisitNormal_function_call(ctx *Normal_function_callContext) interface{} - - // Visit a parse tree produced by SQLParser#foreign_function_call. - VisitForeign_function_call(ctx *Foreign_function_callContext) interface{} - - // Visit a parse tree produced by SQLParser#column_ref. - VisitColumn_ref(ctx *Column_refContext) interface{} - - // Visit a parse tree produced by SQLParser#when_clause. - VisitWhen_clause(ctx *When_clauseContext) interface{} - - // Visit a parse tree produced by SQLParser#subquery_expr. - VisitSubquery_expr(ctx *Subquery_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#logical_not_expr. - VisitLogical_not_expr(ctx *Logical_not_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#boolean_literal_expr. - VisitBoolean_literal_expr(ctx *Boolean_literal_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#comparison_expr. - VisitComparison_expr(ctx *Comparison_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#like_expr. - VisitLike_expr(ctx *Like_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#null_expr. - VisitNull_expr(ctx *Null_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#column_expr. - VisitColumn_expr(ctx *Column_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#in_subquery_expr. - VisitIn_subquery_expr(ctx *In_subquery_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#arithmetic_expr. - VisitArithmetic_expr(ctx *Arithmetic_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#logical_binary_expr. - VisitLogical_binary_expr(ctx *Logical_binary_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#variable_expr. - VisitVariable_expr(ctx *Variable_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#text_literal_expr. - VisitText_literal_expr(ctx *Text_literal_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#unary_expr. - VisitUnary_expr(ctx *Unary_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#collate_expr. - VisitCollate_expr(ctx *Collate_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#parenthesized_expr. - VisitParenthesized_expr(ctx *Parenthesized_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#between_expr. - VisitBetween_expr(ctx *Between_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#expr_list_expr. - VisitExpr_list_expr(ctx *Expr_list_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#numeric_literal_expr. - VisitNumeric_literal_expr(ctx *Numeric_literal_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#null_literal_expr. - VisitNull_literal_expr(ctx *Null_literal_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#in_list_expr. - VisitIn_list_expr(ctx *In_list_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#is_expr. - VisitIs_expr(ctx *Is_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#case_expr. - VisitCase_expr(ctx *Case_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#function_expr. - VisitFunction_expr(ctx *Function_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#blob_literal_expr. - VisitBlob_literal_expr(ctx *Blob_literal_exprContext) interface{} - - // Visit a parse tree produced by SQLParser#subquery. - VisitSubquery(ctx *SubqueryContext) interface{} - - // Visit a parse tree produced by SQLParser#expr_list. - VisitExpr_list(ctx *Expr_listContext) interface{} - - // Visit a parse tree produced by SQLParser#comparisonOperator. - VisitComparisonOperator(ctx *ComparisonOperatorContext) interface{} - - // Visit a parse tree produced by SQLParser#cast_type. - VisitCast_type(ctx *Cast_typeContext) interface{} - - // Visit a parse tree produced by SQLParser#type_cast. - VisitType_cast(ctx *Type_castContext) interface{} - - // Visit a parse tree produced by SQLParser#value_row. - VisitValue_row(ctx *Value_rowContext) interface{} - - // Visit a parse tree produced by SQLParser#values_clause. - VisitValues_clause(ctx *Values_clauseContext) interface{} - - // Visit a parse tree produced by SQLParser#insert_core. - VisitInsert_core(ctx *Insert_coreContext) interface{} - - // Visit a parse tree produced by SQLParser#insert_stmt. - VisitInsert_stmt(ctx *Insert_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#returning_clause. - VisitReturning_clause(ctx *Returning_clauseContext) interface{} - - // Visit a parse tree produced by SQLParser#upsert_update. - VisitUpsert_update(ctx *Upsert_updateContext) interface{} - - // Visit a parse tree produced by SQLParser#upsert_clause. - VisitUpsert_clause(ctx *Upsert_clauseContext) interface{} - - // Visit a parse tree produced by SQLParser#select_core. - VisitSelect_core(ctx *Select_coreContext) interface{} - - // Visit a parse tree produced by SQLParser#select_stmt. - VisitSelect_stmt(ctx *Select_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#join_relation. - VisitJoin_relation(ctx *Join_relationContext) interface{} - - // Visit a parse tree produced by SQLParser#relation. - VisitRelation(ctx *RelationContext) interface{} - - // Visit a parse tree produced by SQLParser#simple_select. - VisitSimple_select(ctx *Simple_selectContext) interface{} - - // Visit a parse tree produced by SQLParser#table_or_subquery. - VisitTable_or_subquery(ctx *Table_or_subqueryContext) interface{} - - // Visit a parse tree produced by SQLParser#result_column. - VisitResult_column(ctx *Result_columnContext) interface{} - - // Visit a parse tree produced by SQLParser#returning_clause_result_column. - VisitReturning_clause_result_column(ctx *Returning_clause_result_columnContext) interface{} - - // Visit a parse tree produced by SQLParser#join_operator. - VisitJoin_operator(ctx *Join_operatorContext) interface{} - - // Visit a parse tree produced by SQLParser#join_constraint. - VisitJoin_constraint(ctx *Join_constraintContext) interface{} - - // Visit a parse tree produced by SQLParser#compound_operator. - VisitCompound_operator(ctx *Compound_operatorContext) interface{} - - // Visit a parse tree produced by SQLParser#update_set_subclause. - VisitUpdate_set_subclause(ctx *Update_set_subclauseContext) interface{} - - // Visit a parse tree produced by SQLParser#update_core. - VisitUpdate_core(ctx *Update_coreContext) interface{} - - // Visit a parse tree produced by SQLParser#update_stmt. - VisitUpdate_stmt(ctx *Update_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#column_name_list. - VisitColumn_name_list(ctx *Column_name_listContext) interface{} - - // Visit a parse tree produced by SQLParser#qualified_table_name. - VisitQualified_table_name(ctx *Qualified_table_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#order_by_stmt. - VisitOrder_by_stmt(ctx *Order_by_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#limit_stmt. - VisitLimit_stmt(ctx *Limit_stmtContext) interface{} - - // Visit a parse tree produced by SQLParser#ordering_term. - VisitOrdering_term(ctx *Ordering_termContext) interface{} - - // Visit a parse tree produced by SQLParser#asc_desc. - VisitAsc_desc(ctx *Asc_descContext) interface{} - - // Visit a parse tree produced by SQLParser#function_keyword. - VisitFunction_keyword(ctx *Function_keywordContext) interface{} - - // Visit a parse tree produced by SQLParser#function_name. - VisitFunction_name(ctx *Function_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#table_name. - VisitTable_name(ctx *Table_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#table_alias. - VisitTable_alias(ctx *Table_aliasContext) interface{} - - // Visit a parse tree produced by SQLParser#column_name. - VisitColumn_name(ctx *Column_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#column_alias. - VisitColumn_alias(ctx *Column_aliasContext) interface{} - - // Visit a parse tree produced by SQLParser#collation_name. - VisitCollation_name(ctx *Collation_nameContext) interface{} - - // Visit a parse tree produced by SQLParser#index_name. - VisitIndex_name(ctx *Index_nameContext) interface{} -} diff --git a/parse/sql/grammar/SQLLexer.g4 b/parse/sql/grammar/SQLLexer.g4 deleted file mode 100644 index 17d02eca2..000000000 --- a/parse/sql/grammar/SQLLexer.g4 +++ /dev/null @@ -1,156 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 by Martin Mirchev - * - * 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. - * - * Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser - * Developed by : Bart Kiers, bart@big-o.nl - */ - -// $antlr-format alignTrailingComments on, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments off, useTab off -// $antlr-format allowShortRulesOnASingleLine on, alignSemicolons ownLine - -lexer grammar SQLLexer; - -options { caseInsensitive = true; } - -SCOL: ';'; -DOT: '.'; -OPEN_PAR: '('; -CLOSE_PAR: ')'; -L_BRACKET: '['; -R_BRACKET: ']'; -COMMA: ','; -ASSIGN: '='; -STAR: '*'; -PLUS: '+'; -MINUS: '-'; -DIV: '/'; -MOD: '%'; -LT: '<'; -LT_EQ: '<='; -GT: '>'; -GT_EQ: '>='; -NOT_EQ1: '!='; -NOT_EQ2: '<>'; -TYPE_CAST: '::'; - -// http://www.sqlite.org/lang_keywords.html -ADD_: 'ADD'; -ALL_: 'ALL'; -AND_: 'AND'; -ASC_: 'ASC'; -AS_: 'AS'; -BETWEEN_: 'BETWEEN'; -BY_: 'BY'; -CASE_: 'CASE'; -COLLATE_: 'COLLATE'; -COMMIT_: 'COMMIT'; -CONFLICT_: 'CONFLICT'; -CREATE_: 'CREATE'; -CROSS_: 'CROSS'; -DEFAULT_: 'DEFAULT'; -DELETE_: 'DELETE'; -DESC_: 'DESC'; -DISTINCT_: 'DISTINCT'; -DO_: 'DO'; -ELSE_: 'ELSE'; -END_: 'END'; -ESCAPE_: 'ESCAPE'; -EXCEPT_: 'EXCEPT'; -EXISTS_: 'EXISTS'; -FILTER_: 'FILTER'; -FIRST_: 'FIRST'; -FROM_: 'FROM'; -FULL_: 'FULL'; -GROUPS_: 'GROUPS'; -GROUP_: 'GROUP'; -HAVING_: 'HAVING'; -INNER_: 'INNER'; -INSERT_: 'INSERT'; -INTERSECT_: 'INTERSECT'; -INTO_: 'INTO'; -IN_: 'IN'; -ISNULL_: 'ISNULL'; -IS_: 'IS'; -JOIN_: 'JOIN'; -LAST_: 'LAST'; -LEFT_: 'LEFT'; -LIKE_: 'LIKE'; -LIMIT_: 'LIMIT'; -NOTHING_: 'NOTHING'; -NOTNULL_: 'NOTNULL'; -NOT_: 'NOT'; -NULLS_: 'NULLS'; -OFFSET_: 'OFFSET'; -OF_: 'OF'; -ON_: 'ON'; -ORDER_: 'ORDER'; -OR_: 'OR'; -OUTER_: 'OUTER'; -RAISE_: 'RAISE'; -REPLACE_: 'REPLACE'; -RETURNING_: 'RETURNING'; -RIGHT_: 'RIGHT'; -SELECT_: 'SELECT'; -SET_: 'SET'; -THEN_: 'THEN'; -UNION_: 'UNION'; -UPDATE_: 'UPDATE'; -USING_: 'USING'; -VALUES_: 'VALUES'; -WHEN_: 'WHEN'; -WHERE_: 'WHERE'; -WITH_: 'WITH'; - -// literals - -BOOLEAN_LITERAL: - 'true' - | 'false' -; - -NUMERIC_LITERAL: - [0-9]+ -; - -BLOB_LITERAL: - '0x' [0-9a-f]+ -; - -TEXT_LITERAL: - '\'' ( ~'\'' | '\'\'')* '\'' -; - -NULL_LITERAL: 'null'; - -IDENTIFIER: - '"' (~'"' | '""')* '"' // Delimited identifiers - | '`' (~'`' | '``')* '`' - | [A-Z_] [A-Z_0-9]* // Ordinary identifiers -; - -BIND_PARAMETER: [@$] IDENTIFIER; - -SINGLE_LINE_COMMENT: '--' ~[\r\n]* (('\r'? '\n') | EOF) -> channel(HIDDEN); - -MULTILINE_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); - -SPACES: [ \u000B\t\r\n] -> channel(HIDDEN); - -UNEXPECTED_CHAR: .; diff --git a/parse/sql/grammar/SQLParser.g4 b/parse/sql/grammar/SQLParser.g4 deleted file mode 100644 index b643f1bc8..000000000 --- a/parse/sql/grammar/SQLParser.g4 +++ /dev/null @@ -1,393 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 by Bart Kiers - * - * 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. - * - * Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser - * Developed by: - * Bart Kiers, bart@big-o.nl - * Martin Mirchev, marti_2203@abv.bg - * Mike Lische, mike@lischke-online.de - */ - -// $antlr-format alignTrailingComments on, columnLimit 130, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments off -// $antlr-format useTab off, allowShortRulesOnASingleLine off, allowShortBlocksOnASingleLine on, alignSemicolons ownLine - -parser grammar SQLParser; - -options { - tokenVocab = SQLLexer; -} - -statements: (sql_stmt_list)* EOF -; - -sql_stmt_list: - SCOL* sql_stmt (SCOL+ sql_stmt)* SCOL* -; - -sql_stmt: ( - delete_stmt - | insert_stmt - | select_stmt - | update_stmt - ) -; - -indexed_column: column_name -; - -cte_table_name: - table_name (OPEN_PAR column_name (COMMA column_name)* CLOSE_PAR)? -; - -common_table_expression: - cte_table_name AS_ OPEN_PAR select_core CLOSE_PAR -; - -common_table_stmt: //additional structures - WITH_ common_table_expression (COMMA common_table_expression)* -; - -delete_core: - DELETE_ FROM_ qualified_table_name - (WHERE_ expr)? - returning_clause? -; - -delete_stmt: - common_table_stmt? - delete_core -; - -variable: - BIND_PARAMETER -; - -function_call: - function_name OPEN_PAR ((DISTINCT_? expr_list) | STAR)? CLOSE_PAR #normal_function_call - | IDENTIFIER L_BRACKET dbid=expr COMMA procedure=expr R_BRACKET OPEN_PAR expr_list? CLOSE_PAR #foreign_function_call -; - - -column_ref: - (table_name DOT)? column_name -; - -when_clause: - WHEN_ condition=expr THEN_ result=expr -; - -/* - https://www.postgresql.org/docs/16/sql-syntax-lexical.html#SQL-PRECEDENCE - - Operator/Element Associativity Description - . left table/column name separator - :: left PostgreSQL-style typecast - [ ] left array element selection - + - right unary plus, unary minus - COLLATE left collation selection - AT left AT TIME ZONE - ^ left exponentiation - * / % left multiplication, division, modulo - + - left addition, subtraction - (any other operator) left all other native and user-defined operators - BETWEEN IN LIKE ILIKE SIMILAR range containment, set membership, string matching - < > = <= >= <> comparison operators - IS ISNULL NOTNULL IS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc. - NOT right logical negation - AND left logical conjunction - OR left logical disjunction - -=========== -Another way to layout expr rules is to group them by the same level of precedence, -expr: - bool_expr - | ... -; -bool_expr: - predicate_expr - | ... -; -predicate_expr: - arithmatic_expr - | ... -; -arithmatic_expr: - primary_expr - | ... -; -primary_expr: - literal_expr - | ... -; -============ -Type cast can only be applied to: - literal_value - BIND_PARAMETER - column_name - () parenthesesed expr - function_call -*/ -expr: - TEXT_LITERAL type_cast? #text_literal_expr - | BOOLEAN_LITERAL type_cast? #boolean_literal_expr - | NUMERIC_LITERAL type_cast? #numeric_literal_expr - | NULL_LITERAL type_cast? #null_literal_expr - | BLOB_LITERAL type_cast? #blob_literal_expr - | variable type_cast? #variable_expr - | column_ref type_cast? #column_expr - | operator=(MINUS | PLUS) expr #unary_expr - | expr COLLATE_ collation_name #collate_expr - | OPEN_PAR expr CLOSE_PAR type_cast? #parenthesized_expr - | ((NOT_)? EXISTS_)? subquery #subquery_expr - | CASE_ case_clause=expr? - when_clause+ - (ELSE_ else_clause=expr)? END_ #case_expr - | OPEN_PAR expr_list CLOSE_PAR #expr_list_expr - | function_call type_cast? #function_expr - // arithmetic expressions - // exponentiation - | left=expr operator=(STAR|DIV|MOD) right=expr #arithmetic_expr - | left=expr operator=(PLUS|MINUS) right=expr #arithmetic_expr - // boolean expressions - // predicate - | elem=expr NOT_? operator=IN_ subquery #in_subquery_expr - | elem=expr NOT_? operator=IN_ OPEN_PAR expr_list CLOSE_PAR #in_list_expr - | elem=expr NOT_? operator=BETWEEN_ low=expr AND_ high=expr #between_expr - | elem=expr NOT_? operator=LIKE_ pattern=expr (ESCAPE_ escape=expr)? #like_expr - // comparison - | left=expr comparisonOperator right=expr #comparison_expr - //| left=expr comparisonOperator right=subquery #scalar_subquery_expr - | expr IS_ NOT_? ((DISTINCT_ FROM_ expr)|BOOLEAN_LITERAL|NULL_LITERAL)#is_expr - | expr (ISNULL_ | NOTNULL_) #null_expr - // logical expressions - | NOT_ expr #logical_not_expr - | left=expr operator=AND_ right=expr #logical_binary_expr - | left=expr operator=OR_ right=expr #logical_binary_expr -; - -subquery: - OPEN_PAR select_core CLOSE_PAR // note: don't support with clause in subquery -; - -expr_list: - expr (COMMA expr)* -; - -comparisonOperator: - LT|LT_EQ|GT|GT_EQ|ASSIGN|NOT_EQ1|NOT_EQ2 -; - -cast_type: - IDENTIFIER (L_BRACKET R_BRACKET)? -; - -type_cast: - TYPE_CAST cast_type -; - -value_row: - OPEN_PAR expr (COMMA expr)* CLOSE_PAR -; - -values_clause: - VALUES_ value_row (COMMA value_row)* -; - -insert_core: - INSERT_ INTO_ table_name - (AS_ table_alias)? - (OPEN_PAR column_name ( COMMA column_name)* CLOSE_PAR)? - values_clause - upsert_clause? - returning_clause? -; - -insert_stmt: - common_table_stmt? - insert_core -; - -returning_clause: - RETURNING_ returning_clause_result_column (COMMA returning_clause_result_column)* -; - -// @yaiba eaiser to parse this way -upsert_update: - (column_name | column_name_list) ASSIGN expr -; - -upsert_clause: - ON_ CONFLICT_ - (OPEN_PAR indexed_column (COMMA indexed_column)* CLOSE_PAR (WHERE_ target_expr=expr)?)? - DO_ - ( - NOTHING_ - | UPDATE_ SET_ - ( - upsert_update (COMMA upsert_update)* - (WHERE_ update_expr=expr)? - ) - ) -; - -select_core: - simple_select - (compound_operator simple_select)* - order_by_stmt? - limit_stmt? -; - -select_stmt: - common_table_stmt? - select_core -; - -join_relation: - join_operator right_relation=table_or_subquery join_constraint -; - -relation: - table_or_subquery join_relation* -; - -simple_select: - SELECT_ DISTINCT_? - result_column (COMMA result_column)* - (FROM_ relation)? - (WHERE_ whereExpr=expr)? - ( - GROUP_ BY_ groupByExpr+=expr (COMMA groupByExpr+=expr)* - (HAVING_ havingExpr=expr)? - )? -; - -table_or_subquery: - function_call (AS_ table_alias)? - | table_name (AS_ table_alias)? - | OPEN_PAR select_core CLOSE_PAR (AS_ table_alias)? -; - -result_column: - STAR - | table_name DOT STAR - | expr (AS_ column_alias)? -; - -returning_clause_result_column: - STAR - | expr (AS_ column_alias)? -; - -join_operator: - ((LEFT_ | RIGHT_ | FULL_) OUTER_? | INNER_)? - JOIN_ -; - -join_constraint: - ON_ expr -; - -compound_operator: - UNION_ ALL_? - | INTERSECT_ - | EXCEPT_ -; - -update_set_subclause: - (column_name | column_name_list) ASSIGN expr -; - -update_core: - UPDATE_ - qualified_table_name - SET_ update_set_subclause (COMMA update_set_subclause)* - (FROM_ relation)? - (WHERE_ expr)? - returning_clause? -; - -update_stmt: - common_table_stmt? - update_core -; - -column_name_list: - OPEN_PAR column_name (COMMA column_name)* CLOSE_PAR -; - -qualified_table_name: - table_name (AS_ table_alias)? -; - -order_by_stmt: - ORDER_ BY_ ordering_term (COMMA ordering_term)* -; - -limit_stmt: - LIMIT_ expr (OFFSET_ expr)? -; - -ordering_term: - expr - asc_desc? - (NULLS_ (FIRST_ | LAST_))? -; - -asc_desc: - ASC_ - | DESC_ -; - - -// function_keywords are keywords also function names -function_keyword: - LIKE_ - | REPLACE_ -; - -function_name: - IDENTIFIER - | function_keyword -; - -table_name: - IDENTIFIER -; - -table_alias: - IDENTIFIER -; - -column_name: - IDENTIFIER -; - -column_alias: - IDENTIFIER -; - -collation_name: - IDENTIFIER // back-compatible with sqlite, NOCASE -; - -index_name: - IDENTIFIER -; - diff --git a/parse/sql/grammar/generate.sh b/parse/sql/grammar/generate.sh deleted file mode 100755 index b1a6bee3d..000000000 --- a/parse/sql/grammar/generate.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -set -e - -cd "$(dirname "$0")" - -target=${1:-Go} -package=${2:-sqlgrammar} -output_dir=${3:-../gen} - -antlr_bin=antlr-4.13.1-complete.jar - -if [ ! -f $antlr_bin ]; then - echo "Downloading antlr4 jar file..." - curl -O https://www.antlr.org/download/${antlr_bin} -fi - -alias antlr4='java -Xmx500M -cp "./${antlr_bin}:$CLASSPATH" org.antlr.v4.Tool' -antlr4 -Dlanguage="${target}" -visitor -no-listener -package "${package}" -o "${output_dir}" *.g4 \ No newline at end of file diff --git a/parse/sql/parser.go b/parse/sql/parser.go deleted file mode 100644 index c37472978..000000000 --- a/parse/sql/parser.go +++ /dev/null @@ -1,101 +0,0 @@ -package sqlparser - -import ( - "fmt" - "runtime" - - antlr "github.com/antlr4-go/antlr/v4" - - grammar "github.com/kwilteam/kwil-db/parse/sql/gen" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// Parse parses a raw sql string and returns a tree.Statement. -// It should only be used if the user is trying to parse a single -// sql statement, and doesn't care about error handling. -func Parse(sql string) (tree.Statement, error) { - stmts, err := ParseMany(sql) - if err != nil { - return nil, err - } - - if len(stmts) != 1 { - return nil, fmt.Errorf("expected 1 statement, but found %d", len(stmts)) - } - - return stmts[0], nil -} - -// ParseMany parses a raw sql string and returns tree.Statements. -// It should only be used if the user is trying to parse multiple -// sql statements, and doesn't care about error handling. -func ParseMany(sql string) ([]tree.Statement, error) { - errorListener := parseTypes.NewErrorListener() - ast, err := ParseWithErrorListener(sql, errorListener) - if err != nil { - return nil, err - } - - if errorListener.Err() != nil { - return nil, errorListener.Err() - } - - return ast, nil -} - -// ParseWithErrorListener parses a raw sql string and returns tree.Statements. -// Syntax errors are returned in the error listener. -func ParseWithErrorListener(sql string, errorListener parseTypes.AntlrErrorListener) (stmts []tree.Statement, err error) { - stream := antlr.NewInputStream(sql) - lexer := grammar.NewSQLLexer(stream) - tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) - p := grammar.NewSQLParser(tokenStream) - - // remove default error visitor - lexer.RemoveErrorListeners() - lexer.AddErrorListener(errorListener) - - p.RemoveErrorListeners() - p.AddErrorListener(errorListener) - - p.BuildParseTrees = true - - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("panic: %v", e) - } - - // if there is a panic, it is likely due to a syntax error - // check for parse errors and return them first - if errorListener.Err() != nil { - // if there is an error listener error, we should swallow the panic - // If the issue persists until after the user has fixed the parse errors, - // the panic will be returned in the else block. - err = nil - } else { - // if there are no parse errors, then there is a bug. - // we should return the panic with a stack trace. - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - - err = fmt.Errorf("%w\n\n%s", err, buf[:stackSize]) - } - } - }() - - visitor := &astBuilder{ - errs: errorListener, - } - parsed := p.Statements().Accept(visitor).([]tree.AstNode) - - s := make([]tree.Statement, len(parsed)) - for i, stmt := range parsed { - s[i] = stmt.(tree.Statement) - } - - return s, nil -} diff --git a/parse/sql/parser_test.go b/parse/sql/parser_test.go deleted file mode 100644 index b6512e3e5..000000000 --- a/parse/sql/parser_test.go +++ /dev/null @@ -1,2644 +0,0 @@ -package sqlparser - -import ( - "flag" - "fmt" - "regexp" - "strconv" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/sql/postgres" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var traceMode = flag.Bool("trace-mode", false, "run tests with tracing") - -var columnStar = []tree.ResultColumn{ - &tree.ResultColumnStar{}, -} - -func Test_ParseMany(t *testing.T) { - stmt := "select * from users; select * from users2;" - res, err := ParseMany(stmt) - if err != nil { - t.Fatal(err) - } - - for _, s := range res { - checkNodesAreSet(t, s) - } - - require.Equal(t, 2, len(res)) -} - -func genLiteralExpression(value string) tree.Expression { - // if it has single quote, it is a string literal - // otherwise, we will try to make it a number - if strings.HasPrefix(value, "'") && strings.HasSuffix(value, "'") { - return &tree.ExpressionTextLiteral{Value: value[1 : len(value)-1]} - } - - s, err := strconv.ParseInt(value, 10, 64) - if err == nil { - return &tree.ExpressionNumericLiteral{Value: s} - } - - if strings.EqualFold(value, "true") { - return &tree.ExpressionBooleanLiteral{Value: true} - } else if strings.EqualFold(value, "false") { - return &tree.ExpressionBooleanLiteral{Value: false} - } else if strings.EqualFold(value, "null") { - return &tree.ExpressionNullLiteral{} - } - - panic(fmt.Sprintf("unsupported literal value: %s", value)) -} - -func getResultColumnExprs(values ...string) []tree.ResultColumn { - t := make([]tree.ResultColumn, len(values)) - for i, v := range values { - t[i] = &tree.ResultColumnExpression{ - Expression: genLiteralExpression(v), - } - } - return t -} - -func genSelectUnaryExprTree(op tree.UnaryOperator, value string) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionUnary{ - Operator: op, - Operand: genLiteralExpression(value), - }, - }, - }, - }, - }, - }, - } -} - -func genSelectColumnLiteralTree(value string) *tree.SelectStmt { - t := tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: genLiteralExpression(value), - }, - }, - }, - }, - }} - return &t -} - -func genSelectColumnStarTree() *tree.SelectStmt { - t := tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnStar{}, - }, - }, - }, - }} - return &t -} - -func genSelectColumnTableTree(table string) *tree.SelectStmt { - t := tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnTable{TableName: table}, - }, - }, - }, - }} - return &t -} - -func genSimpleCompoundSelectTree(op tree.CompoundOperatorType) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: getResultColumnExprs("1"), - }, - { - SelectType: tree.SelectTypeAll, - Columns: getResultColumnExprs("2"), - Compound: &tree.CompoundOperator{Operator: op}, - }, - }, - }, - } -} - -func genSimpleCollateSelectTree(collateType tree.CollationType, value string) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCollate{ - Expression: genLiteralExpression(value), - Collation: collateType, - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleBinaryCompareSelectTree(op tree.BinaryOperator, leftValue, rightValue string) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Left: genLiteralExpression(leftValue), - Operator: op, - Right: genLiteralExpression(rightValue), - }, - }, - }, - }, - }, - }, - } -} - -func genSimplyArithmeticSelectTree(op tree.ArithmeticOperator, leftValue, rightValue string) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionArithmetic{ - Left: genLiteralExpression(leftValue), - Operator: op, - Right: genLiteralExpression(rightValue), - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleStringCompareSelectTree(op tree.StringOperator, leftValue, rightValue, escape string) *tree.SelectStmt { - - var escapeExpr tree.Expression - if escape != "" { - escapeExpr = genLiteralExpression(escape) - } - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionStringCompare{ - Left: genLiteralExpression(leftValue), - Operator: op, - Right: genLiteralExpression(rightValue), - Escape: escapeExpr, - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleCTETree(table, value string) *tree.CTE { - return &tree.CTE{ - Table: table, - Select: genSelectColumnLiteralTree(value).Stmt, - } -} - -func genSimpleExprNullSelectTree(value string, not bool) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionIs{ - Left: genLiteralExpression(value), - Distinct: false, - Not: not, - Right: genLiteralExpression("NULL"), - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleExprIsSelectTree(left string, right string, not bool) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionIs{ - Left: genLiteralExpression(left), - Distinct: false, - Not: not, - Right: genLiteralExpression(right), - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleFunctionSelectTree(f string, inputs ...tree.Expression) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionFunction{ - Function: f, - Inputs: inputs, - }, - }, - }, - }, - }, - }, - } -} - -func genDistinctFunctionSelectTree(f string, inputs ...tree.Expression) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionFunction{ - Function: f, - Inputs: inputs, - Distinct: true, - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleJoinSelectTree(joinOP *tree.JoinOperator, t1, t1Column, t2, t2Column string) *tree.SelectStmt { - return &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnStar{}, - }, - From: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: t1, - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: joinOP, - Table: &tree.RelationTable{Name: t2}, - Constraint: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Table: t1, Column: t1Column}, - Right: &tree.ExpressionColumn{Table: t2, Column: t2Column}, - }, - }, - }, - }, - }, - }, - }, - } -} - -func genSimpleUpdateTree(qt *tree.QualifiedTableName, column, value string) *tree.UpdateStmt { - return &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: qt, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{column}, - Expression: genLiteralExpression(value), - }, - }, - }, - } -} - -// deepCompare deep compares the values of two nodes. -// It ignores the parseTypes.Node field. -func deepCompare(node1, node2 tree.AstNode) bool { - // we return true for the parseTypes.Node field, - // we also need to ignore the unexported "schema" fields - return cmp.Equal(node1, node2, cmp.Comparer(func(x, y parseTypes.Node) bool { - return true - }), cmpopts.IgnoreUnexported(tree.RelationTable{}, tree.InsertCore{}, tree.QualifiedTableName{})) -} - -func TestParseRawSQL_syntax_valid(t *testing.T) { - tests := []struct { - name string - input string - expect tree.AstNode - }{ - // with semicolon at the end - {"with semicolon", "select *;", genSelectColumnStarTree()}, - // common table stmt - {"cte", "with t as (select 1) select *", - &tree.SelectStmt{ - CTE: []*tree.CTE{genSimpleCTETree("t", "1")}, - Stmt: genSelectColumnStarTree().Stmt, - }, - }, - {"cte with column", "with t(c1,c2) as (select 1) select *", - &tree.SelectStmt{ - CTE: []*tree.CTE{ - { - Table: "t", - Columns: []string{"c1", "c2"}, - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - Stmt: genSelectColumnStarTree().Stmt, - }, - }, - //// compound operator - {"compound union", "select 1 union select 2", - genSimpleCompoundSelectTree(tree.CompoundOperatorTypeUnion), - }, - {"compound union all", "select 1 union all select 2", - genSimpleCompoundSelectTree(tree.CompoundOperatorTypeUnionAll), - }, - {"compound intersect", "select 1 intersect select 2", - genSimpleCompoundSelectTree(tree.CompoundOperatorTypeIntersect), - }, - {"compound except", "select 1 except select 2", - genSimpleCompoundSelectTree(tree.CompoundOperatorTypeExcept), - }, - // result column - {"*", "select *", genSelectColumnStarTree()}, - {"table.*", "select t.*", genSelectColumnTableTree("t")}, - //// table or subquery - {"table or subquery", "select * from t1 as tt", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - Alias: "tt", - }, - }, - }, - }, - }, - }, - {"table or subquery nest select", "select * from (select 1) as tt", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationSubquery{ - Select: genSelectColumnLiteralTree("1").Stmt, - Alias: "tt", - }, - }, - }, - }, - }, - }, - {"table or subquery join", "select * from t1 as tt join t2 as ttt on tt.a = ttt.a", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationJoin{ - Relation: &tree.RelationTable{Name: "t1", Alias: "tt"}, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeJoin, - Outer: false, - }, - Table: &tree.RelationTable{Name: "t2", Alias: "ttt"}, - Constraint: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "tt", - Column: "a", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionColumn{ - Table: "ttt", - Column: "a", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - //// expr - // literal value,, - {"number", "select 1", genSelectColumnLiteralTree("1")}, - {"string", "select 'a'", genSelectColumnLiteralTree("'a'")}, - {"null", "select NULL", genSelectColumnLiteralTree("NULL")}, - {"true", "select true", genSelectColumnLiteralTree("true")}, - {"false", "select false", genSelectColumnLiteralTree("false")}, - // bind parameter - {"expr bind parameter $", "select $a", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - }, - }, - }}}, - {"expr bind parameter @", "select @a", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBindParameter{ - Parameter: "@a", - }, - }, - }, - }, - }, - }}}, - {"expr names", "select t1.c1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionColumn{ - Table: "t1", - Column: "c1", - }, - }, - }, - }, - }, - }}}, - // unary op - {"expr unary op +", "select +1", genSelectUnaryExprTree(tree.UnaryOperatorPlus, "1")}, - {"expr unary op -", "select -1", genSelectUnaryExprTree(tree.UnaryOperatorMinus, "1")}, - {"expr unary op - twice, right associative", "select - -1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: genLiteralExpression("1"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - //{"expr unary op ~", "select ~1", genSelectUnaryExprTree(tree.UnaryOperatorBitNot, "1")}, - {"expr unary op not", "select not 1", genSelectUnaryExprTree(tree.UnaryOperatorNot, "1")}, - {"expr unary op not twice, right associative", "select not not true", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: genLiteralExpression("true"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - // binary op - //{"expr binary op ||", "select 1 || 2", - // genSimplyArithmeticSelectTree(tree.ArithmeticConcat, "1", "2")}, - {"expr binary op *", "select 1 * 2", - genSimplyArithmeticSelectTree(tree.ArithmeticOperatorMultiply, "1", "2")}, - {"expr binary op /", "select 1 / 2", - genSimplyArithmeticSelectTree(tree.ArithmeticOperatorDivide, "1", "2")}, - {"expr binary op %", "select 1 % 2", - genSimplyArithmeticSelectTree(tree.ArithmeticOperatorModulus, "1", "2")}, - {"expr binary op +", "select 1 + 2", - genSimplyArithmeticSelectTree(tree.ArithmeticOperatorAdd, "1", "2")}, - {"expr binary op -", "select 1 - 2", - genSimplyArithmeticSelectTree(tree.ArithmeticOperatorSubtract, "1", "2")}, - //{"expr binary op <<", "select 1 << 2", - // genSimplyArithmeticSelectTree(tree.ArithmeticOperatorBitwiseLeftShift, "1", "2")}, - //{"expr binary op >>", "select 1 >> 2", - // genSimplyArithmeticSelectTree(tree.ArithmeticOperatorBitwiseRightShift, "1", "2")}, - //{"expr binary op &", "select 1 & 2", - // genSimplyArithmeticSelectTree(tree.ArithmeticOperatorBitwiseAnd, "1", "2")}, - //{"expr binary op |", "select 1 | 2", - // genSimplyArithmeticSelectTree(tree.ArithmeticOperatorBitwiseOr, "1", "2")}, - {"expr binary op <", "select 1 < 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorLessThan, "1", "2")}, - {"expr binary op <=", "select 1 <= 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorLessThanOrEqual, "1", "2")}, - {"expr binary op >", "select 1 > 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorGreaterThan, "1", "2")}, - {"expr binary op >=", "select 1 >= 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorGreaterThanOrEqual, "1", "2")}, - {"expr binary op =", "select 1 = 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorEqual, "1", "2")}, - {"expr binary op !=", "select 1 != 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorNotEqual, "1", "2")}, - {"expr binary op <>", "select 1 <> 2", - genSimpleBinaryCompareSelectTree(tree.ComparisonOperatorNotEqualDiamond, "1", "2")}, - {"expr binary op and", "select 1 and 2", - genSimpleBinaryCompareSelectTree(tree.LogicalOperatorAnd, "1", "2")}, - {"expr binary op or", "select 1 or 2", - genSimpleBinaryCompareSelectTree(tree.LogicalOperatorOr, "1", "2")}, - // in - {"expr binary op in", "select 1 in (1,2)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Left: genLiteralExpression("1"), - Operator: tree.ComparisonOperatorIn, - Right: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr binary op not in", "select 1 not in (1,2)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Left: genLiteralExpression("1"), - Operator: tree.ComparisonOperatorNotIn, - Right: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr binary op in with select", "select 1 in (select 1)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Left: genLiteralExpression("1"), - Operator: tree.ComparisonOperatorIn, - Right: &tree.ExpressionSelect{ - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr binary op not in with select", "select 1 not in (select 1)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Left: genLiteralExpression("1"), - Operator: tree.ComparisonOperatorNotIn, - Right: &tree.ExpressionSelect{ - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - }, - }, - }, - }, - }, - }, - }, - // string compare - {"expr binary op like", "select 1 like 2", - genSimpleStringCompareSelectTree(tree.StringOperatorLike, "1", "2", "")}, - {"expr binary op not like", "select 1 not like 2", - genSimpleStringCompareSelectTree(tree.StringOperatorNotLike, "1", "2", "")}, - {"expr binary op like escape", "select 1 like 2 escape 3", - genSimpleStringCompareSelectTree(tree.StringOperatorLike, "1", "2", "3")}, - // function - // core functions - {"expr function abs", "select abs(1)", - genSimpleFunctionSelectTree("abs", genLiteralExpression("1"))}, - {"expr function error", "select error('error message')", - genSimpleFunctionSelectTree("error", genLiteralExpression(`'error message'`))}, - {"expr function format", `select format('%d',2)`, - genSimpleFunctionSelectTree("format", - genLiteralExpression(`'%d'`), genLiteralExpression("2"))}, - {"expr function length", `select length(1)`, - genSimpleFunctionSelectTree("length", genLiteralExpression("1"))}, - {"expr function lower", `select lower('Z')`, - genSimpleFunctionSelectTree("lower", genLiteralExpression("'Z'"))}, - {"expr function upper", `select upper('z')`, - genSimpleFunctionSelectTree("upper", genLiteralExpression("'z'"))}, - - // aggregate functions - {"expr function count", `select count(1)`, - genSimpleFunctionSelectTree("count", genLiteralExpression("1"))}, - {"expr function count distinct", `select count(distinct 1)`, - genDistinctFunctionSelectTree("count", genLiteralExpression("1"))}, - {"expr function sum", `select sum(1)`, - genSimpleFunctionSelectTree("sum", genLiteralExpression("1"))}, - {"expr function sum distinct", `select sum(distinct 1)`, - genDistinctFunctionSelectTree("sum", genLiteralExpression("1"))}, - - // expr list - {"expr list", "select (1,2)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - // expr precedence - {"expr precedence 1", "select -1 > 2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorGreaterThan, - Left: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: genLiteralExpression("1"), - }, - Right: genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - {"expr precedence 2", "SELECT NOT (-1 = 1) AND 1 notnull OR 3 < 2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Operator: tree.LogicalOperatorOr, - Left: &tree.ExpressionBinaryComparison{ - Operator: tree.LogicalOperatorAnd, - Left: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionBinaryComparison{ - Wrapped: true, - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: genLiteralExpression("1"), - }, - Right: genLiteralExpression("1"), - }, - }, - Right: &tree.ExpressionIs{ - Left: genLiteralExpression("1"), - Not: true, - Right: genLiteralExpression("NULL"), - }, - }, - Right: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorLessThan, - Left: genLiteralExpression("3"), - Right: genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr precedence 3", "SELECT NOT (-1 = 1) AND (1 notnull OR 3 < 2)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBinaryComparison{ - Operator: tree.LogicalOperatorAnd, - Left: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: genLiteralExpression("1"), - }, - Right: genLiteralExpression("1"), - Wrapped: true, - }, - }, - Right: &tree.ExpressionBinaryComparison{ - Wrapped: true, - Operator: tree.LogicalOperatorOr, - Left: &tree.ExpressionIs{ - Left: genLiteralExpression("1"), - Not: true, - Right: genLiteralExpression("NULL"), - }, - Right: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorLessThan, - Left: genLiteralExpression("3"), - Right: genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr precedence 4", "select not 3 + 4 * 5 - 2 = 2 + -1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionArithmetic{ - Operator: tree.ArithmeticOperatorSubtract, - Left: &tree.ExpressionArithmetic{ - Operator: tree.ArithmeticOperatorAdd, - Left: genLiteralExpression("3"), - Right: &tree.ExpressionArithmetic{ - Operator: tree.ArithmeticOperatorMultiply, - Left: genLiteralExpression("4"), - Right: genLiteralExpression("5"), - }, - }, - Right: genLiteralExpression("2"), - }, - Right: &tree.ExpressionArithmetic{ - Left: genLiteralExpression("2"), - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorMinus, - Operand: genLiteralExpression("1"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - - // collate - {"expr collate nocase", "select 1 collate nocase", - genSimpleCollateSelectTree(tree.CollationTypeNoCase, "1")}, - // is - {"expr isnull", "select 1 isnull", genSimpleExprNullSelectTree("1", false)}, - {"expr notnull", "select 1 notnull", genSimpleExprNullSelectTree("1", true)}, - {"expr not null", "select 1 is not null", genSimpleExprNullSelectTree("1", true)}, - {"expr is", "select true is true", - genSimpleExprIsSelectTree("true", "true", false)}, - {"expr is not", "select true is not true", - genSimpleExprIsSelectTree("true", "true", true)}, - {"expr is distinct from", "select 1 is distinct from 2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionIs{ - Left: genLiteralExpression("1"), - Right: genLiteralExpression("2"), - Distinct: true, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr is not distinct from", "select 1 is not distinct from 2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionIs{ - Left: genLiteralExpression("1"), - Right: genLiteralExpression("2"), - Distinct: true, - Not: true, - }, - }, - }, - }, - }, - }, - }, - }, - // between - {"expr between", "select 1 between 2 and 3", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBetween{ - Expression: genLiteralExpression("1"), - Left: genLiteralExpression("2"), - Right: genLiteralExpression("3"), - }, - }, - }, - }, - }, - }, - }, - }, - {"expr not between", "select 1 not between 2 and 3", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBetween{ - Expression: genLiteralExpression("1"), - Left: genLiteralExpression("2"), - Right: genLiteralExpression("3"), - NotBetween: true, - }, - }, - }, - }, - }, - }, - }, - }, - // - {"expr exists", "select (select 1)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionSelect{ - IsNot: false, - IsExists: false, - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr exists", "select exists (select 1)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionSelect{ - IsNot: false, - IsExists: true, - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr not exists", "select not exists (select 1)", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionSelect{ - IsNot: true, - IsExists: true, - Select: genSelectColumnLiteralTree("1").Stmt, - }, - }, - }, - }, - }, - }, - }, - }, - // case - {"expr case", "select case when 1 then 2 end", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCase{ - WhenThenPairs: [][2]tree.Expression{ - { - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr case else", "select case when 1 then 2 else 3 end", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCase{ - WhenThenPairs: [][2]tree.Expression{ - { - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - ElseExpression: genLiteralExpression("3"), - }, - }, - }, - }, - }, - }, - }, - }, - {"expr case multi when", "select case when 1 then 2 when 3 then 4 end", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCase{ - WhenThenPairs: [][2]tree.Expression{ - { - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - { - genLiteralExpression("3"), - genLiteralExpression("4"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - {"expr case expr", "select case 1 when 2 then 3 end", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCase{ - CaseExpression: genLiteralExpression("1"), - WhenThenPairs: [][2]tree.Expression{ - { - genLiteralExpression("2"), - genLiteralExpression("3"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - //// insert stmt - {"insert", "insert into t1 values (1)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{{genLiteralExpression("1")}}, - }}}, - {"insert with columns", "insert into t1 (a,b) values (1,2)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - { - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }}}}, - {"insert with columns with table alias", "insert into t1 as t (a,b) values (1,2)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - TableAlias: "t", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - { - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }}}}, - {"insert with columns with bind parameter", "insert into t1 (a,b) values ($a, $b)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - { - &tree.ExpressionBindParameter{Parameter: "$a"}, - &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - }}}}, - {"insert with cte", "with t as (select 1) insert into t1 (a,b) values (1,2)", - &tree.InsertStmt{ - CTE: []*tree.CTE{genSimpleCTETree("t", "1")}, - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with returning", "insert into t1 (a,b) values (1,2) returning a as c", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }, - ReturningClause: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - Expression: &tree.ExpressionColumn{ - Column: "a", - }, - Alias: "c", - }, - }, - }}}}, - {"insert with returning literal", "insert into t1 (a,b) values (1,2) returning 1", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }, - ReturningClause: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - Expression: genLiteralExpression("1"), - }, - }, - }}}}, - {"insert with returning *", "insert into t1 (a,b) values (1,2) returning *", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }, - ReturningClause: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }}}}, - {"insert with values upsert without target do nothing", "insert into t1 (a,b) values (1,2) on conflict do nothing", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoNothing, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with target without where do nothing", - "insert into t1 (a,b) values (1,2) on conflict (c1,c2) do nothing", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"c1", "c2"}, - }, - Type: tree.UpsertTypeDoNothing, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with target and where do nothing", - "insert into t1 (a,b) values (1,2) on conflict(c1,c2) where 1 do nothing", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"c1", "c2"}, - Where: genLiteralExpression("1"), - }, - Type: tree.UpsertTypeDoNothing, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with update column name", - "insert into t1 (a,b) values (1,2) on conflict do update set b=1", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - {Columns: []string{"b"}, - Expression: genLiteralExpression("1")}, - }, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with update multi column name", - "insert into t1 (a,b) values (1,2) on conflict do update set b=1,c=2", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - { - Columns: []string{"b"}, - Expression: genLiteralExpression("1"), - }, - { - Columns: []string{"c"}, - Expression: genLiteralExpression("2"), - }, - }, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with update column name list", - "insert into t1 (a,b) values (1,2) on conflict do update set (b,c)=(1,2)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - { - Columns: []string{"b", "c"}, - Expression: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }}, - }, - }, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with update multi column name list", - "insert into t1 (a,b) values (1,2) on conflict do update set (b,c)=(1,2), (d,e)=(3,4)", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - { - Columns: []string{"b", "c"}, - Expression: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }}, - }, - { - Columns: []string{"d", "e"}, - Expression: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("3"), - genLiteralExpression("4"), - }}, - }, - }, - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - {"insert with values upsert with update and where", - "insert into t1 (a,b) values (1,2) on conflict do update set b=1 where 1", - &tree.InsertStmt{ - Core: &tree.InsertCore{ - Table: "t1", - Columns: []string{"a", "b"}, - InsertType: tree.InsertTypeInsert, - Upsert: &tree.Upsert{ - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - {Columns: []string{"b"}, - Expression: genLiteralExpression("1")}, - }, - Where: genLiteralExpression("1"), - }, - Values: [][]tree.Expression{ - {genLiteralExpression("1"), genLiteralExpression("2")}, - }}}}, - //// select - {"select *", "select * from t1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }}}, - {"select with cte", "with t as (select 1) select * from t1", - &tree.SelectStmt{ - CTE: []*tree.CTE{genSimpleCTETree("t", "1")}, - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }}}, - {"select distinct", "select distinct * from t1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeDistinct, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }}}, - {"select with where", "select * from t1 where c1=1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "c1"}, - Operator: tree.ComparisonOperatorEqual, - Right: genLiteralExpression("1"), - }, - }, - }, - }}}, - {"select with where and", "select * from t1 where c1=1 and c2=2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "c1"}, - Operator: tree.ComparisonOperatorEqual, - Right: genLiteralExpression("1"), - }, - Operator: tree.LogicalOperatorAnd, - Right: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "c2"}, - Operator: tree.ComparisonOperatorEqual, - Right: genLiteralExpression("2"), - }, - }, - }, - }, - }}}, - {"select with where or", "select * from t1 where c1=1 or c2=2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "c1"}, - Operator: tree.ComparisonOperatorEqual, - Right: genLiteralExpression("1"), - }, - Operator: tree.LogicalOperatorOr, - Right: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "c2"}, - Operator: tree.ComparisonOperatorEqual, - Right: genLiteralExpression("2"), - }, - }, - }, - }, - }}}, - {"select with group by", "select * from t1 group by c1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - GroupBy: &tree.GroupBy{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{Column: "c1"}, - }, - }, - }, - }, - }}}, - {"select with group by and having", "select * from t1 group by c1 having 1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - GroupBy: &tree.GroupBy{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{Column: "c1"}, - }, - Having: genLiteralExpression("1"), - }, - }, - }, - }}}, - {"select with order by", "select * from t1 order by c1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - OrderBy: &tree.OrderBy{ - OrderingTerms: []*tree.OrderingTerm{ - { - Expression: &tree.ExpressionColumn{Column: "c1"}, - }, - }, - }, - }}}, - - {"select with order by all", "select * from t1 order by c1 collate nocase asc nulls first", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - OrderBy: &tree.OrderBy{ - OrderingTerms: []*tree.OrderingTerm{ - { - Expression: &tree.ExpressionCollate{ - Expression: &tree.ExpressionColumn{Column: "c1"}, - Collation: tree.CollationTypeNoCase, - }, - OrderType: tree.OrderTypeAsc, - NullOrdering: tree.NullOrderingTypeFirst, - }, - }, - }, - }}}, - {"select with limit", "select * from t1 limit 1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - Limit: &tree.Limit{Expression: genLiteralExpression("1")}, - }}}, - {"select with limit offset", "select * from t1 limit 1 offset 2", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - Limit: &tree.Limit{ - Expression: genLiteralExpression("1"), - Offset: genLiteralExpression("2"), - }, - }}}, - //// join - {"join on", "select * from t1 join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeJoin, - }, "t1", "c1", "t2", "c1")}, - {"left join on", "select * from t1 left join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeLeft, - }, "t1", "c1", "t2", "c1")}, - {"left outer join on", "select * from t1 left outer join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeLeft, - Outer: true, - }, "t1", "c1", "t2", "c1")}, - {"right join on", "select * from t1 right join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeRight, - }, "t1", "c1", "t2", "c1")}, - {"right outer join on", "select * from t1 right outer join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeRight, - Outer: true, - }, "t1", "c1", "t2", "c1")}, - {"full join on", "select * from t1 full join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeFull, - }, "t1", "c1", "t2", "c1")}, - {"full outer join on", "select * from t1 full outer join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeFull, - Outer: true, - }, "t1", "c1", "t2", "c1")}, - {"inner join on", "select * from t1 inner join t2 on t1.c1=t2.c1", - genSimpleJoinSelectTree(&tree.JoinOperator{ - JoinType: tree.JoinTypeInner, - }, "t1", "c1", "t2", "c1")}, - {"join multi", "select * from t1 join t2 on t1.c1=t2.c1 left join t3 on t1.c1=t3.c1", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "t1", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeJoin, - }, - Table: &tree.RelationTable{Name: "t2"}, - Constraint: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Table: "t1", Column: "c1"}, - Right: &tree.ExpressionColumn{Table: "t2", Column: "c1"}, - }, - }, - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeLeft, - }, - Table: &tree.RelationTable{Name: "t3"}, - Constraint: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Table: "t1", Column: "c1"}, - Right: &tree.ExpressionColumn{Table: "t3", Column: "c1"}, - }, - }, - }, - }, - }, - }, - }}}, - - //// update stmt - {"update", "update t1 set c1=1", - genSimpleUpdateTree(&tree.QualifiedTableName{TableName: "t1"}, "c1", "1")}, - {"update with table alias", "update t1 as t set c1=1", - genSimpleUpdateTree(&tree.QualifiedTableName{ - TableName: "t1", - TableAlias: "t", - }, "c1", "1")}, - {"update with multi set", "update t1 set c1=1, c2=2", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - { - Columns: []string{"c2"}, - Expression: genLiteralExpression("2"), - }, - }, - }, - }, - }, - {"update with column list set", "update t1 set (c1, c2)=(1,2)", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1", "c2"}, - Expression: &tree.ExpressionList{ - Expressions: []tree.Expression{ - genLiteralExpression("1"), - genLiteralExpression("2"), - }, - }, - }, - }, - }, - }, - }, - {"update from table", "update t1 set c1=1 from t2", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - }, - From: &tree.RelationTable{Name: "t2"}, - }, - }, - }, - {"update from join", "update t1 set c1=1 from t2 join t3 on t2.c1=t3.c1", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - }, - From: &tree.RelationJoin{ - Relation: &tree.RelationTable{Name: "t2"}, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeJoin, - }, - Table: &tree.RelationTable{Name: "t3"}, - Constraint: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Table: "t2", Column: "c1"}, - Right: &tree.ExpressionColumn{Table: "t3", Column: "c1"}, - }, - }, - }, - }, - }, - }, - }, - {"update where", "update t1 set c1=1 where c2=1", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - }, - Where: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Column: "c2"}, - Right: genLiteralExpression("1"), - }, - }, - }, - }, - {"update returning", "update t1 set c1=1 returning *", - &tree.UpdateStmt{ - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - }, - Returning: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - }, - }, - }, - {"update with cte", "with t as (select 1) update t1 set c1=1", - &tree.UpdateStmt{ - CTE: []*tree.CTE{ - genSimpleCTETree("t", "1"), - }, - Core: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{TableName: "t1"}, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"c1"}, - Expression: genLiteralExpression("1"), - }, - }, - }, - }, - }, - - //// delete - {"delete all", "delete from t1", - &tree.DeleteStmt{ - Core: &tree.DeleteCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "t1", - }, - }, - }, - }, - {"delete with where", "delete from t1 where c1='1'", - &tree.DeleteStmt{ - Core: &tree.DeleteCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "t1", - }, - Where: &tree.ExpressionBinaryComparison{ - Operator: tree.ComparisonOperatorEqual, - Left: &tree.ExpressionColumn{Column: "c1"}, - Right: genLiteralExpression("'1'"), - }, - }, - }, - }, - {"delete with returning", "delete from t1 returning *", - &tree.DeleteStmt{ - Core: &tree.DeleteCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "t1", - }, - Returning: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - }, - }, - }, - {"delete with cte", "with t as (select 1) delete from t1", - &tree.DeleteStmt{ - CTE: []*tree.CTE{ - genSimpleCTETree("t", "1"), - }, - Core: &tree.DeleteCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "t1", - }, - }, - }, - }, - //// identifier quotes, `"` and `[]` and "`" - {"table name with double quote", `select * from "t1"`, - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }, - }, - }, - {"table name alias with double quote", `select * from "t1" as "t"`, - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: columnStar, - From: &tree.RelationTable{ - Name: "t1", - Alias: "t", - }, - }, - }, - }, - }, - }, - // we cannot actually test this without re-architecting the whole test, - // so will comment out for now - // { - // name: "foreign function call", - // input: `select call['a', $b]('c');`, - // expect: &tree.SelectStmt{ - // Stmt: &tree.SelectCore{ - // SimpleSelects: []*tree.SimpleSelect{ - // { - // SelectType: tree.SelectTypeAll, - // Columns: []tree.ResultColumn{ - // &tree.ResultColumnExpression{ - // Expression: &tree.ExpressionFunction{ - // Function: "call", - // ContextualParams: []tree.Expression{ - // genLiteralExpression("'a'"), - // &tree.ExpressionBindParameter{Parameter: "$b"}, - // }, - // Inputs: []tree.Expression{ - // genLiteralExpression("'c'"), - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - {"collation name with back tick quote", "select `col1` COLLATE `nocase` from `t1`; ", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionCollate{ - Expression: &tree.ExpressionColumn{ - Table: "", - Column: "col1", - }, - Collation: tree.CollationTypeNoCase, - }, - }, - }, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }, - }, - }, - {"function name with back tick quote", "select `abs`(1)", - genSimpleFunctionSelectTree("abs", genLiteralExpression("1"))}, - - //// type cast - {"type cast", - "select 1::int as x, @caller::text, t1.c1::text, (t1.c2::int * 3)::int, " + - "(t1.c3 isnull)::int, abs(2)::int from t1;", - &tree.SelectStmt{ - Stmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionNumericLiteral{ - Value: 1, - TypeCast: types.IntType, - }, - Alias: "x", - }, - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionBindParameter{ - Parameter: "@caller", - TypeCast: types.TextType, - }, - }, - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionColumn{ - Table: "t1", - Column: "c1", - TypeCast: types.TextType, - }, - }, - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionArithmetic{ - Wrapped: true, - TypeCast: types.IntType, - Left: &tree.ExpressionColumn{ - Table: "t1", - Column: "c2", - TypeCast: types.IntType, - }, - Operator: tree.ArithmeticOperatorMultiply, - Right: genLiteralExpression("3"), - }, - }, - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Table: "t1", - Column: "c3", - }, - Right: genLiteralExpression("NULL"), - Wrapped: true, - TypeCast: types.IntType, - }, - }, - &tree.ResultColumnExpression{ - Expression: &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{genLiteralExpression("2")}, - Distinct: false, - TypeCast: types.IntType, - }, - }, - }, - From: &tree.RelationTable{ - Name: "t1", - }, - }, - }, - }, - }, - }, - } - - // Replace multiple spaces with a single space - re := regexp.MustCompile(`\s+`) - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - defer func() { - tt.expect = nil - }() - - stmts, err := ParseMany(tt.input) - require.NoError(t, err) - stmt := stmts[0] - - if !deepCompare(stmt, tt.expect) { - t.Errorf("ParseRawSQL() got %+v, want %+v", stmt, tt.expect) - } - - sql, err := tree.SafeToSQL(stmt) - if err != nil { - t.Errorf("ParseRawSQL() got %s", err) - } - - if *traceMode { - fmt.Println("SQL from AST: ", sql) - } - - singleSpaceSql := re.ReplaceAllString(sql, " ") - t.Logf("%s \n=> %s\n", tt.input, singleSpaceSql) - - if !(strings.Contains(tt.input, "isnull") || strings.Contains(tt.input, "notnull")) { - // assert original sql and sql from ast are equal, WITHOUT format - assert.True(t, - strings.EqualFold(unFormatSql(sql), unFormatSql(tt.input)), - "ParseRawSQL() got %s, origin %s", sql, tt.input) - } - - err = postgres.CheckSyntaxReplaceDollar(sql) - assert.NoErrorf(t, err, "postgres syntax check failed: %s", err) - - checkNodesAreSet(t, stmt) - }) - } -} - -// unFormatSql remove unnecessary spaces, quotes, etc. -func unFormatSql(sql string) string { - sql = strings.ReplaceAll(sql, " ", "") - sql = strings.ReplaceAll(sql, ";", "") - //// double quotes are for table/column names, astTree.ToSQL() will add them - sql = strings.ReplaceAll(sql, `"`, "") - // those markers are not supported by astTree.ToSQL(), but they are supported by sqlite(from original input) - sql = strings.ReplaceAll(sql, `[`, "") - sql = strings.ReplaceAll(sql, `]`, "") - sql = strings.ReplaceAll(sql, "`", "") - - return sql -} - -func TestParseRawSQL_syntax_invalid(t *testing.T) { - tests := []struct { - name string - input string - causeSymbol string - }{ - // literal value - {"blob", "select x'01'", "x'01'"}, - - // bind parameter - {"expr bind parameter ?", "select ?", "?"}, - {"expr bind parameter ?1", "SELECT ?1", "?"}, - {"expr bind parameter :a", "select :a", ":"}, - - // common table stmt - {"cte recursive", "with recursive t1(c1,c2) as (select 1) select * from t1", "recursive"}, - // common table expression - {"cte not", "with t1(c1,c2) as (select 1) not select * from t1", "not"}, - {"cte materialized", "with t1(c1,c2) as (select 1) materialized select * from t1", "materialized"}, - - // table or subquery - {"table or subquery indexed", "select * from t1 indexed by index_a", "indexed"}, - {"table or subquery not indexed", "select * from t1 not indexed", "not"}, - {"table or subquery nest tos", "select * from (t1, t2)", ","}, - - // expr - {"expr names", "select schema.table.column", "."}, // no schema - {"expr cast", "select cast(true as aaa)", "cast"}, - {"expr function with over", "select abs(1) over (partition by 1)", "over"}, - //{"expr raise", "select raise(fail, 'dsd')", "raise"}, - - // insert - {"insert or abort", "insert or abort into t1 values (1)", "abort"}, - {"insert or fail", "insert or fail into t1 values (1)", "fail"}, - {"insert or ignore", "insert or ignore into t1 values (1)", "ignore"}, - {"insert or rollback", "insert or rollback into t1 values (1)", "rollback"}, - {"insert schema_name", "insert or replace into schema.t1 values (1)", "."}, - {"insert into with select", "insert into t1 as tt with t1 as (select 1) select * from t2", "with"}, - {"insert into select", "insert into t1 as tt select * from t2", "select"}, - {"insert into default values", "insert into t1 default values", "default"}, - //wrong indexed_column syntax - //"insert into t1 (a,b) values (1,2) on conflict (c1 collate collate_name asc) do nothing", - - // select - {"select all", "select all c1 from t1", "c1"}, - {"select with window", "select * from t1 window w1 as (partition by 1)", "window"}, - {"select with not supported null ordering", "select * from t1 order by c1 nulls firstss", "firstss"}, - {"select values", "values (1)", "values"}, - {"select values with cte", "with t as (select 1) values (1)", "values"}, - {"select with compound operator and values", "select * from t1 union values (1)", "values"}, - - // function - {"expr function with filter", "select f(1) filter (where 1)", "filter"}, - - // join - {"cross join", "select * from t3 cross join t4", "cross"}, - {"join using", "select * from t3 join t4 using (c1)", "using"}, - {"join without condition", "select * from t3 join t4", ""}, - {"comma cartesian join 1", "select * from t3, t4", ","}, - - // other statement - {"explain", "explain select * from t1", "explain"}, - {"explain query plan", "explain query plan select * from t1", "explain"}, - {"create table", "create table t1 (c1 int)", "create"}, - {"drop table", "drop table t1", "drop"}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - //eh := NewErrorHandler(1) - //el := newSqliteErrorListener(eh) - res, err := ParseMany(tt.input) - // the returned error should be nil, since the error listener - // should have caught the error - assert.Errorf(t, err, "Parser should complain abould invalid syntax") - - for _, r := range res { - checkNodesAreSet(t, r) - } - - //if el.symbol != tt.causeSymbol { - // t.Errorf("ParseRawSQL() expected cause symbol: %s, got: %s", tt.causeSymbol, el.symbol) - //} - }) - } -} - -func TestParseRawSQL_semantic_invalid(t *testing.T) { - // TODO: we probably should move all semantic checks to analysis phase - // but some semantic checks need catalog, some don't, like these - // let's keep it here for now - tests := []struct { - name string - input string - reason string - }{ - // type cast - {"type cast not supported type", "select 1::random", `unknown type`}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - res, err := ParseMany(tt.input) - require.NotNil(t, err) - - assert.Contains(t, err.Error(), tt.reason) - - for _, r := range res { - checkNodesAreSet(t, r) - } - }) - } -} - -// checkNodesAreSet checks that all nodes have been set. -// it ensures that we have called Set on all nodes in the AST. -func checkNodesAreSet(t *testing.T, node tree.AstNode) { - l := tree.ImplementedListener{ - FuncEnterCTE: func(p0 *tree.CTE) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterCompoundOperator: func(p0 *tree.CompoundOperator) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterConflictTarget: func(p0 *tree.ConflictTarget) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterDeleteStmt: func(p0 *tree.DeleteStmt) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterDeleteCore: func(p0 *tree.DeleteCore) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionArithmetic: func(p0 *tree.ExpressionArithmetic) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionBetween: func(p0 *tree.ExpressionBetween) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionBinaryComparison: func(p0 *tree.ExpressionBinaryComparison) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionBindParameter: func(p0 *tree.ExpressionBindParameter) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionCase: func(p0 *tree.ExpressionCase) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionCollate: func(p0 *tree.ExpressionCollate) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionColumn: func(p0 *tree.ExpressionColumn) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionFunction: func(p0 *tree.ExpressionFunction) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionIs: func(p0 *tree.ExpressionIs) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionList: func(p0 *tree.ExpressionList) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionTextLiteral: func(p0 *tree.ExpressionTextLiteral) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionNumericLiteral: func(p0 *tree.ExpressionNumericLiteral) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionBooleanLiteral: func(p0 *tree.ExpressionBooleanLiteral) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionNullLiteral: func(p0 *tree.ExpressionNullLiteral) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionBlobLiteral: func(p0 *tree.ExpressionBlobLiteral) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionSelect: func(p0 *tree.ExpressionSelect) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionStringCompare: func(p0 *tree.ExpressionStringCompare) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterExpressionUnary: func(p0 *tree.ExpressionUnary) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterGroupBy: func(p0 *tree.GroupBy) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterInsertStmt: func(p0 *tree.InsertStmt) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterInsertCore: func(p0 *tree.InsertCore) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterJoinOperator: func(p0 *tree.JoinOperator) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterJoinPredicate: func(p0 *tree.JoinPredicate) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterLimit: func(p0 *tree.Limit) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterOrderBy: func(p0 *tree.OrderBy) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterOrderingTerm: func(p0 *tree.OrderingTerm) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterQualifiedTableName: func(p0 *tree.QualifiedTableName) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterRelationFunction: func(p0 *tree.RelationFunction) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterRelationJoin: func(p0 *tree.RelationJoin) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterRelationSubquery: func(p0 *tree.RelationSubquery) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterRelationTable: func(p0 *tree.RelationTable) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterResultColumnExpression: func(p0 *tree.ResultColumnExpression) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterResultColumnStar: func(p0 *tree.ResultColumnStar) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterResultColumnTable: func(p0 *tree.ResultColumnTable) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterReturningClause: func(p0 *tree.ReturningClause) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterReturningClauseColumn: func(p0 *tree.ReturningClauseColumn) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterSelectStmt: func(p0 *tree.SelectStmt) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterSimpleSelect: func(p0 *tree.SimpleSelect) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterSelectCore: func(p0 *tree.SelectCore) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterUpdateStmt: func(p0 *tree.UpdateStmt) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterUpdateSetClause: func(p0 *tree.UpdateSetClause) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterUpdateCore: func(p0 *tree.UpdateCore) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - FuncEnterUpsert: func(p0 *tree.Upsert) error { - if !p0.Node.IsSet { - return fmt.Errorf("node not set for AST node %T", p0) - } - - return nil - }, - } - - err := node.Walk(&l) - require.NoError(t, err) -} diff --git a/parse/sql/sqlanalyzer/analyzer.go b/parse/sql/sqlanalyzer/analyzer.go deleted file mode 100644 index 705a109ec..000000000 --- a/parse/sql/sqlanalyzer/analyzer.go +++ /dev/null @@ -1,169 +0,0 @@ -package sqlanalyzer - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/core/types" - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/clean" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/join" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/order" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/parameters" - schemaWalker "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/schema" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// WalkerRecoverer is a wrapper around a statement that implements the AstWalker -// interface, it catches panics and returns them as errors -type WalkerRecoverer struct { - inner tree.AstWalker -} - -func NewWalkerRecoverer(a tree.AstWalker) *WalkerRecoverer { - return &WalkerRecoverer{a} -} - -func (a *WalkerRecoverer) Walk(walker tree.AstListener) (err error) { - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("panic while walking statement: %v", r) - } - }() - - return a.inner.Walk(walker) -} - -// ApplyRules analyzes the given statement and returns the transformed statement. -// It parses it, and then traverses the AST with the given flags. -// It will alter the statement to make it conform to the given flags, or return an error if it cannot. -// All tables will target the pgSchemaName schema. -func ApplyRules(stmt string, flags VerifyFlag, schema *types.Schema, pgSchemaName string, errorListener *parseTypes.ErrorListener) (*AnalyzedStatement, error) { - parsed, err := sqlparser.ParseWithErrorListener(stmt, errorListener) - if err != nil { - return nil, fmt.Errorf("error parsing statement: %w", err) - } - if len(parsed) != 1 { - return nil, fmt.Errorf("expected 1 statement, but found %d", len(parsed)) - } - - walker := &WalkerRecoverer{parsed[0]} - - clnr := clean.NewStatementCleaner(schema, errorListener) - err = walker.Walk(clnr) - if err != nil { - return nil, fmt.Errorf("error cleaning statement: %w", err) - } - - schemaWalker := schemaWalker.NewSchemaWalker(pgSchemaName) - err = walker.Walk(schemaWalker) - if err != nil { - return nil, fmt.Errorf("error applying schema rules: %w", err) - } - - if flags&NoCartesianProduct != 0 { - err := walker.Walk(join.NewJoinWalker(errorListener)) - if err != nil { - return nil, fmt.Errorf("error applying join rules: %w", err) - } - } - - if flags&GuaranteedOrder != 0 { - err := walker.Walk(order.NewOrderWalker(schema, errorListener)) - if err != nil { - return nil, fmt.Errorf("error enforcing guaranteed order: %w", err) - } - } - - orderedParams := make([]string, 0) - if flags&ReplaceNamedParameters != 0 { - paramVisitor := parameters.NewParametersWalker() - err := walker.Walk(paramVisitor) - if err != nil { - return nil, fmt.Errorf("error replacing named parameters: %w", err) - } - orderedParams = paramVisitor.OrderedParameters - } - - mutative, err := IsMutative(parsed[0]) - if err != nil { - return nil, fmt.Errorf("error determining mutativity: %w", err) - } - - generated, err := tree.SafeToSQL(parsed[0]) - if err != nil { - return nil, fmt.Errorf("error generating SQL: %w", err) - } - - return &AnalyzedStatement{ - Statement: generated, - Mutative: mutative, - HasTableRefs: schemaWalker.SetCount > 0, - ParameterOrder: orderedParams, - }, nil -} - -// CleanAST cleans and makes the given statement deterministic. -func CleanAST(ast tree.AstWalker, schema *types.Schema, pgSchemaName string, errorListener parseTypes.NativeErrorListener) (err error) { - accept := &WalkerRecoverer{ast} - - clnr := clean.NewStatementCleaner(schema, errorListener) - err = accept.Walk(clnr) - if err != nil { - return fmt.Errorf("error cleaning statement: %w", err) - } - - sw := schemaWalker.NewSchemaWalker(pgSchemaName) - err = accept.Walk(sw) - if err != nil { - return fmt.Errorf("error applying schema rules: %w", err) - } - - err = accept.Walk(join.NewJoinWalker(errorListener)) - if err != nil { - return fmt.Errorf("error applying join rules: %w", err) - } - - err = accept.Walk(order.NewOrderWalker(schema, errorListener)) - if err != nil { - return fmt.Errorf("error enforcing guaranteed order: %w", err) - } - - return nil -} - -type VerifyFlag uint8 - -const ( - // NoCartesianProduct prevents cartesian products from being generated - NoCartesianProduct VerifyFlag = 1 << iota - // GuaranteedOrder provides a guarantee of deterministic ordering of the results (even if it is not explicitly specified in the query) - GuaranteedOrder - // ReplaceNamedParameters replaces named parameters with numbered parameters - ReplaceNamedParameters -) - -const ( - AllRules = NoCartesianProduct | GuaranteedOrder | ReplaceNamedParameters -) - -// AnalyzedStatement is a statement that has been analyzed by the analyzer -// As we progressively add more types of analysis (e.g. query pricing), we will add more fields to this struct -type AnalyzedStatement struct { - // Statement is the rewritten SQL statement, with the correct rules applied - Statement string - // Mutative indicates if the statement mutates state. - // If true, then the statement cannot run in a read-only transaction. - Mutative bool - // HasTableRefs indicates if the statement included tables IFF the - // NamedParametersVisitor was run on the AST after parsing. These tables - // would have had a schema prefixed by the walker. This can indicate if the - // statement alone is not likely to provide type (OID) information by - // preparing the statement with the database backend. - HasTableRefs bool - // ParameterOrder is a list of the parameters in the order they appear in the statement. - // This is set if the ReplaceNamedParameters flag is set. - // For example, if the statement is "SELECT * FROM table WHERE id = $id AND name = @caller", - // then the parameter order would be ["$id", "@caller"] - ParameterOrder []string -} diff --git a/parse/sql/sqlanalyzer/analyzer_test.go b/parse/sql/sqlanalyzer/analyzer_test.go deleted file mode 100644 index 62ddd9483..000000000 --- a/parse/sql/sqlanalyzer/analyzer_test.go +++ /dev/null @@ -1,210 +0,0 @@ -package sqlanalyzer_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/core/types/testdata" - "github.com/kwilteam/kwil-db/parse/sql/postgres" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_Analyze(t *testing.T) { - type testCase struct { - name string - stmt string - want string - tables []*types.Table - wantErr bool - } - - tests := []testCase{ - { - name: "simple select", - stmt: "SELECT * FROM users", - want: `SELECT * FROM "dbid"."users" ORDER BY "users"."id";`, - tables: []*types.Table{ - tblUsers, - }, - }, - { - name: "select with joins and subqueries", - stmt: `SELECT p.id, p.title - FROM posts AS p - INNER JOIN followers AS f ON p.user_id = f.user_id - INNER JOIN users AS u ON u.id = f.user_id - WHERE f.follower_id = ( - SELECT id FROM users WHERE username = $username - ) - ORDER BY p.post_date DESC NULLS LAST - LIMIT 20 OFFSET $offset;`, - want: `SELECT "p"."id", "p"."title" - FROM "dbid"."posts" AS "p" - INNER JOIN "dbid"."followers" AS "f" ON "p"."user_id" = "f"."user_id" - INNER JOIN "dbid"."users" AS "u" ON "u"."id" = "f"."user_id" - WHERE "f"."follower_id" = ( - SELECT "id" FROM "dbid"."users" WHERE "username" = $1 ORDER BY "users"."id" - ) - ORDER BY "p"."post_date" DESC NULLS LAST, - "f"."follower_id" , "f"."user_id" , "p"."id" , "u"."id" - LIMIT 20 OFFSET $2;`, - tables: []*types.Table{ - tblUsers, - tblPosts, - tblFollowers, - }, - }, - { - name: "table joined on self", - stmt: `SELECT u1.id, u1.name, u2.name - FROM users AS u1 - INNER JOIN users AS u2 ON u1.id = u2.id`, - want: `SELECT "u1"."id", "u1"."name", "u2"."name" - FROM "dbid"."users" AS "u1" - INNER JOIN "dbid"."users" AS "u2" ON "u1"."id" = "u2"."id" - ORDER BY "u1"."id" , "u2"."id";`, - tables: []*types.Table{ - tblUsers, - }, - }, - { - name: "common table expression", - stmt: `WITH - users_aged_20 AS ( - SELECT id, username FROM users WHERE age = 20 - ) - SELECT * FROM users_aged_20`, - want: `WITH - "users_aged_20" AS ( - SELECT "id", "username" FROM "dbid"."users" WHERE "age" = 20 ORDER BY "users"."id" - ) - SELECT * FROM "users_aged_20" ORDER BY "users_aged_20"."id" , "users_aged_20"."username";`, - tables: []*types.Table{ - tblUsers, - }, - }, - { - name: "basic insert", - stmt: `INSERT INTO users (id, username, age) VALUES (1, 'user1', 20)`, - want: `INSERT INTO "dbid"."users" ("id", "username", "age") VALUES (1, 'user1', 20);`, - tables: []*types.Table{ - tblUsers, - }, - }, - { - name: "select with count", - stmt: `SELECT COUNT(*) FROM users`, - want: `SELECT count(*) FROM "dbid"."users";`, - tables: []*types.Table{ - tblUsers, - }, - }, - { - name: "select with aggregate and group by", - stmt: `SELECT sum(age) FROM users GROUP BY username;`, - want: `SELECT sum("age") FROM "dbid"."users" GROUP BY "username" ORDER BY "username";`, - tables: []*types.Table{ - tblUsers, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - errList := parseTypes.NewErrorListener() - got, err := sqlanalyzer.ApplyRules(tt.stmt, sqlanalyzer.AllRules, &types.Schema{ - Tables: tt.tables, - }, "dbid", errList) - require.NoError(t, err) - if (errList.Err() != nil) != tt.wantErr { - t.Errorf("ApplyRules() error = %v, wantErr %v", errList.Err(), tt.wantErr) - return - } - - assert.Equal(t, removeSpaces(tt.want), removeSpaces(got.Statement)) - - err = postgres.CheckSyntaxReplaceDollar(got.Statement) - assert.NoErrorf(t, err, "postgres syntax check failed: %s", err) - }) - } -} - -var ( - tblUsers = testdata.TableUsers - - tblPosts = &types.Table{ - Name: "posts", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "user_id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - }, - }, - { - Name: "title", - Type: types.TextType, - }, - { - Name: "post_date", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - }, - }, - }, - } - - tblFollowers = &types.Table{ - Name: "followers", - Columns: []*types.Column{ - { - Name: "user_id", - Type: types.IntType, - }, - { - Name: "follower_id", - Type: types.IntType, - }, - }, - Indexes: []*types.Index{ - { - Name: "primary_key", - Columns: []string{ - "user_id", - "follower_id", - }, - Type: types.PRIMARY, - }, - }, - } -) - -// removeSpaces removes all spaces from a string. -// this is useful for comparing strings, where one is generated -func removeSpaces(s string) string { - var result []rune - for _, ch := range s { - if ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' { - result = append(result, ch) - } - } - return string(result) -} diff --git a/parse/sql/sqlanalyzer/clean/clean.go b/parse/sql/sqlanalyzer/clean/clean.go deleted file mode 100644 index c279d31eb..000000000 --- a/parse/sql/sqlanalyzer/clean/clean.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Package clean cleans SQL queries. - -This includes making identifiers lower case. - -The walker in this package implements all the tree.Walker methods, even if it -doesn't do anything. This is to ensure that if we need to add more cleaning / validation -rules, we know that we've covered all the nodes. - -For example, EnterDeleteStmt does nothing, but if we later set a limit on the amount of -CTEs allowed, then we would add it there. -*/ -package clean - -import ( - "fmt" - "regexp" - "strings" - - "github.com/kwilteam/kwil-db/core/types/validation" -) - -// checks that the string only contains alphanumeric characters and underscores -var identifierRegexp = regexp.MustCompile(`^[a-z][a-z0-9_]*$`) - -// cleanIdentifier checks that the identifier is a valid identifier and returns -// it in lower case -func cleanIdentifier(identifier string) (string, error) { - res := strings.ToLower(identifier) - - if !identifierRegexp.MatchString(res) { - return "", wrapErr(ErrInvalidIdentifier, fmt.Errorf(`identifier must start with letter and only contain alphanumeric characters or underscores, received: "%s"`, identifier)) - } - - if validation.IsKeyword(res) { - return "", wrapErr(ErrInvalidIdentifier, fmt.Errorf(`identifier must not be a keyword, received: "%s"`, identifier)) - } - - return res, nil -} - -// cleanIdentifiers checks several identifiers and returns them in lower case -func cleanIdentifiers(identifiers []string) ([]string, error) { - res := make([]string, len(identifiers)) - - for i, identifier := range identifiers { - var err error - res[i], err = cleanIdentifier(identifier) - if err != nil { - return nil, err - } - } - - return res, nil -} diff --git a/parse/sql/sqlanalyzer/clean/errors.go b/parse/sql/sqlanalyzer/clean/errors.go deleted file mode 100644 index 2afe0df88..000000000 --- a/parse/sql/sqlanalyzer/clean/errors.go +++ /dev/null @@ -1,35 +0,0 @@ -package clean - -import ( - "errors" - "fmt" -) - -var ( - ErrInvalidIdentifier = errors.New("invalid identifier") - ErrInvalidLiteral = errors.New("invalid literal") - ErrInvalidBindParameter = errors.New("invalid bind parameter") - ErrInvalidCollation = errors.New("invalid collation") - ErrInvalidInsertType = errors.New("invalid insert type") - ErrInvalidUpdateType = errors.New("invalid update type") - ErrInvalidSelectType = errors.New("invalid select type") - ErrInvalidJoinOperator = errors.New("invalid join operator") - ErrInvalidOrderType = errors.New("invalid order type") - ErrInvalidNullOrderType = errors.New("invalid null order type") - ErrInvalidReturningClause = errors.New("invalid returning clause") - ErrInvalidCompoundOperator = errors.New("invalid compound operator") - ErrInvalidUpsertType = errors.New("invalid upsert type") - ErrInvalidUnaryOperator = errors.New("invalid unary operator") - ErrInvalidBinaryOperator = errors.New("invalid binary operator") - ErrInvalidStringComparisonOperator = errors.New("invalid string comparison operator") - ErrInvalidArithmeticOperator = errors.New("invalid arithmetic operator") - ErrTableNotFound = errors.New("table not found") -) - -// wrapErr wraps an error with another, if the second error is not nil -func wrapErr(err error, err2 error) error { - if err2 == nil { - return nil - } - return fmt.Errorf("%w: %s", err, err2) -} diff --git a/parse/sql/sqlanalyzer/clean/walker.go b/parse/sql/sqlanalyzer/clean/walker.go deleted file mode 100644 index 05133a205..000000000 --- a/parse/sql/sqlanalyzer/clean/walker.go +++ /dev/null @@ -1,452 +0,0 @@ -package clean - -import ( - "errors" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -// TODO: the statement cleaner should also check for table / column existence -func NewStatementCleaner(schema *types.Schema, errorListener parseTypes.NativeErrorListener) *StatementCleaner { - return &StatementCleaner{ - AstListener: tree.NewBaseListener(), - schema: schema, - errs: errorListener, - } -} - -var _ tree.AstListener = &StatementCleaner{} - -type StatementCleaner struct { - tree.AstListener - schema *types.Schema - errs parseTypes.NativeErrorListener -} - -// err is a helper function to send errors to the error listener. -// It will ignore nil errors. If err1 is not nil but err2 is, it will -// not send an error. It is meant to be used to wrap errors, with the -// first error being the type of error, and the second error giving -// more information -func (s *StatementCleaner) err(err1, err2 error, getNode getNoder) { - if err1 == nil { - panic("internal api misuse: err1 cannot be nil") - } - - if err2 == nil { - return - } - - s.errs.NodeErr(getNode.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.Join(err1, err2)) -} - -type getNoder interface { - GetNode() *parseTypes.Node -} - -// EnterConflictTarget checks that the indexed column names are valid identifiers -func (s *StatementCleaner) EnterConflictTarget(node *tree.ConflictTarget) (err error) { - node.IndexedColumns, err = cleanIdentifiers(node.IndexedColumns) - s.err(ErrInvalidIdentifier, err, node) - return nil -} - -// EnterCTE checks that the table name and column names are valid identifiers -func (s *StatementCleaner) EnterCTE(node *tree.CTE) (err error) { - node.Table, err = cleanIdentifier(node.Table) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - node.Columns, err = cleanIdentifiers(node.Columns) - s.err(ErrInvalidIdentifier, err, node) - return nil -} - -// EnterDelete does nothing -func (s *StatementCleaner) EnterDeleteStmt(node *tree.DeleteStmt) (err error) { - return nil -} - -// EnterDeleteStmt does nothing -func (s *StatementCleaner) EnterDeleteCore(node *tree.DeleteCore) (err error) { - return nil -} - -// EnterExpressionBindParameter checks that the bind parameter is a valid bind parameter -func (s *StatementCleaner) EnterExpressionBindParameter(node *tree.ExpressionBindParameter) (err error) { - if !strings.HasPrefix(node.Parameter, "$") && !strings.HasPrefix(node.Parameter, "@") { - s.err(ErrInvalidBindParameter, errors.New("bind parameter must start with $ or @"), node) - return nil - } - - node.Parameter = strings.ToLower(node.Parameter) - return nil -} - -// EnterExpressionColumn checks that the table and column names are valid identifiers -func (s *StatementCleaner) EnterExpressionColumn(node *tree.ExpressionColumn) (err error) { - if node.Table != "" { - node.Table, err = cleanIdentifier(node.Table) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - node.Column, err = cleanIdentifier(node.Column) - s.err(ErrInvalidIdentifier, err, node) - return nil -} - -// EnterExpressionUnary checks that the operator is a valid operator -func (s *StatementCleaner) EnterExpressionUnary(node *tree.ExpressionUnary) (err error) { - s.err(ErrInvalidUnaryOperator, node.Operator.Valid(), node) - return nil -} - -// EnterExpressionBinary checks that the operator is a valid operator -func (s *StatementCleaner) EnterExpressionBinaryComparison(node *tree.ExpressionBinaryComparison) (err error) { - s.err(ErrInvalidBinaryOperator, node.Operator.Valid(), node) - return nil -} - -// EnterExpressionFunction lowers the function name and checks that it is a valid function -func (s *StatementCleaner) EnterExpressionFunction(node *tree.ExpressionFunction) (err error) { - node.Function = strings.ToLower(node.Function) - // this can either be a procedure or a function call. - // it cannot be a foreign procedure, as those are parsed differently - - _, ok := metadata.Functions[node.Function] - if !ok { - // check if it's a procedure - if _, ok := s.schema.FindProcedure(node.Function); ok { - return nil - } - - _, _, err := util.FindProcOrForeign(s.schema, node.Function) - if err != nil { - return err - } - } - - return nil -} - -// EnterExpressionList does nothing -func (s *StatementCleaner) EnterExpressionList(node *tree.ExpressionList) (err error) { - return nil -} - -// EnterExpressionCollate checks that the collation is a valid collation -func (s *StatementCleaner) EnterExpressionCollate(node *tree.ExpressionCollate) (err error) { - if node.Collation.Empty() { - s.err(ErrInvalidCollation, errors.New("collation cannot be empty"), node) - return nil - } - - err = node.Collation.Valid() - if err != nil { - s.err(ErrInvalidCollation, err, node) - return nil - } - - return nil -} - -// EnterExpressionStringCompare checks that the operator is a valid operator -func (s *StatementCleaner) EnterExpressionStringCompare(node *tree.ExpressionStringCompare) (err error) { - s.err(ErrInvalidStringComparisonOperator, node.Operator.Valid(), node) - return nil -} - -// EnterExpressionIs does nothing -func (s *StatementCleaner) EnterExpressionIs(node *tree.ExpressionIs) (err error) { - return nil -} - -// EnterExpressionBetween does nothing -func (s *StatementCleaner) EnterExpressionBetween(node *tree.ExpressionBetween) (err error) { - return nil -} - -// EnterExpressionExists checks that you can only negate EXISTS -func (s *StatementCleaner) EnterExpressionSelect(node *tree.ExpressionSelect) (err error) { - if node.IsNot && !node.IsExists { - s.err(ErrInvalidIdentifier, errors.New("cannot negate non-EXISTS select expression"), node) - return nil - } - - return nil -} - -// EnterExpressionCase does nothing -func (s *StatementCleaner) EnterExpressionCase(node *tree.ExpressionCase) (err error) { - return nil -} - -// EnterExpressionArithmetic checks the validity of the operator -func (s *StatementCleaner) EnterExpressionArithmetic(node *tree.ExpressionArithmetic) (err error) { - s.err(ErrInvalidArithmeticOperator, node.Operator.Valid(), node) - return nil -} - -// EnterGroupBy does nothing -func (s *StatementCleaner) EnterGroupBy(node *tree.GroupBy) (err error) { - return nil -} - -// EnterInsert does nothing -func (s *StatementCleaner) EnterInsertStmt(node *tree.InsertStmt) (err error) { - return nil -} - -// EnterInsertStmt cleans the insert type, table, table alias, and columns -func (s *StatementCleaner) EnterInsertCore(node *tree.InsertCore) (err error) { - err = node.InsertType.Valid() - if err != nil { - s.err(ErrInvalidInsertType, err, node) - return nil - } - - node.Table, err = cleanIdentifier(node.Table) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - - _, found := s.schema.FindTable(node.Table) - if !found { - s.err(ErrTableNotFound, ErrTableNotFound, node) - return nil - } - - if node.TableAlias != "" { - node.TableAlias, err = cleanIdentifier(node.TableAlias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - node.Columns, err = cleanIdentifiers(node.Columns) - s.err(ErrInvalidIdentifier, err, node) - return nil -} - -func (s *StatementCleaner) EnterRelationFunction(node *tree.RelationFunction) (err error) { - // check the alias is a valid identifier - if node.Alias != "" { - node.Alias, err = cleanIdentifier(node.Alias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - return nil -} - -// EnterJoinConstraint does nothing -func (s *StatementCleaner) EnterJoinPredicate(node *tree.JoinPredicate) (err error) { - return nil -} - -// EnterJoinOperator validates the join operator -func (s *StatementCleaner) EnterJoinOperator(node *tree.JoinOperator) (err error) { - s.err(ErrInvalidJoinOperator, node.Valid(), node) - return nil -} - -// EnterLimit does nothing -func (s *StatementCleaner) EnterLimit(node *tree.Limit) (err error) { - return nil -} - -// EnterOrderBy does nothing -func (s *StatementCleaner) EnterOrderBy(node *tree.OrderBy) (err error) { - return nil -} - -// EnterOrderingTerm validates the order type and null order type -func (s *StatementCleaner) EnterOrderingTerm(node *tree.OrderingTerm) (err error) { - // ordertype and nullorderingtype are both valid as empty, so we don't need to check for that - if err = node.OrderType.Valid(); err != nil { - s.err(ErrInvalidOrderType, err, node) - return nil - } - - if err = node.NullOrdering.Valid(); err != nil { - s.err(ErrInvalidNullOrderType, err, node) - return nil - } - - return nil -} - -// EnterQualifiedTableName checks the table name and alias and indexed by column -func (s *StatementCleaner) EnterQualifiedTableName(node *tree.QualifiedTableName) (err error) { - node.TableName, err = cleanIdentifier(node.TableName) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - - // we do not check for table existence here since it can reference a cte - - if node.TableAlias != "" { - node.TableAlias, err = cleanIdentifier(node.TableAlias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - return nil -} - -// EnterResultColumnStar does nothing -func (s *StatementCleaner) EnterResultColumnStar(node *tree.ResultColumnStar) (err error) { - return nil -} - -// EnterResultColumnExpression checks the alias if it exists -func (s *StatementCleaner) EnterResultColumnExpression(node *tree.ResultColumnExpression) (err error) { - if node.Alias != "" { - node.Alias, err = cleanIdentifier(node.Alias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - return nil -} - -// EnterResultColumnTable checks the table name -func (s *StatementCleaner) EnterResultColumnTable(node *tree.ResultColumnTable) (err error) { - node.TableName, err = cleanIdentifier(node.TableName) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - - return nil -} - -// EnterReturningClause does nothing -func (s *StatementCleaner) EnterReturningClause(node *tree.ReturningClause) (err error) { - return nil -} - -// EnterReturningClauseColumn checks that either all is selected, or that an expression is used. An alias can -// only be used if an expression is used. -func (s *StatementCleaner) EnterReturningClauseColumn(node *tree.ReturningClauseColumn) (err error) { - if node.All && node.Expression != nil { - s.err(ErrInvalidReturningClause, errors.New("all and expression cannot be set at the same time"), node) - return nil - } - - if node.Alias != "" && node.Expression == nil { - s.err(ErrInvalidReturningClause, errors.New("alias cannot be set without an expression"), node) - return nil - } - - return nil -} - -// EnterSelect does nothing -func (s *StatementCleaner) EnterSelectStmt(node *tree.SelectStmt) (err error) { - return nil -} - -// EnterSelectCore validates the select type -func (s *StatementCleaner) EnterSimpleSelect(node *tree.SimpleSelect) (err error) { - s.err(ErrInvalidSelectType, node.SelectType.Valid(), node) - return nil -} - -// EnterSelectStmt checks that, for each SelectCore besides the last, a compound operator is provided -func (s *StatementCleaner) EnterSelectCore(node *tree.SelectCore) (err error) { - for _, core := range node.SimpleSelects[1:] { - if core.Compound == nil { - s.err(ErrInvalidCompoundOperator, errors.New("compound operator must be provided for all SelectCores except the first"), node) - return nil - } - } - - return nil -} - -// EnterCompoundOperator validates the compound operator -func (s *StatementCleaner) EnterCompoundOperator(node *tree.CompoundOperator) (err error) { - s.err(ErrInvalidCompoundOperator, node.Operator.Valid(), node) - return nil -} - -// EnterRelationTable checks the table name and alias -func (s *StatementCleaner) EnterRelationTable(node *tree.RelationTable) (err error) { - node.Name, err = cleanIdentifier(node.Name) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - - // we do not check for table existence here since it can reference a cte - - if node.Alias != "" { - node.Alias, err = cleanIdentifier(node.Alias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - return nil -} - -// EnterRelationSubquery checks the alias -func (s *StatementCleaner) EnterRelationSubquery(node *tree.RelationSubquery) (err error) { - if node.Alias != "" { - node.Alias, err = cleanIdentifier(node.Alias) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - return nil -} - -// EnterRelationJoin does nothing -func (s *StatementCleaner) EnterRelationJoin(node *tree.RelationJoin) (err error) { - return nil -} - -// EnterUpdateSetClause checks the column names -func (s *StatementCleaner) EnterUpdateSetClause(node *tree.UpdateSetClause) (err error) { - for i, column := range node.Columns { - node.Columns[i], err = cleanIdentifier(column) - if err != nil { - s.err(ErrInvalidIdentifier, err, node) - return nil - } - } - - return nil -} - -// EnterUpdate does nothing -func (s *StatementCleaner) EnterUpdateStmt(node *tree.UpdateStmt) (err error) { - return nil -} - -// EnterUpsert validates the upsert type -func (s *StatementCleaner) EnterUpsert(node *tree.Upsert) (err error) { - s.err(ErrInvalidUpsertType, node.Type.Valid(), node) - return nil -} diff --git a/parse/sql/sqlanalyzer/join/errors.go b/parse/sql/sqlanalyzer/join/errors.go deleted file mode 100644 index a58a4dfc4..000000000 --- a/parse/sql/sqlanalyzer/join/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package join - -import "errors" - -var ( - ErrInvalidJoinCondition = errors.New("invalid join condition") -) diff --git a/parse/sql/sqlanalyzer/join/joins.go b/parse/sql/sqlanalyzer/join/joins.go deleted file mode 100644 index 6f0cbc8d0..000000000 --- a/parse/sql/sqlanalyzer/join/joins.go +++ /dev/null @@ -1,123 +0,0 @@ -package join - -import "github.com/kwilteam/kwil-db/parse/sql/tree" - -/* - This file contains functionality for evaluating expressions as join conditions. - due to SQLite's propensity for cartesian joins, we need to impose very strict standards - on what constitutes a valid join condition. - - In the context of Kwil and SQLite, the terms "join condition" and "join constraint" are - used interchangeably. - - As per the SQLite docs: - - ` - All joins in SQLite are based on the cartesian product of the left and right-hand datasets. - The columns of the cartesian product dataset are, in order, all the columns of the left-hand - dataset followed by all the columns of the right-hand dataset. There is a row in the - cartesian product dataset formed by combining each unique combination of a row from the - left-hand and right-hand datasets. In other words, if the left-hand dataset consists of Nleft - rows of Mleft columns, and the right-hand dataset of Nright rows of Mright columns, then the - cartesian product is a dataset of Nleft×Nright rows, each containing Mleft+Mright columns. - - If the join-operator is "CROSS JOIN", "INNER JOIN", "JOIN" or a comma (",") and there is no - ON or USING clause, then the result of the join is simply the cartesian product of the left and - right-hand datasets. If join-operator does have ON or USING clauses, those are handled according - to the following bullet points: - - - If there is an ON clause then the ON expression is evaluated for each row of the cartesian - product as a boolean expression. Only rows for which the expression evaluates to true - are included from the dataset. - ` - - There are more bullet points, however this is the only one that is relevant to us. - - Due to this behavior, we need to ensure that join conditions: - - Are binary comparisons - - Contain columns from both sides of the join - - Do not contain any subqueries - - Do not contain any function calls - - Are joined with an "=" operator - -The joinAnalyzer is used in a DFS manner to determine if a join is valid. It can exist in one of the following states: -- joinableStatusInvalid: the join is invalid -- joinableStatusContainsColumn: the join contains a column from one of the tables -- joinableStatusValid: the join is valid - -*/ - -// checkJoin is used to check if a join is valid -func checkJoin(join *tree.JoinPredicate) error { - if validateJoinStatus(join.Constraint) != joinableStatusValid { - return ErrInvalidJoinCondition - } - - return nil -} - -func validateJoinStatus(joinConstraint tree.Expression) joinableStatus { - switch j := joinConstraint.(type) { - case *tree.ExpressionTextLiteral, *tree.ExpressionNumericLiteral, *tree.ExpressionBooleanLiteral, - *tree.ExpressionNullLiteral, *tree.ExpressionBlobLiteral: - return joinableStatusInvalid - case *tree.ExpressionBindParameter: - return joinableStatusInvalid - case *tree.ExpressionColumn: - return joinableStatusContainsColumn - case *tree.ExpressionUnary: - return joinableStatusInvalid - case *tree.ExpressionBinaryComparison: - left := validateJoinStatus(j.Left) - right := validateJoinStatus(j.Right) - if left == joinableStatusContainsColumn && right == joinableStatusContainsColumn && j.Operator == tree.ComparisonOperatorEqual { - return joinableStatusValid - } - - if left == joinableStatusContainsColumn || right == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid - case *tree.ExpressionFunction: - return joinableStatusInvalid - case *tree.ExpressionList: - return joinableStatusInvalid - case *tree.ExpressionCollate: - return validateJoinStatus(j.Expression) - case *tree.ExpressionStringCompare: - if validateJoinStatus(j.Left) == joinableStatusContainsColumn || validateJoinStatus(j.Right) == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid - case *tree.ExpressionIs: - if validateJoinStatus(j.Left) == joinableStatusContainsColumn || validateJoinStatus(j.Right) == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid - case *tree.ExpressionBetween: - return validateJoinStatus(j.Expression) - case *tree.ExpressionSelect: - return joinableStatusInvalid - case *tree.ExpressionCase: - return joinableStatusInvalid - case *tree.ExpressionArithmetic: - if validateJoinStatus(j.Left) == joinableStatusContainsColumn || validateJoinStatus(j.Right) == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid - } - - return joinableStatusInvalid -} - -type joinableStatus uint8 - -const ( - joinableStatusInvalid joinableStatus = iota - joinableStatusContainsColumn - joinableStatusValid -) diff --git a/parse/sql/sqlanalyzer/join/visitor.go b/parse/sql/sqlanalyzer/join/visitor.go deleted file mode 100644 index 1cbba12bb..000000000 --- a/parse/sql/sqlanalyzer/join/visitor.go +++ /dev/null @@ -1,27 +0,0 @@ -package join - -import ( - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -type joinWalker struct { - tree.AstListener - errs parseTypes.NativeErrorListener -} - -func NewJoinWalker(errLis parseTypes.NativeErrorListener) tree.AstListener { - return &joinWalker{ - AstListener: tree.NewBaseListener(), - errs: errLis, - } -} - -func (s *joinWalker) EnterJoinPredicate(j *tree.JoinPredicate) error { - err := checkJoin(j) - if err != nil { - s.errs.NodeErr(j.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - - return nil -} diff --git a/parse/sql/sqlanalyzer/mutative/mutative_test.go b/parse/sql/sqlanalyzer/mutative/mutative_test.go deleted file mode 100644 index 4c1f869cf..000000000 --- a/parse/sql/sqlanalyzer/mutative/mutative_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package mutative_test - -import ( - "testing" - - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/mutative" -) - -func Test_Mutativity(t *testing.T) { - type testCase struct { - name string - input string - wantMutative bool - } - - testCases := []testCase{ - { - name: "simple select", - input: "SELECT * FROM users", - wantMutative: false, - }, - { - name: "simple insert", - input: "INSERT INTO users VALUES (1, 'test')", - wantMutative: true, - }, - { - name: "simple update", - input: "UPDATE users SET name = 'test' WHERE id = 1", - wantMutative: true, - }, - { - name: "simple delete", - input: "DELETE FROM users WHERE id = 1", - wantMutative: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - stmt, err := sqlparser.Parse(tc.input) - if err != nil { - t.Fatalf("failed to parse input: %v", err) - } - - mutativityWalker := mutative.NewMutativityWalker() - - err = stmt.Walk(mutativityWalker) - if err != nil { - t.Fatalf("failed to walk statement: %v", err) - } - - if mutativityWalker.Mutative != tc.wantMutative { - t.Fatalf("got mutativity %v, want %v", mutativityWalker.Mutative, tc.wantMutative) - } - }) - } -} diff --git a/parse/sql/sqlanalyzer/mutative/walker.go b/parse/sql/sqlanalyzer/mutative/walker.go deleted file mode 100644 index 4e6af19a2..000000000 --- a/parse/sql/sqlanalyzer/mutative/walker.go +++ /dev/null @@ -1,31 +0,0 @@ -package mutative - -import "github.com/kwilteam/kwil-db/parse/sql/tree" - -// IsMutative returns true if the statement is mutative, false otherwise. -func NewMutativityWalker() *MutativityWalker { - return &MutativityWalker{ - AstListener: tree.NewBaseListener(), - Mutative: false, - } -} - -type MutativityWalker struct { - Mutative bool - tree.AstListener -} - -func (m *MutativityWalker) EnterDeleteCore(node *tree.DeleteCore) error { - m.Mutative = true - return nil -} - -func (m *MutativityWalker) EnterInsertCore(node *tree.InsertCore) error { - m.Mutative = true - return nil -} - -func (m *MutativityWalker) EnterUpdateCore(node *tree.UpdateCore) error { - m.Mutative = true - return nil -} diff --git a/parse/sql/sqlanalyzer/mutativity.go b/parse/sql/sqlanalyzer/mutativity.go deleted file mode 100644 index 3516990ac..000000000 --- a/parse/sql/sqlanalyzer/mutativity.go +++ /dev/null @@ -1,20 +0,0 @@ -package sqlanalyzer - -import ( - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/mutative" - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -// IsMutative returns true if the statement is mutative, false otherwise. -// It doesn't need an error listener since it doesn't actually perform any syntax/ -// semantic analysis, it simply checks if there is an INSERT, UPDATE, or DELETE. -func IsMutative(stmt tree.AstWalker) (bool, error) { - mutativityWalker := mutative.NewMutativityWalker() - - err := stmt.Walk(mutativityWalker) - if err != nil { - return false, err - } - - return mutativityWalker.Mutative, nil -} diff --git a/parse/sql/sqlanalyzer/order/README.md b/parse/sql/sqlanalyzer/order/README.md deleted file mode 100644 index 74b6c00ce..000000000 --- a/parse/sql/sqlanalyzer/order/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Ordering - -To enforce guaranteed ordering, we enforce default ordering rules. Statements are broken down into their `*tree.SelectStmt` structs, -including nested statements (in the case of CTEs or subqueries). - -Each `*tree.SelectStmt` is categorized as either being simple or compound. A compound is a SELECT that uses a compound operator, -such as UNION. A simple SELECT is a select that does not have any compound operator. - -## Simple SELECTs - -Simple SELECTs have the following rules applied: - -- Each primary key column FOR EACH TABLE JOINED is ordered in ascending order. Table aliases will be ordered instead of name, if used. -- Primary keys from all used tables are ordered alphabetically (first by table name, then by column name) Primary keys are given precedence alphabetically (e.g. column "age" will be ordered before column "name") -- User provided ordering is given precedence over default ordering, and will therefore appear first in the statement. - -If a simple SELECT has a GROUP BY clause, none of these rules apply, and instead it will simply order by all columns includes in the group by. - -If a simple SELECT is a SELECT DISTINCT, then it will order by every returned column, in the order which it appears. The reasoning for this can be found here: - -Statement cannot be both SELECT DISTINCT and contain GROUP BY - -## Compound SELECTs - -Compound SELECTs will be ordered by each returned column, in the order they appear. For the time being, compound selects with group bys will be rejected. -This is a remnant of a restriction imposed by SQLite's relatively rudimentary referencing, where it cannot order table aliases in a compound select. -If we wish to support GROUP BYs in compound selects in the future, we will need to dig deeper on Postgres's referencing. Since group bys in compounds are not -very common statements, we have decided to not support them for now. diff --git a/parse/sql/sqlanalyzer/order/order.go b/parse/sql/sqlanalyzer/order/order.go deleted file mode 100644 index 83283230e..000000000 --- a/parse/sql/sqlanalyzer/order/order.go +++ /dev/null @@ -1,484 +0,0 @@ -package order - -import ( - "errors" - "fmt" - "sort" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/typing" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/utils" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -func NewOrderWalker(schema *types.Schema, errLis parseTypes.NativeErrorListener) tree.AstListener { - // copy tables, since we will be modifying the tables slice to register CTEs - tbls := make([]*types.Table, len(schema.Tables)) - copy(tbls, schema.Tables) - - return &orderingWalker{ - schema: schema, - tables: tbls, - errs: errLis, - } -} - -// orderingWalker is the highest level walker to order a statement -type orderingWalker struct { - tree.BaseListener - - schema *types.Schema - tables []*types.Table // all tables in the schema - errs parseTypes.NativeErrorListener -} - -var _ tree.AstListener = &orderingWalker{} - -// we need to register common table expressions as tables, so that we can order them. -func (o *orderingWalker) EnterCTE(node *tree.CTE) error { - if len(node.Select.SimpleSelects) == 0 { - return nil - } - - res, err := typing.AnalyzeTypes(node.Select, o.tables, &typing.AnalyzeOptions{ - ArbitraryBinds: true, - }) - if err != nil { - return err - } - - tbl, err := tableFromRelation(res, node.Table) - if err != nil { - return err - } - - // make sure this does not have a conflicting name with another table - _, err = findTable(o.tables, tbl.Name) - if err == nil { - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, - fmt.Errorf(`table or subquery with name or alias "%s" already exists`, tbl.Name)) - return nil - } - - o.tables = append(o.tables, tbl) - - return nil -} - -// tableFromRelation will return a table from a relation. -// It will make all columns primary keys. -func tableFromRelation(rel *typing.Relation, name string) (*types.Table, error) { - tbl := &types.Table{ - Name: name, - } - - cols := make([]string, 0) - err := rel.Loop(func(s string, a *typing.Attribute) error { - tbl.Columns = append(tbl.Columns, &types.Column{ - Name: s, - Type: a.Type, - }) - - cols = append(cols, s) - return nil - }) - if err != nil { - return nil, err - } - - tbl.Indexes = []*types.Index{ - { - Name: "_auto_primary_", - Columns: cols, - Type: types.PRIMARY, - }, - } - - return tbl, nil -} - -// Register RelationSubquerys as tables, so that we can order them. -func (o *orderingWalker) EnterRelationSubquery(node *tree.RelationSubquery) error { - if node.Select == nil { - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("subquery select is nil")) - return nil - } - if len(node.Select.SimpleSelects) == 0 { - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("subquery select has no select cores")) - return nil - } - - name := node.Alias // can be "" - - res, err := typing.AnalyzeTypes(node.Select, o.tables, &typing.AnalyzeOptions{ - ArbitraryBinds: true, - Schema: o.schema, - }) - if err != nil { - return err - } - - tbl, err := tableFromRelation(res, name) - if err != nil { - return err - } - - // make sure this does not have a conflicting name with another table - _, err = findTable(o.tables, tbl.Name) - if err == nil { - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf(`table or subquery with name or alias "%s" already exists`, tbl.Name)) - return nil - } - - o.tables = append(o.tables, tbl) - - return nil -} - -// put this on exit so we can search the whole statement for used tables -func (o *orderingWalker) ExitSelectCore(node *tree.SelectCore) error { - var terms []*tree.OrderingTerm - var err error - switch len(node.SimpleSelects) { - case 0: - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("no select cores in select statement")) - return nil - case 1: - terms, err = o.orderSimpleStatement(node.SimpleSelects[0], o.tables) - default: - terms, err = o.orderCompoundStatement(node.SimpleSelects, o.tables) - } - if err != nil { - o.errs.NodeErr(node.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return nil - } - - if len(terms) == 0 { - return nil - } - - if node.OrderBy == nil { - node.OrderBy = &tree.OrderBy{ - OrderingTerms: terms, - } - } else { - node.OrderBy.OrderingTerms = append(node.OrderBy.OrderingTerms, terms...) - } - - return nil -} - -var ErrDistinctWithGroupBy = errors.New("select distinct with group by not supported") - -// orderSimpleStatement will return the ordering required for a simple statement. -// If there are errors we wish to pass to the error listener, we will simply log them here and return nil error, -// since returning nil,nil is a valid return value for this function. -func (o *orderingWalker) orderSimpleStatement(stmt *tree.SimpleSelect, tables []*types.Table) ([]*tree.OrderingTerm, error) { - // it is possible to not have any tables in a select - // if so, no ordering is required - if stmt.From == nil { - return nil, nil - } - - // if there is a group by clause, then we order by each term in the group by clause - // if there is no group by clause, then we order by primary keys. - // if there is no group by and an aggregate function is used, all other columns returned must - // be aggregates, or else we throw an error. We do not need to order in this case, since an - // aggregate with no group by will always return a simple row. - - if stmt.GroupBy != nil && len(stmt.GroupBy.Expressions) > 0 { - // if it has a distinct, error as this is not allowed. We do not know how to order this. - if stmt.SelectType == tree.SelectTypeDistinct { - return nil, ErrDistinctWithGroupBy - } - - // it has a group by, order by each of them - columns := make([]*tree.OrderingTerm, len(stmt.GroupBy.Expressions)) - for i, expr := range stmt.GroupBy.Expressions { - cols := utils.SearchResultColumns(expr) - switch len(cols) { - case 0: - return nil, nil - case 1: - columns[i] = &tree.OrderingTerm{ - Expression: &tree.ExpressionColumn{ - Table: cols[0].Table, - Column: cols[0].Column, - }, - } - default: - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeSemantic, - errors.New("multiple columns in a simple grouped term in a group by expression not supported")) - return nil, nil - } - } - - return columns, nil - } - - // if we reach here, there is no group by clause. - - // we will now get a list of all tables that are renamed to the used aliases - // this allows us to search for them by their alias, and not their real name. - usedTables, err := utils.GetUsedTables(stmt.From) - if err != nil { - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeUnknown, err) - return nil, nil - } - - usedTblsFull := make([]*types.Table, len(usedTables)) - for i, tbl := range usedTables { - newTable, err := findTable(tables, tbl.Name) - if err != nil { - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return nil, nil - } - - copied := newTable.Copy() // copy since we will be modifying the table - - // set the alias to the table name if it exists - if tbl.Alias != "" { - copied.Name = tbl.Alias - } - - usedTblsFull[i] = copied - } - - if stmt.SelectType == tree.SelectTypeDistinct { - return o.getReturnedColumnOrderingTerms(stmt.Columns, usedTblsFull) - } - - sort.Slice(usedTblsFull, func(i, j int) bool { - return usedTblsFull[i].Name < usedTblsFull[j].Name - }) - - // we first must check if there are any aggregate functions in the result columns. - // if so, then all other columns must be aggregates, or else we throw an error. - numberOfAggregates := 0 - for _, ret := range stmt.Columns { - containsAggregate, err := containsAggregateFunc(ret) - if err != nil { - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeUnknown, err) - return nil, nil - } - - if containsAggregate { - numberOfAggregates++ - } - } - - if numberOfAggregates > 0 { - if numberOfAggregates != len(stmt.Columns) { - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeSemantic, - errors.New("all columns must be aggregates if an aggregate function is used without a group by")) - return nil, nil - } - return nil, nil // order nothing in this case - } - - orderingTerms := make([]*tree.OrderingTerm, 0) - for _, tbl := range usedTblsFull { - primaries, err := tbl.GetPrimaryKey() - if err != nil { - o.errs.NodeErr(stmt.GetNode(), parseTypes.ParseErrorTypeUnknown, err) - return nil, nil - } - - if len(primaries) == 0 { - continue // can't happen I think - } - - sort.Strings(primaries) - - for _, primary := range primaries { - orderingTerms = append(orderingTerms, &tree.OrderingTerm{ - Expression: &tree.ExpressionColumn{ - Table: tbl.Name, - Column: primary, - }, - }) - } - } - - return orderingTerms, nil -} - -// there can be two types of ordering: simple and compound statements. -// a simple statement is just a simple select statement, while a compound statement is a select statement with a union, intersect, etc -// each of the below functions will return the ordering that is required for the statement. - -// containsAggregateFunc returns true if the result column contains an aggregate function. -func containsAggregateFunc(ret tree.ResultColumn) (bool, error) { - containsAggregateFunc := false - depth := 0 // depth tracks if we are in a subquery or not - - err := ret.Walk(&tree.ImplementedListener{ - FuncEnterExpressionFunction: func(p0 *tree.ExpressionFunction) error { - if depth == 0 { - def, ok := metadata.Functions[p0.Function] - if !ok { - // can be a procedure - return nil - } - - containsAggregateFunc = def.IsAggregate - } - return nil - }, - FuncEnterSelectCore: func(p0 *tree.SelectCore) error { - depth++ - return nil - }, - FuncExitSelectCore: func(p0 *tree.SelectCore) error { - depth-- - return nil - }, - }) - - return containsAggregateFunc, err -} - -var ErrGroupByWithCompoundStatement = fmt.Errorf("statements cannot have a group by clause with a compound SELECT statement") -var ErrCompoundStatementDifferentNumberOfColumns = fmt.Errorf("select cores have different number of result columns") - -// orderCompoundStatement will return the ordering required for a compound statement. -// it will order each result column, in the order they are returned. -// if there is a group by clause in any of the select cores, we will return an error. -// using a group by with a compound statement is not yet supported because idk how -// to make it deterministic with postgres's ordering, and it is not a common use case. -// If there are errors we wish to pass to the error listener, we will simply log them here and return nil error, -// since returning nil,nil is a valid return value for this function. -func (o *orderingWalker) orderCompoundStatement(stmt []*tree.SimpleSelect, tables []*types.Table) ([]*tree.OrderingTerm, error) { - if len(stmt) == 0 { - // returning error here since this would indicate a bug in the parser - return nil, fmt.Errorf("no select cores in compound statement") - } - - expectedNumberOfColumns := len(stmt[0].Columns) - - // we need to ensure that all cores have the same amount of result columns. - // if so, we will simply order the first one, and then return. - // we also need to check there are no group by clauses in any of the select cores. - for _, core := range stmt { - contains, err := containsGroupBy(core) - if err != nil { - o.errs.NodeErr(core.GetNode(), parseTypes.ParseErrorTypeUnknown, err) - return nil, nil - } - - if contains { - o.errs.NodeErr(core.GetNode(), parseTypes.ParseErrorTypeSemantic, ErrGroupByWithCompoundStatement) - return nil, nil - } - - if len(core.Columns) != expectedNumberOfColumns { - o.errs.NodeErr(core.GetNode(), parseTypes.ParseErrorTypeSemantic, ErrCompoundStatementDifferentNumberOfColumns) - return nil, nil - } - } - - // we will order the first select core, and then return. - return o.getReturnedColumnOrderingTerms(stmt[0].Columns, tables) -} - -// containsGroupBy will return true if the select core contains a group by clause. -func containsGroupBy(stmt *tree.SimpleSelect) (bool, error) { - contains := false - depth := 0 - - err := stmt.Walk(&tree.ImplementedListener{ - FuncEnterGroupBy: func(p0 *tree.GroupBy) error { - if depth == 0 { - if len(p0.Expressions) > 0 { - contains = true - } - } - return nil - }, - FuncEnterSelectCore: func(p0 *tree.SelectCore) error { - depth++ - return nil - }, - FuncExitSelectCore: func(p0 *tree.SelectCore) error { - depth-- - return nil - }, - }) - - return contains, err -} - -// getReturnedColumnOrderingTerms gets the ordering terms for the returned columns. -// it is used to order result columns for compound select statements or distinct statements. -// If there are errors we wish to pass to the error listener, we will simply log them here and return nil error, -// since returning nil,nil is a valid return value for this function. -func (o *orderingWalker) getReturnedColumnOrderingTerms(resultCols []tree.ResultColumn, tables []*types.Table) ([]*tree.OrderingTerm, error) { - terms := []*tree.OrderingTerm{} - - for _, col := range resultCols { - switch c := col.(type) { - default: - panic(fmt.Sprintf("unexpected result column type: %T", c)) - case *tree.ResultColumnExpression: - // we simply use the expression as the ordering term - // this works even for complex expressions, such as - // "SELECT sum(a%4/(b+2)) FROM table" - terms = append(terms, &tree.OrderingTerm{ - Expression: c.Expression, - }) - case *tree.ResultColumnTable: - tbl, err := findTable(tables, c.TableName) - if err != nil { - o.errs.NodeErr(c.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return nil, nil - } - - terms = append(terms, getTableOrderTerms(tbl)...) - case *tree.ResultColumnStar: - sort.Slice(tables, func(i, j int) bool { - return tables[i].Name < tables[j].Name - }) - - for _, tbl := range tables { - terms = append(terms, getTableOrderTerms(tbl)...) - } - } - } - - return terms, nil -} - -// getTableOrderTerms returns the ordering terms for a table. -// It is used to order result columns for compound select statements or distinct statements. -func getTableOrderTerms(tbl *types.Table) []*tree.OrderingTerm { - terms := []*tree.OrderingTerm{} - - columns := tbl.Columns - sort.Slice(columns, func(i, j int) bool { - return columns[i].Name < columns[j].Name - }) - - for _, col := range columns { - terms = append(terms, &tree.OrderingTerm{ - Expression: &tree.ExpressionColumn{ - Table: tbl.Name, - Column: col.Name, - }, - }) - } - - return terms -} - -// findTable will return the table with the given name, or an error if it does not exist. -func findTable(tables []*types.Table, name string) (*types.Table, error) { - for _, tbl := range tables { - if tbl.Name == name { - return tbl, nil - } - } - - return nil, fmt.Errorf("unknown table: %s", name) -} diff --git a/parse/sql/sqlanalyzer/order/order_test.go b/parse/sql/sqlanalyzer/order/order_test.go deleted file mode 100644 index 9ac7788ec..000000000 --- a/parse/sql/sqlanalyzer/order/order_test.go +++ /dev/null @@ -1,290 +0,0 @@ -package order_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/core/types" - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/postgres" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/order" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_Order(t *testing.T) { - type testcase struct { - name string - stmt string - want string - err error // can be nil - } - - tests := []testcase{ - { - name: "simple select", - stmt: `SELECT * FROM users;`, - want: `SELECT * FROM "users" ORDER BY "users"."id";`, - }, - { - name: "table joined on self", - stmt: `SELECT u1.id, u1.name, u2.name - FROM users AS u1 - INNER JOIN users AS u2 ON u1.id = u2.id`, - want: `SELECT "u1"."id", "u1"."name", "u2"."name" - FROM "users" AS "u1" - INNER JOIN "users" AS "u2" ON "u1"."id" = "u2"."id" - ORDER BY "u1"."id" , "u2"."id";`, - }, - { - name: "aliased columns", - stmt: `SELECT u.id AS user_id, u.name AS user_name FROM users AS u;`, - want: `SELECT "u"."id" AS "user_id", "u"."name" AS "user_name" FROM "users" AS "u" ORDER BY "u"."id";`, - }, - { - name: "select count", - stmt: `SELECT count(*) FROM users;`, - want: `SELECT count(*) FROM "users";`, - }, - { - name: "select with joins and aliases", - stmt: `SELECT * FROM users AS u INNER JOIN posts AS p ON u.id = p.user_id;`, - want: `SELECT * FROM "users" AS "u" INNER JOIN "posts" AS "p" ON "u"."id" = "p"."user_id" ORDER BY "p"."id", "u"."id";`, - }, - { - name: "select distinct", - stmt: `SELECT DISTINCT id, name FROM users;`, - want: `SELECT DISTINCT "id", "name" FROM "users" ORDER BY "id", "name";`, - }, - { - name: "select distinct with join", - stmt: `SELECT DISTINCT u.id, p.title FROM users AS u INNER JOIN posts AS p ON u.id = p.user_id;`, - want: `SELECT DISTINCT "u"."id", "p"."title" FROM "users" AS "u" INNER JOIN "posts" AS "p" ON "u"."id" = "p"."user_id" ORDER BY "u"."id", "p"."title";`, - }, - { - name: "SELECT DISTINCT with group by", - stmt: `SELECT DISTINCT id, name FROM users GROUP BY id;`, - err: order.ErrDistinctWithGroupBy, - }, - { - name: "select distinct with self join and aliases", - stmt: `SELECT DISTINCT u1.* FROM users AS u1 INNER JOIN users AS u2 ON u1.id = u2.id;`, - want: `SELECT DISTINCT "u1".* FROM "users" AS "u1" INNER JOIN "users" AS "u2" ON "u1"."id" = "u2"."id" ORDER BY "u1"."id", "u1"."name";`, - }, - { - name: "select distinct * with self join and aliases", - stmt: `SELECT DISTINCT * FROM users AS u1 INNER JOIN users AS u2 ON u1.id = u2.id;`, - want: `SELECT DISTINCT * FROM "users" AS "u1" INNER JOIN "users" AS "u2" ON "u1"."id" = "u2"."id" ORDER BY "u1"."id", "u1"."name", "u2"."id", "u2"."name";`, - }, - { - name: "select with joins and subqueries", // it should not register the subquery as a table - stmt: `SELECT p.id, p.title, (SELECT count(*) FROM likes WHERE likes.post_id = p.id) AS total_likes - FROM posts AS p - INNER JOIN followers AS f ON p.user_id = f.user_id - INNER JOIN users ON users.id = f.user_id - WHERE f.follower_id = ( - SELECT liker_id from likes WHERE likes.post_id = p.id - ) - ORDER BY p.post_date DESC NULLS LAST - LIMIT 20 OFFSET $offset;`, - want: `SELECT "p"."id", "p"."title", (SELECT count(*) FROM "likes" WHERE "likes"."post_id" = "p"."id") AS "total_likes" - FROM "posts" AS "p" - INNER JOIN "followers" AS "f" ON "p"."user_id" = "f"."user_id" - INNER JOIN "users" ON "users"."id" = "f"."user_id" - WHERE "f"."follower_id" = ( - SELECT "liker_id" FROM "likes" WHERE "likes"."post_id" = "p"."id" ORDER BY "likes"."liker_id", "likes"."post_id" - ) - ORDER BY "p"."post_date" DESC NULLS LAST, "f"."follower_id", "f"."user_id", "p"."id", "users"."id" - LIMIT 20 OFFSET $offset;`, - }, - { - name: "compound select", - stmt: `SELECT id, name FROM users UNION SELECT id, name FROM users;`, - want: `SELECT "id", "name" FROM "users" UNION SELECT "id", "name" FROM "users" ORDER BY "id", "name";`, - }, - { - name: "compound select with incompatible tables", - stmt: `SELECT id, name FROM users UNION SELECT * FROM posts;`, - err: order.ErrCompoundStatementDifferentNumberOfColumns, - }, - { - name: "compound with group by", - stmt: `SELECT id, name FROM users GROUP BY id UNION SELECT id, name FROM users;`, - err: order.ErrGroupByWithCompoundStatement, - }, - { - name: "common table expression", - stmt: `WITH - user_likes_count AS ( - SELECT liker_id as user_id, count(*) AS likes_count FROM likes GROUP BY liker_id - ) - SELECT u.id, u.name, ulc.likes_count - FROM users AS u - LEFT JOIN user_likes_count AS ulc ON u.id = ulc.user_id;`, - want: `WITH - "user_likes_count" AS ( - SELECT "liker_id" AS "user_id", count(*) AS "likes_count" FROM "likes" GROUP BY "liker_id" ORDER BY "liker_id" - ) - SELECT "u"."id", "u"."name", "ulc"."likes_count" - FROM "users" AS "u" - LEFT JOIN "user_likes_count" AS "ulc" ON "u"."id" = "ulc"."user_id" ORDER BY "u"."id", "ulc"."likes_count", "ulc"."user_id";`, - // order u ahead of ulc because we order based on alias - }, - { - name: "raw select", - stmt: `SELECT $id AS res`, - want: `SELECT $id AS "res";`, - }, - { - name: "joined subquery", - stmt: `SELECT u.id, subq.total_likes - FROM users AS u - INNER JOIN ( - SELECT post_id, count(*) AS total_likes FROM likes GROUP BY post_id - ) AS subq ON u.id = subq.post_id;`, - want: `SELECT "u"."id", "subq"."total_likes" - FROM "users" AS "u" - INNER JOIN ( - SELECT "post_id", count(*) AS "total_likes" FROM "likes" GROUP BY "post_id" ORDER BY "post_id" - ) AS "subq" ON "u"."id" = "subq"."post_id" ORDER BY "subq"."post_id", "subq"."total_likes", "u"."id";`, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - stmt, err := sqlparser.Parse(tt.stmt) - require.NoError(t, err) - - errLis := parseTypes.NewErrorListener() - - walker := order.NewOrderWalker(&types.Schema{ - Tables: defaultTables, - }, errLis) - err = stmt.Walk(walker) - require.Nil(t, err) - if errLis.Err() != nil { - require.Contains(t, errLis.Err().Error(), tt.err.Error()) - return - } - require.Equal(t, tt.err, err) - - sql, err := tree.SafeToSQL(stmt) - require.NoError(t, err) - - assert.Equal(t, removeSpaces(tt.want), removeSpaces(sql)) - - err = postgres.CheckSyntaxReplaceDollar(sql) - assert.NoErrorf(t, err, "postgres syntax check failed: %s", err) - }) - } -} - -var defaultTables = []*types.Table{ - { - Name: "users", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "name", - Type: types.TextType, - }, - }, - Indexes: []*types.Index{}, - ForeignKeys: []*types.ForeignKey{}, - }, - { - Name: "posts", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.PRIMARY_KEY, - }, - }, - }, - { - Name: "user_id", - Type: types.IntType, - Attributes: []*types.Attribute{ - { - Type: types.NOT_NULL, - }, - }, - }, - { - Name: "title", - Type: types.TextType, - }, - }, - }, - { - Name: "followers", - Columns: []*types.Column{ - { - Name: "user_id", - Type: types.IntType, - }, - { - Name: "follower_id", - Type: types.IntType, - }, - }, - Indexes: []*types.Index{ - { - Name: "primary_key", - Columns: []string{ - "user_id", - "follower_id", - }, - Type: types.PRIMARY, - }, - }, - }, - { - // likes is a join table for liker id and post id - Name: "likes", - Columns: []*types.Column{ - { - Name: "liker_id", - Type: types.IntType, - }, - { - Name: "post_id", - Type: types.IntType, - }, - }, - Indexes: []*types.Index{ - { - Name: "primary_key", - Columns: []string{ - "liker_id", - "post_id", - }, - Type: types.PRIMARY, - }, - }, - }, -} - -// removeSpaces removes all spaces from a string. -// this is useful for comparing strings, where one is generated -func removeSpaces(s string) string { - var result []rune - for _, ch := range s { - if ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' { - result = append(result, ch) - } - } - return string(result) -} diff --git a/parse/sql/sqlanalyzer/parameters/rename.go b/parse/sql/sqlanalyzer/parameters/rename.go deleted file mode 100644 index dce2b81fd..000000000 --- a/parse/sql/sqlanalyzer/parameters/rename.go +++ /dev/null @@ -1,16 +0,0 @@ -package parameters - -import "github.com/kwilteam/kwil-db/parse/sql/tree" - -// RenameVariables calls the callback function for each bind parameter in the statement. -// It does not verify syntax / semantics, so it does not need an error listener. -func RenameVariables(ast tree.AstWalker, fn func(b string) string) error { - walker := &tree.ImplementedListener{ - FuncEnterExpressionBindParameter: func(p0 *tree.ExpressionBindParameter) error { - p0.Parameter = fn(p0.Parameter) - return nil - }, - } - - return ast.Walk(walker) -} diff --git a/parse/sql/sqlanalyzer/parameters/visitor.go b/parse/sql/sqlanalyzer/parameters/visitor.go deleted file mode 100644 index ec924ab4d..000000000 --- a/parse/sql/sqlanalyzer/parameters/visitor.go +++ /dev/null @@ -1,47 +0,0 @@ -package parameters - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -// ParametersWalker walks the AST and replaces all bind parameters with numbered parameters. -type ParametersWalker struct { - // OrderedParameters are the passed named identifiers in the order that they have become numbered. - // For example, if a query was SELECT * FROM tbl WHERE a = $a AND b = $b, the query would be rewritten - // as SELECT * FROM tbl WHERE a = $1 AND b = $2, and OrderedParameters would be []string{"$a", "$b"}. - OrderedParameters []string - renamedParams map[string]string // maps $bindParam to $1 - tree.AstListener -} - -func NewParametersWalker() *ParametersWalker { - return &ParametersWalker{ - OrderedParameters: []string{}, - renamedParams: map[string]string{}, - AstListener: tree.NewBaseListener(), - } -} - -func (p *ParametersWalker) EnterExpressionBindParameter(b *tree.ExpressionBindParameter) error { - // check if the parameter has already been numbered - // if not, then we will number it - if param, ok := p.renamedParams[b.Parameter]; ok { - b.Parameter = param - return nil - } - - // the parameter has not been numbered yet - num := len(p.OrderedParameters) + 1 - p.OrderedParameters = append(p.OrderedParameters, b.Parameter) - - numberedName := "$" + fmt.Sprint(num) - - // rename the parameter - p.renamedParams[b.Parameter] = numberedName - - b.Parameter = numberedName - - return nil -} diff --git a/parse/sql/sqlanalyzer/parameters/visitor_test.go b/parse/sql/sqlanalyzer/parameters/visitor_test.go deleted file mode 100644 index 0070cff3d..000000000 --- a/parse/sql/sqlanalyzer/parameters/visitor_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package parameters_test - -import ( - "strings" - "testing" - "unicode" - - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/postgres" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/parameters" - "github.com/kwilteam/kwil-db/parse/sql/tree" - "github.com/stretchr/testify/assert" -) - -func Test_NumberedParameters(t *testing.T) { - type testCase struct { - name string - stmt string - wantParams []string - wantStmt string - } - - tests := []testCase{ - { - name: "simple select", - stmt: `SELECT * FROM "table" WHERE "id" = $id;`, - wantParams: []string{"$id"}, - wantStmt: `SELECT * FROM "table" WHERE "id" = $1;`, - }, - { - name: "simple select with multiple parameters", - stmt: `SELECT * FROM "table" WHERE "id" = $id AND "name" = $name;`, - wantParams: []string{"$id", "$name"}, - wantStmt: `SELECT * FROM "table" WHERE "id" = $1 AND "name" = $2;`, - }, - { - name: "repeating parameters", - stmt: `SELECT * FROM "table" WHERE "id" = $id AND "name" = $id AND "age" = $name AND "address" = $id;`, - wantParams: []string{ - "$id", - "$name", - }, - wantStmt: `SELECT * FROM "table" WHERE "id" = $1 AND "name" = $1 AND "age" = $2 AND "address" = $1;`, - }, - { - name: "@ binding", - stmt: `SELECT * FROM "table" WHERE "id" = @id AND "name" = @caller;`, - wantParams: []string{ - "@id", - "@caller", - }, - wantStmt: `SELECT * FROM "table" WHERE "id" = $1 AND "name" = $2;`, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - stmt, err := sqlparser.Parse(tt.stmt) - if err != nil { - t.Errorf("Parameters() = %v, want %v", err, tt.wantParams) - } - - v := parameters.NewParametersWalker() - - if err := stmt.Walk(v); err != nil { - t.Errorf("Parameters() = %v, want %v", err, tt.wantParams) - } - - got := v.OrderedParameters - - if len(got) != len(tt.wantParams) { - t.Errorf("Parameters() = %v, want %v", got, tt.wantParams) - } - - for i := range got { - if got[i] != tt.wantParams[i] { - t.Errorf("Parameters() = %v, want %v", got, tt.wantParams) - } - } - - str, err := tree.SafeToSQL(stmt) - if err != nil { - t.Errorf("Parameters() = %v, want %v", err, tt.wantParams) - } - trimmedRes := removeWhitespace(str) - trimmedWant := removeWhitespace(tt.wantStmt) - - if trimmedRes != trimmedWant { - t.Errorf("Parameters() = %v, want %v", trimmedRes, trimmedWant) - } - - err = postgres.CheckSyntaxReplaceDollar(str) - assert.NoErrorf(t, err, "postgres syntax check failed: %s", err) - }) - } -} - -// removeWhitespace removes all whitespace characters from a string. -func removeWhitespace(s string) string { - return strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return -1 // skip this rune - } - return r - }, s) -} diff --git a/parse/sql/sqlanalyzer/schema/walker.go b/parse/sql/sqlanalyzer/schema/walker.go deleted file mode 100644 index 1db538bf3..000000000 --- a/parse/sql/sqlanalyzer/schema/walker.go +++ /dev/null @@ -1,82 +0,0 @@ -package schema - -import ( - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -// SchemaWalker walks statements and ensures that their statements are targeting a postgres schema / namespace. -type SchemaWalker struct { - tree.AstListener - schema string - ctes map[string]struct{} // we keep track of ctes since they should not be prefixed with a schema - - // SetCount is the number of table refs where the schema was set by the walker. - SetCount int -} - -// NewSchemaWalker creates a new SchemaWalker. -// The schemawalker qualifies table names with the target schema. -// it does not perform syntax / semantic validation, and therefore -// does not need an error listener. -func NewSchemaWalker(targetSchema string) *SchemaWalker { - return &SchemaWalker{ - AstListener: tree.NewBaseListener(), - schema: targetSchema, - ctes: make(map[string]struct{}), - } -} - -type settable interface { - SetSchema(string) -} - -// set conditionally sets the schema of the settable, if the table is not a CTE. -func (s *SchemaWalker) set(table string, st settable) { - if _, ok := s.ctes[table]; ok { - return - } - - s.SetCount++ - st.SetSchema(s.schema) -} - -func (w *SchemaWalker) EnterInsertCore(stmt *tree.InsertCore) error { - w.set(stmt.Table, stmt) - return nil -} - -func (w *SchemaWalker) EnterQualifiedTableName(q *tree.QualifiedTableName) error { - w.set(q.TableName, q) - return nil -} - -func (w *SchemaWalker) EnterRelationTable(t *tree.RelationTable) error { - w.set(t.Name, t) - return nil -} - -/* - There is a special case where common table expressions should not be prefixed with a schema. - In postgres, CTEs cannot be used before they are declared. For example, the following schema is will fail: - with users_2 as ( - select * from users_1 - ), users_1 as ( - select * from users - ) - select * from users_2 - - The following schema will succeed: - with users_2 as ( - select * from users - ), users_1 as ( - select * from users_2 - ) - select * from users_1 - - Therefore, we simply need to intercept the CTEs and keep track of them. -*/ - -func (w *SchemaWalker) EnterCTE(cte *tree.CTE) error { - w.ctes[cte.Table] = struct{}{} - return nil -} diff --git a/parse/sql/sqlanalyzer/schema/walker_test.go b/parse/sql/sqlanalyzer/schema/walker_test.go deleted file mode 100644 index 8cc596221..000000000 --- a/parse/sql/sqlanalyzer/schema/walker_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package schema_test - -import ( - "strings" - "testing" - "unicode" - - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/postgres" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/schema" - "github.com/kwilteam/kwil-db/parse/sql/tree" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_PGSchemas(t *testing.T) { - type testcase struct { - name string - stmt string - schema string - want string - } - - tests := []testcase{ - { - name: "basic select", - stmt: `SELECT * FROM "foo";`, - want: `SELECT * FROM "baz"."foo";`, - schema: "baz", - }, - { - name: "insert", - stmt: `INSERT INTO "foo" ("bar", "baz") VALUES ('barVal', $a);`, - want: `INSERT INTO "baz"."foo" ("bar", "baz") VALUES ('barVal', $a);`, - schema: "baz", - }, - { - name: "update", - stmt: `UPDATE "foo" SET "bar" = 'barVal' WHERE "baz" = $a;`, - want: `UPDATE "baz"."foo" SET "bar" = 'barVal' WHERE "baz" = $a;`, - schema: "baz", - }, - { - name: "delete", - stmt: `DELETE FROM "foo" WHERE "bar" = 'barVal';`, - want: `DELETE FROM "baz"."foo" WHERE "bar" = 'barVal';`, - schema: "baz", - }, - { - name: "common table expression", - stmt: `WITH "cte" AS (SELECT * FROM "foo") SELECT * FROM "cte";`, - want: `WITH "cte" AS (SELECT * FROM "baz"."foo") SELECT * FROM "cte";`, - schema: "baz", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - stmt, err := sqlparser.Parse(tt.stmt) - require.NoError(t, err) - - w := schema.NewSchemaWalker(tt.schema) - - err = stmt.Walk(w) - require.NoError(t, err) - - got, err := tree.SafeToSQL(stmt) - require.NoError(t, err) - - require.Equal(t, removeWhitespace(tt.want), removeWhitespace(got)) - - err = postgres.CheckSyntaxReplaceDollar(got) - assert.NoErrorf(t, err, "postgres syntax check failed: %s", err) - }) - } -} - -// removeWhitespace removes all whitespace characters from a string. -func removeWhitespace(s string) string { - return strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return -1 // skip this rune - } - return r - }, s) -} diff --git a/parse/sql/sqlanalyzer/typing/errors.go b/parse/sql/sqlanalyzer/typing/errors.go deleted file mode 100644 index 85f8a542f..000000000 --- a/parse/sql/sqlanalyzer/typing/errors.go +++ /dev/null @@ -1,12 +0,0 @@ -package typing - -import ( - "fmt" -) - -var ( - ErrInvalidType = fmt.Errorf("invalid type") - ErrCompoundShape = fmt.Errorf("compound shape mismatch") - errColumnNotFound = fmt.Errorf("column not found") - errAmbiguousColumn = fmt.Errorf("ambiguous column") -) diff --git a/parse/sql/sqlanalyzer/typing/relation.go b/parse/sql/sqlanalyzer/typing/relation.go deleted file mode 100644 index 2b9963f7a..000000000 --- a/parse/sql/sqlanalyzer/typing/relation.go +++ /dev/null @@ -1,169 +0,0 @@ -package typing - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/core/types" -) - -// Relation is a set of attributes. -type Relation struct { - // attributes are the attributes in the relation. - attributes map[string]*Attribute - - // OrdinalPositions tracks the ordinal positions of the attributes. - // It is used to loop through the attributes in the order they were added. - oridinalPositions []string -} - -// newRelation creates a new relation. -func newRelation() *Relation { - return &Relation{ - attributes: make(map[string]*Attribute), - oridinalPositions: []string{}, - } -} - -// Attribute returns an attribute from the relation. -// It also returns whether the attribute was found. -func (q *Relation) Attribute(name string) (*Attribute, bool) { - attr, ok := q.attributes[name] - return attr, ok -} - -// AddAttribute adds an attribute to the relation. -// If there is a conflict, it will return an error. -func (q *Relation) AddAttribute(a *QualifiedAttribute) error { - if a.Name == "" { - return fmt.Errorf("returned columns cannot be anonymous, and should be aliased") - } - - if _, ok := q.attributes[a.Name]; ok { - return fmt.Errorf(`ambiguous return column "%s"`, a.Name) - } - - q.attributes[a.Name] = a.Copy() - q.oridinalPositions = append(q.oridinalPositions, a.Name) - - return nil -} - -// Merge merges two relations. If there is a conflict, -// an error is returned. -func (q *Relation) Merge(other *Relation) error { - for _, attrName := range other.oridinalPositions { - if _, ok := q.attributes[attrName]; ok { - return fmt.Errorf("ambiguous attribute: %s", attrName) - } - - q.attributes[attrName] = other.attributes[attrName].Copy() - } - - q.oridinalPositions = append(q.oridinalPositions, other.oridinalPositions...) - - return nil -} - -// Copy returns a copy of the relation. -func (q *Relation) Copy() *Relation { - copied := make(map[string]*Attribute) - for k, v := range q.attributes { - copied[k] = v.Copy() - } - - return &Relation{ - attributes: copied, - oridinalPositions: copyArr(q.oridinalPositions), - } -} - -func copyArr(arr []string) []string { - copied := make([]string, len(arr)) - copy(copied, arr) - return copied -} - -// Loop loops through the attributes of the relation, -// in the order of their ordinal position. -// Returning an error will stop the loop. -func (q *Relation) Loop(f func(string, *Attribute) error) error { - for _, attrName := range q.oridinalPositions { - attr, ok := q.attributes[attrName] - if !ok { - panic("attribute not found during ordered loop") - } - - err := f(attrName, attr) - if err != nil { - return err - } - } - - return nil -} - -// Shape returns the shape of the relation. -func (q *Relation) Shape() []*types.DataType { - var res []*types.DataType - - err := q.Loop(func(s string, a *Attribute) error { - res = append(res, a.Type) - return nil - }) - if err != nil { - panic(err) // this will never happen since the loop function does not return an error - } - - return res -} - -// Attribute is an anonymous attribute in a relation. -type Attribute struct { - // Type is the type of the attribute. - Type *types.DataType -} - -// Copy returns a copy of the attribute. -func (a *Attribute) Copy() *Attribute { - copied := *a.Type - return &Attribute{ - Type: &copied, - } -} - -// QualifiedRelation is a relation that has a name. -// It is used for subqueries and joins. -type QualifiedRelation struct { - *Relation - Name string -} - -// QualifiedAttribute represents an attribute in a relation -type QualifiedAttribute struct { - *Attribute - Name string -} - -// tableToRelation converts a table to a relation. -// It is only used in the constructor of the visitor, -// and therefore could probably be deleted. -func tableToRelation(t *types.Table) *QualifiedRelation { - attrs := make(map[string]*Attribute) - columnNames := make([]string, len(t.Columns)) - - for i, col := range t.Columns { - attrs[col.Name] = &Attribute{ - Type: col.Type.Copy(), - } - - columnNames[i] = col.Name - } - - return &QualifiedRelation{ - Name: t.Name, - Relation: &Relation{ - attributes: attrs, - oridinalPositions: columnNames, - }, - } -} diff --git a/parse/sql/sqlanalyzer/typing/typing.go b/parse/sql/sqlanalyzer/typing/typing.go deleted file mode 100644 index baf3d69f0..000000000 --- a/parse/sql/sqlanalyzer/typing/typing.go +++ /dev/null @@ -1,290 +0,0 @@ -package typing - -import ( - "errors" - "fmt" - "runtime" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// AnalyzeOptions is a set of options for type analysis. -type AnalyzeOptions struct { - // BindParams are the bind parameters for the statement. - BindParams map[string]*types.DataType - // ArbitraryBinds will treat all bind parameters as unknown, - // effectively disabling type checking for them. - ArbitraryBinds bool - // Qualify will qualify all column references in the statement. - Qualify bool - // VerifyProcedures will verify procedure calls in the statement. - VerifyProcedures bool - // Schema is the current database schema. - Schema *types.Schema - // ErrorListener is the error listener for the statement. - ErrorListener parseTypes.NativeErrorListener -} - -// AnalyzeTypes will run type analysis on the given statement. -// It will return the relation that will be returned by the statement, -// if any. -func AnalyzeTypes(ast tree.AstNode, tables []*types.Table, options *AnalyzeOptions) (rel *Relation, err error) { - defer func() { - if r := recover(); r != nil { - var ok bool - err, ok = r.(error) - if !ok { - err = fmt.Errorf("%v", r) - } else { - err = fmt.Errorf("%w", err) - } - - // add stack trace since this is a bug: - buf := make([]byte, 1<<16) - stackSize := runtime.Stack(buf, false) - err = fmt.Errorf("%w\n%s", err, buf[:stackSize]) - } - }() - - if options == nil { - options = &AnalyzeOptions{ - BindParams: make(map[string]*types.DataType), - Schema: &types.Schema{}, - } - } - if options.ErrorListener == nil { - options.ErrorListener = parseTypes.NewErrorListener() - } - - tbls := make(map[string]*Relation) - for _, t := range tables { - r := tableToRelation(t) - tbls[t.Name] = r.Relation - } - - v := &typeVisitor{ - commonTables: tbls, - ctes: make(map[string]struct{}), - AnalyzeOptions: options, - } - - res := ast.Accept(v) - fn, ok := res.(returnFunc) - if !ok { - return nil, fmt.Errorf("unknown error: could not analyze types") - } - - rel = fn(newEvaluationContext()) - return rel, nil -} - -// evaluationContext is a context for evaluating expressions. -// It provides info on the available tables and bind parameters. -// Unlike the visitor, which holds all available tables, the -// context only holds tables that have been joined and are -// accessible in the current scope. -type evaluationContext struct { - // joinedTables are tables that have been joined in the current scope. - joinedTables map[string]*Relation - // joinOrder is the order in which tables have been joined. - // it matches the keys in joinedTables. - joinOrder []string - - // outerTables are tables that are accessible in the outer scope. - // they are not recorded in the joinOrder. - outerTables map[string]*Relation -} - -// findColumn finds a column in the joined tables. -// If the specified table is empty, it will loop through -// all tables to find the column. -// If it does not find the column, or finds several -// columns with the same name, it will return an error. -// It returns the relation the column is from, and the column itself. -func (e *evaluationContext) findColumn(table, column string) (fromRelation string, attribute *QualifiedAttribute, err error) { - if table != "" { - cols, ok := e.joinedTables[table] - if !ok { - // check outer tables - cols, ok = e.outerTables[table] - if !ok { - return "", nil, fmt.Errorf("table %s not found", table) - } - } - - c, ok := cols.Attribute(column) - if !ok { - return "", nil, fmt.Errorf("column %s not found in table %s", column, table) - } - - return table, &QualifiedAttribute{ - Name: column, - Attribute: c, - }, nil - } - - // if table is empty, loop through all tables - var found bool - var foundValue *QualifiedAttribute - var foundTable string - for tbl, cols := range e.joinedTables { - t, ok := cols.Attribute(column) - if !ok { - continue - } - - if found { - return "", nil, fmt.Errorf(`%w: "%s"`, errAmbiguousColumn, column) - } - - found = true - foundValue = &QualifiedAttribute{ - Name: column, - Attribute: t, - } - foundTable = tbl - } - if !found { - return "", nil, fmt.Errorf(`%w: "%s"`, errColumnNotFound, column) - } - - return foundTable, foundValue, nil -} - -// join joins new relations to the evaluation context. -// If there is a conflicting tabe name, it will return an error. -// If no table name is specified, it will be joined anonymously. -// Column conflicts in anonymous tables will return an error. -func (e *evaluationContext) join(relation *QualifiedRelation) error { - if relation.Name == "" { - // ensure an anonymous relation already exists - if _, ok := e.joinedTables[""]; !ok { - // if it does not exist, create it and add it to the join order - e.joinedTables[""] = newRelation() - e.joinOrder = append(e.joinOrder, "") - } - - return e.joinedTables[""].Merge(relation.Relation) - } - - if _, ok := e.joinedTables[relation.Name]; ok { - return fmt.Errorf("conflicting table name: %s", relation.Name) - } - if _, ok := e.outerTables[relation.Name]; ok { - return fmt.Errorf("conflicting table name: %s", relation.Name) - } - - e.joinedTables[relation.Name] = relation.Relation.Copy() - e.joinOrder = append(e.joinOrder, relation.Name) - - return nil -} - -// mergeAnonymousSafe merges an anonymous relation into the current scope. -// it is like joining, but if there is a naming conflict where the type -// of the column is the same, it will not return an error. It will not merge columns that -// make the relation ambiguous. -func (e *evaluationContext) mergeAnonymousSafe(relation *Relation) error { - anonTbl, ok := e.joinedTables[""] - if !ok { - anonTbl = newRelation() - e.joinedTables[""] = anonTbl - } - - // for each column in the new table, check if it is already in ANY - // of the tables. If not, add it. If so, ensure the types - // are the same. - return relation.Loop(func(s string, a *Attribute) error { - _, attr, err := e.findColumn("", s) - // if no error, then the column exists, so check the type - if err == nil { - if !attr.Type.Equals(a.Type) { - return fmt.Errorf("conflicting column type in ambiguous column: %s", s) - } - return nil - } - // if the column is not found, add it - if errors.Is(err, errColumnNotFound) { - return anonTbl.AddAttribute(&QualifiedAttribute{ - Name: s, - Attribute: a, - }) - } - // if it is ambiguous, then it already exists, so - // we can ignore it - if errors.Is(err, errAmbiguousColumn) { - return nil - } - - return err - }) -} - -// loop loops through the joined tables in the evaluation context, -// in the order they were joined. -// Returning an error will stop the loop. -func (e *evaluationContext) Loop(f func(string, *Relation) error) error { - for _, table := range e.joinOrder { - t, ok := e.joinedTables[table] - if !ok { - panic("table not found during ordered loop") - } - - err := f(table, t) - if err != nil { - return err - } - } - - return nil -} - -// scope returns a new evaluation context, and moves all joined tables -// to the outerTables map. This is useful for subqueries, where the -// inner scope should not affect the outer scope. -func (e *evaluationContext) scope() *evaluationContext { - newTables := make(map[string]*Relation) - for k, v := range e.joinedTables { - newTables[k] = v.Copy() - } - - for k, v := range e.outerTables { - newTables[k] = v.Copy() - } - - return &evaluationContext{ - joinedTables: make(map[string]*Relation), - joinOrder: []string{}, - outerTables: newTables, - } -} - -// copy returns a copy of the evaluation context. -func (e *evaluationContext) copy() *evaluationContext { - newTables := make(map[string]*Relation) - for k, v := range e.joinedTables { - newTables[k] = v.Copy() - } - - outerTables := make(map[string]*Relation) - for k, v := range e.outerTables { - outerTables[k] = v.Copy() - } - - return &evaluationContext{ - joinedTables: newTables, - joinOrder: append([]string{}, e.joinOrder...), - outerTables: outerTables, - } - -} - -func newEvaluationContext() *evaluationContext { - return &evaluationContext{ - joinedTables: make(map[string]*Relation), - joinOrder: []string{}, - outerTables: make(map[string]*Relation), - } -} diff --git a/parse/sql/sqlanalyzer/typing/visitor.go b/parse/sql/sqlanalyzer/typing/visitor.go deleted file mode 100644 index 4ccfecc04..000000000 --- a/parse/sql/sqlanalyzer/typing/visitor.go +++ /dev/null @@ -1,1215 +0,0 @@ -package typing - -import ( - "errors" - "fmt" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/kwilteam/kwil-db/parse/util" -) - -type typeVisitor struct { - *tree.BaseAstVisitor - // commonTables are tables that are globally available. - // these are either tables that have been defined in the schema, - // or common table expressions. - // they are defined at the beginning of the query, and do not - // change. - commonTables map[string]*Relation - // ctes is a set of common table expressions that have been defined. - // all of the keys can be found in commonTables. - ctes map[string]struct{} - *AnalyzeOptions -} - -var _ tree.AstVisitor = &typeVisitor{} - -// evalFunc is a function that allows modifying an evaluation context. -type evalFunc func(e *evaluationContext) - -// BEGIN evalFunc - -func (t *typeVisitor) VisitCTE(p0 *tree.CTE) any { - return evalFunc(func(e *evaluationContext) { - relation := p0.Select.Accept(t).(returnFunc)(e) - - _, ok := t.commonTables[p0.Table] - if ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("common table expression conflicts with existing table %s", p0.Table)) - return - } - - t.commonTables[p0.Table] = relation - t.ctes[p0.Table] = struct{}{} - }) -} - -func (t *typeVisitor) VisitRelationJoin(p0 *tree.RelationJoin) any { - return evalFunc(func(e *evaluationContext) { - p0.Relation.Accept(t).(evalFunc)(e) - for _, join := range p0.Joins { - join.Accept(t).(evalFunc)(e) - } - }) -} - -func (t *typeVisitor) VisitRelationSubquery(p0 *tree.RelationSubquery) any { - return evalFunc(func(e *evaluationContext) { - r := p0.Select.Accept(t).(returnFunc)(e) - - err := e.join(&QualifiedRelation{ - Name: p0.Alias, // this can be "" - Relation: r, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -func (t *typeVisitor) VisitRelationFunction(p0 *tree.RelationFunction) any { - // check the function is a procedure that returns a table, and has the same - // number of inputs as the function has parameters - return evalFunc(func(e *evaluationContext) { - // we can ignore the attribute here, we simply want to make sure we visit - p0.Function.Accept(t).(attributeFn)(e) - - parameters, returns, err := util.FindProcOrForeign(t.Schema, p0.Function.Function) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return - } - - if len(p0.Function.Inputs) != len(parameters) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("procedure %s expected %d inputs, received %d", p0.Function.Function, len(parameters), len(p0.Function.Inputs))) - return - } - - for i, in := range p0.Function.Inputs { - attr := in.Accept(t).(attributeFn)(e) - - if !attr.Type.Equals(parameters[i]) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("procedure %s expected input %d to be %s, received %s", p0.Function.Function, i, parameters[i].String(), attr.Type.String())) - // we don't have to return here, we can continue to check the return type - } - } - - if returns == nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("procedure %s does not return a table", p0.Function.Function)) - return - } - if !returns.IsTable { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("procedure %s does not return a table", p0.Function.Function)) - return - } - - rel := newRelation() - for _, retCol := range returns.Fields { - err := rel.AddAttribute(&QualifiedAttribute{ - Name: retCol.Name, - Attribute: &Attribute{ - Type: retCol.Type, - }, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return - } - } - - // add the relation to the context - err = e.join(&QualifiedRelation{ - Name: p0.Alias, - Relation: rel, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -func (t *typeVisitor) VisitRelationTable(p0 *tree.RelationTable) any { - return evalFunc(func(e *evaluationContext) { - tbl, ok := t.commonTables[p0.Name] - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("table %s not found", p0.Name)) - return - } - - name := p0.Name - if p0.Alias != "" { - name = p0.Alias - } - - err := e.join(&QualifiedRelation{ - Name: name, - Relation: tbl, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -// the rest of the evalFunc visitors do not actually modify the evaluation context - -func (t *typeVisitor) VisitUpsert(p0 *tree.Upsert) any { - return evalFunc(func(e *evaluationContext) { - if p0.ConflictTarget != nil { - p0.ConflictTarget.Accept(t).(evalFunc)(e) - } - - for _, set := range p0.Updates { - set.Accept(t).(evalFunc)(e) - } - - if p0.Where != nil { - attr := p0.Where.Accept(t).(attributeFn)(e) - - if !attr.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("where clause must evaluate to boolean. Received: %s", attr.Type.String())) - return - } - } - }) -} - -func (t *typeVisitor) VisitUpdateSetClause(p0 *tree.UpdateSetClause) any { - return evalFunc(func(e *evaluationContext) { - // check that the columns exist - // we can only update columns in the first table - if len(e.joinOrder) == 0 { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("no table to update")) - return - } - for _, col := range p0.Columns { - _, _, err := e.findColumn(e.joinOrder[0], col) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return - } - } - - if p0.Expression != nil { - // we can disregard the attribute here, we just want to visit - p0.Expression.Accept(t).(attributeFn)(e) - } - }) -} - -func (t *typeVisitor) VisitConflictTarget(p0 *tree.ConflictTarget) any { - return evalFunc(func(e *evaluationContext) { - // check that the columns exist - if len(e.joinOrder) == 0 { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("no table to update")) - return - } - for _, col := range p0.IndexedColumns { - _, _, err := e.findColumn(e.joinOrder[0], col) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return - } - } - - if p0.Where != nil { - attr := p0.Where.Accept(t).(attributeFn)(e) - - if !attr.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("where clause must evaluate to boolean. Received: %s", attr.Type.String())) - } - } - }) -} - -func (t *typeVisitor) VisitLimit(p0 *tree.Limit) any { - return evalFunc(func(e *evaluationContext) { - if p0.Expression != nil { - limit := p0.Expression.Accept(t).(attributeFn)(e) - - if !limit.Type.Equals(types.IntType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("limit must be an integer. Received: %s", limit.Type.String())) - // we can continue here, since this will not affect future evaluation - } - } - - if p0.Offset != nil { - offset := p0.Offset.Accept(t).(attributeFn)(e) - - if !offset.Type.Equals(types.IntType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("offset must be an integer. Received: %s", offset.Type.String())) - } - } - }) -} - -func (t *typeVisitor) VisitOrderBy(p0 *tree.OrderBy) any { - return evalFunc(func(e *evaluationContext) { - for _, term := range p0.OrderingTerms { - term.Accept(t).(evalFunc)(e) - } - }) -} - -func (t *typeVisitor) VisitOrderingTerm(p0 *tree.OrderingTerm) any { - return evalFunc(func(e *evaluationContext) { - if p0.Expression == nil { - return // not sure if this is possible, don't believe it is - } - p0.Expression.Accept(t).(attributeFn)(e) - }) -} - -func (t *typeVisitor) VisitGroupBy(p0 *tree.GroupBy) any { - return evalFunc(func(e *evaluationContext) { - for _, col := range p0.Expressions { - col.Accept(t).(attributeFn)(e) - } - - if p0.Having != nil { - attr := p0.Having.Accept(t).(attributeFn)(e) - - if !attr.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("having clause must be boolean. Received: %s", attr.Type.String())) - return - } - } - }) -} - -func (t *typeVisitor) VisitJoinPredicate(p0 *tree.JoinPredicate) any { - return evalFunc(func(e *evaluationContext) { - p0.Table.Accept(t).(evalFunc)(e) - - if p0.Constraint != nil { - r := p0.Constraint.Accept(t).(attributeFn)(e) - - if !r.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("join constraint must be boolean. Received: %s", r.Type.String())) - } - } - }) -} - -// END evalFunc - -// attributeFn is returned from all visitor expressions. -// It allows us to evaluate return attributes once we -// have more context. -// The attribute name can be blank, and will only be set -// if the expression is a column. -type attributeFn func(ev *evaluationContext) *QualifiedAttribute - -// BEGIN attributeFn - -func (t *typeVisitor) VisitExpressionArithmetic(p0 *tree.ExpressionArithmetic) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - left := p0.Left.Accept(t).(attributeFn) - right := p0.Right.Accept(t).(attributeFn) - - at := left(ev) - if !at.Type.Equals(types.IntType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("arithmetic expression expected int. Received: %s", at.Type.String())) - return unknownAttr() - } - - bt := right(ev) - if !bt.Type.Equals(types.IntType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("arithmetic expression expected int. Received: %s", bt.Type.String())) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.IntType) - }) -} - -func (t *typeVisitor) VisitExpressionBetween(p0 *tree.ExpressionBetween) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - expr := p0.Expression.Accept(t).(attributeFn) - left := p0.Left.Accept(t).(attributeFn) - right := p0.Right.Accept(t).(attributeFn) - - et := expr(ev) - - lt := left(ev) - - rt := right(ev) - - if !et.Type.Equals(lt.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("between expression expected %s. Received: %s", et.Type.Name, lt.Type.String())) - return unknownAttr() - } - - if !et.Type.Equals(rt.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("between expression expected %s. Received: %s", et.Type.Name, rt.Type.String())) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BoolType) - }) -} - -func (t *typeVisitor) VisitExpressionBinaryComparison(p0 *tree.ExpressionBinaryComparison) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - left := p0.Left.Accept(t).(attributeFn) - right := p0.Right.Accept(t).(attributeFn) - - at := left(ev) - bt := right(ev) - - if !at.Type.Equals(bt.Type) { - t.ErrorListener.NodeErr(parseTypes.MergeNodes(p0.Left.GetNode(), p0.Right.GetNode()), parseTypes.ParseErrorTypeType, fmt.Errorf("cannot compare types: left: %s right: %s", at.Type.String(), bt.Type.String())) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BoolType) - }) -} - -func (t *typeVisitor) VisitExpressionBindParameter(p0 *tree.ExpressionBindParameter) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - c, ok := t.BindParams[p0.Parameter] - if !ok { - if t.ArbitraryBinds { - c = types.UnknownType - } else { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("bind parameter %s not found", util.UnformatParameterName(p0.Parameter))) - return unknownAttr() - } - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(c) - }) -} - -func (t *typeVisitor) VisitExpressionCase(p0 *tree.ExpressionCase) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - // whenTypes must always be bool, unless there is a case expression - // If a case expression is present, then when clause must be the same type as the case expression - expectedWhenType := types.BoolType - if p0.CaseExpression != nil { - c := p0.CaseExpression.Accept(t).(attributeFn) - ct := c(ev) - - expectedWhenType = ct.Type - } - - var neededType *types.DataType - - for _, w := range p0.WhenThenPairs { - when := w[0].Accept(t).(attributeFn) - whenType := when(ev) - - if !whenType.Type.Equals(expectedWhenType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("when clause expected %s. Received: %s", expectedWhenType.String(), whenType.Type.String())) - return unknownAttr() - } - - then := w[1].Accept(t).(attributeFn) - thenType := then(ev) - - if neededType == nil { - neededType = thenType.Type - } - - if !neededType.Equals(thenType.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("all THEN types must be the same. Received: %s and %s", neededType.String(), thenType.Type.String())) - return unknownAttr() - } - } - - if p0.ElseExpression != nil { - e := p0.ElseExpression.Accept(t).(attributeFn) - eType := e(ev) - - if !neededType.Equals(eType.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("ELSE type must match THEN type. Received: %s and %s", neededType.String(), eType.Type.String())) - return unknownAttr() - } - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(neededType) - }) -} - -func (t *typeVisitor) VisitExpressionCollate(p0 *tree.ExpressionCollate) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - rel := p0.Expression.Accept(t).(attributeFn)(ev) - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return rel - }) -} - -func (t *typeVisitor) VisitExpressionColumn(p0 *tree.ExpressionColumn) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - // if table is not qualified, we will attempt to qualify, and return an error on ambiguity - tbl, col, err := ev.findColumn(p0.Table, p0.Column) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return unknownAttr() - } - - if p0.Table == "" && t.Qualify { - p0.Table = tbl // this will modify the statement - } - - if p0.TypeCast != nil { - return &QualifiedAttribute{ - Name: p0.Column, - Attribute: &Attribute{ - Type: p0.TypeCast, - }, - } - } - - return col - }) -} - -func (t *typeVisitor) VisitExpressionFunction(p0 *tree.ExpressionFunction) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - funcDef, ok := metadata.Functions[p0.Function] - if !ok { - // can be a procedure/foreign procedure - params, returns, err := util.FindProcOrForeign(t.Schema, p0.Function) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return unknownAttr() - } - - if len(p0.Inputs) != len(params) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("procedure %s expected %d inputs, received %d", p0.Function, len(params), len(p0.Inputs))) - return unknownAttr() - } - - for i, in := range p0.Inputs { - attr := in.Accept(t).(attributeFn)(ev) - - if !attr.Type.Equals(params[i]) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("procedure %s expected input %d to be %s, received %s", p0.Function, i, params[i].String(), attr.Type.String())) - return unknownAttr() - } - } - - if returns == nil { - return anonAttr(types.NullType) - } - - if returns.IsTable { - return anonAttr(types.NullType) - } - - if len(returns.Fields) != 1 { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("procedure %s must return exactly one column", p0.Function)) - return unknownAttr() - } - - return anonAttr(returns.Fields[0].Type) - } - - var argTypes []*types.DataType - for _, arg := range p0.Inputs { - attr := arg.Accept(t).(attributeFn)(ev) - argTypes = append(argTypes, attr.Type) - } - - returnType, err := funcDef.ValidateArgs(argTypes) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, err) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(returnType) - }) -} - -func (t *typeVisitor) VisitExpressionIs(p0 *tree.ExpressionIs) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - l := p0.Left.Accept(t).(attributeFn) - r := p0.Right.Accept(t).(attributeFn) - - lt := l(ev) - - rt := r(ev) - - if !lt.Type.Equals(rt.Type) && !lt.Type.Equals(types.NullType) && !rt.Type.Equals(types.NullType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("is expression expected %s. Received: %s", lt.Type.String(), rt.Type.String())) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BoolType) - }) -} - -func (t *typeVisitor) VisitExpressionList(p0 *tree.ExpressionList) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - var lastType *types.DataType - for _, e := range p0.Expressions { - et := e.Accept(t).(attributeFn) - etType := et(ev) - - if lastType == nil { - lastType = etType.Type - continue - } - - if !lastType.Equals(etType.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("expression list expected %s. Received: %s", lastType.String(), etType.Type.String())) - return unknownAttr() - } - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(lastType) - }) -} - -func (t *typeVisitor) VisitExpressionTextLiteral(p0 *tree.ExpressionTextLiteral) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.TextType) - }) -} - -func (t *typeVisitor) VisitExpressionNumericLiteral(p0 *tree.ExpressionNumericLiteral) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.IntType) - }) -} - -func (t *typeVisitor) VisitExpressionBooleanLiteral(p0 *tree.ExpressionBooleanLiteral) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BoolType) - }) -} - -func (t *typeVisitor) VisitExpressionNullLiteral(p0 *tree.ExpressionNullLiteral) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.NullType) - }) -} - -func (t *typeVisitor) VisitExpressionBlobLiteral(p0 *tree.ExpressionBlobLiteral) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BlobType) - }) -} - -func (t *typeVisitor) VisitExpressionSelect(p0 *tree.ExpressionSelect) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - r := p0.Select.Accept(t).(returnFunc)(ev) - - shape := r.Shape() - if len(shape) != 1 && !p0.IsExists { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("subquery must return exactly one column")) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - if p0.IsExists { - return anonAttr(types.BoolType) - } - - return anonAttr(shape[0]) - }) -} - -func (t *typeVisitor) VisitExpressionStringCompare(p0 *tree.ExpressionStringCompare) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - a := p0.Left.Accept(t).(attributeFn) - b := p0.Right.Accept(t).(attributeFn) - - // do these both need to be text? I believe so - at := a(ev) - bt := b(ev) - - if !at.Type.Equals(bt.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("string comparison expression expected %s. Received: %s", at.Type.String(), bt.Type.String())) - return unknownAttr() - } - - if p0.Escape != nil { - esc := p0.Escape.Accept(t).(attributeFn) - et := esc(ev) - - if !et.Type.Equals(types.TextType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("string comparison escape expected text. Received: %s", et.Type.String())) - return unknownAttr() - } - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.BoolType) - }) -} - -func (t *typeVisitor) VisitExpressionUnary(p0 *tree.ExpressionUnary) any { - return attributeFn(func(ev *evaluationContext) *QualifiedAttribute { - o := p0.Operand.Accept(t).(attributeFn) - ot := o(ev) - - if !ot.Type.Equals(types.IntType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeType, fmt.Errorf("unary expression expected int. Received: %s", ot.Type.String())) - return unknownAttr() - } - - if p0.TypeCast != nil { - return anonAttr(p0.TypeCast) - } - - return anonAttr(types.IntType) - }) -} - -// anonAttr is a helper function that creates an anonymous attribute -func anonAttr(t *types.DataType) *QualifiedAttribute { - return &QualifiedAttribute{ - Attribute: &Attribute{ - Type: t, - }, - } -} - -// unknownAttr returns an unknown attribute. -// It should be used to avoid nil pointer dereferences. -func unknownAttr() *QualifiedAttribute { - return anonAttr(types.UnknownType) -} - -// END attributeFn - -// returnFunc if a function that returns a relation. -// it is returned from INSERT, UPDATE, DELETE, and SELECT cores -// and stmts, as well as SimpleSelects. -type returnFunc func(e *evaluationContext) *Relation - -// BEGIN returnFunc - -func (t *typeVisitor) VisitInsertStmt(p0 *tree.InsertStmt) any { - return returnFunc(func(e *evaluationContext) *Relation { - for _, cte := range p0.CTE { - cte.Accept(t).(evalFunc)(e) - } - - return p0.Core.Accept(t).(returnFunc)(e) - }) -} - -func (t *typeVisitor) VisitInsertCore(p0 *tree.InsertCore) any { - return returnFunc(func(e *evaluationContext) *Relation { - // we only search the visitor for the table, - // since contextual table (such as CTEs) cannot be - // inserted into. - tbl, ok := t.commonTables[p0.Table] - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("table %s not found", p0.Table)) - return newRelation() - } - - _, ok = t.ctes[p0.Table] - if ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("cannot insert into common table expression %s", p0.Table)) - return newRelation() - } - - // check that the columns exist - for _, col := range p0.Columns { - _, ok := tbl.Attribute(col) - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("column %s not found", col)) - return newRelation() - } - } - - // Postgres has a weird quirk with inserts: - // tables can be aliased (e.g. insert into foo as bar), - // but bar cannot be used in a subquery in the insert statement, - // while foo can. The alias is only useable in the returning clause. - // Therefore, we will not add the alias to the context. - for _, row := range p0.Values { - if len(row) != len(p0.Columns) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("mismatched column/value count")) - return newRelation() - } - - for i, val := range row { - attr := val.Accept(t).(attributeFn)(e) - - expectedAttr, ok := tbl.Attribute(p0.Columns[i]) - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("unknown column %s", p0.Columns[i])) - return newRelation() - } - - if !expectedAttr.Type.Equals(attr.Type) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s: type mismatch for column %s", ErrInvalidType.Error(), p0.Columns[i])) - return newRelation() - } - } - } - - // common table expressions cannot be returned - // we want a new context that only has this table - - name := p0.Table - if p0.TableAlias != "" { - name = p0.TableAlias - } - - e2 := e.scope() - - err := e2.join(&QualifiedRelation{ - Name: name, - Relation: tbl, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return newRelation() - } - - // similar to values, aliased insert tables cannot be used in the - // conflict target or set clause. We will not add the alias to the context. - if p0.Upsert != nil { - p0.Upsert.Accept(t).(evalFunc)(e2) - } - - // handle returning: - - if p0.ReturningClause == nil { - return newRelation() - } - - result := newRelation() - - p0.ReturningClause.Accept(t).(resultFunc)(e2, result) - - return result - }) -} - -func (t *typeVisitor) VisitUpdateStmt(p0 *tree.UpdateStmt) any { - return returnFunc(func(e *evaluationContext) *Relation { - for _, cte := range p0.CTE { - cte.Accept(t).(evalFunc)(e) - } - - return p0.Core.Accept(t).(returnFunc)(e) - }) -} - -func (t *typeVisitor) VisitUpdateCore(p0 *tree.UpdateCore) any { - return returnFunc(func(e *evaluationContext) *Relation { - tbl, ok := t.commonTables[p0.QualifiedTableName.TableName] - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("unknown table %s", p0.QualifiedTableName.TableName)) - return newRelation() - } - - _, ok = t.ctes[p0.QualifiedTableName.TableName] - if ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("cannot update common table expression %s", p0.QualifiedTableName.TableName)) - return newRelation() - } - - name := p0.QualifiedTableName.TableName - if p0.QualifiedTableName.TableAlias != "" { - name = p0.QualifiedTableName.TableAlias - } - - // we now want to update our context with joined relations since they can - // be accessed in both the set clause and the where clause - e2 := e.scope() - - err := e2.join(&QualifiedRelation{ - Name: name, - Relation: tbl, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return newRelation() - } - - if p0.From != nil { - p0.From.Accept(t).(evalFunc)(e2) - - for _, set := range p0.UpdateSetClause { - set.Accept(t).(evalFunc)(e2) - } - } - - if p0.Where != nil { - whereType := p0.Where.Accept(t).(attributeFn)(e2) - - if !whereType.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s: where clause must be boolean. Got %s", ErrInvalidType.Error(), whereType.Type.String())) - return newRelation() - } - } - - if p0.Returning == nil { - return newRelation() - } - - result := newRelation() - - p0.Returning.Accept(t).(resultFunc)(e2, result) - - return result - }) -} - -func (t *typeVisitor) VisitDeleteStmt(p0 *tree.DeleteStmt) any { - return returnFunc(func(e *evaluationContext) *Relation { - for _, cte := range p0.CTE { - cte.Accept(t).(evalFunc)(e) - } - - return p0.Core.Accept(t).(returnFunc)(e) - }) -} - -func (t *typeVisitor) VisitDeleteCore(p0 *tree.DeleteCore) any { - return returnFunc(func(e *evaluationContext) *Relation { - tbl, ok := t.commonTables[p0.QualifiedTableName.TableName] - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("unknown table %s", p0.QualifiedTableName.TableName)) - return newRelation() - } - - _, ok = t.ctes[p0.QualifiedTableName.TableName] - if ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("cannot delete from common table expression %s", p0.QualifiedTableName.TableName)) - return newRelation() - } - - name := p0.QualifiedTableName.TableName - if p0.QualifiedTableName.TableAlias != "" { - name = p0.QualifiedTableName.TableAlias - } - - // we want to use the new context within the where clause - // DELETE can use the alias in both the where clause and the returning clause - e2 := e.scope() - err := e2.join(&QualifiedRelation{ - Name: name, - Relation: tbl, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return newRelation() - } - - if p0.Where != nil { - whereType := p0.Where.Accept(t).(attributeFn)(e2) - - if !whereType.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s, where clause must be boolean. Got %s", ErrInvalidType.Error(), whereType.Type.String())) - return newRelation() - } - } - - if p0.Returning == nil { - return newRelation() - } - - result := newRelation() - - p0.Returning.Accept(t).(resultFunc)(e2, result) - return result - }) -} - -func (t *typeVisitor) VisitSelectStmt(p0 *tree.SelectStmt) any { - return returnFunc(func(e *evaluationContext) *Relation { - for _, cte := range p0.CTE { - cte.Accept(t).(evalFunc)(e) - } - - return p0.Stmt.Accept(t).(returnFunc)(e) - }) -} - -func (t *typeVisitor) VisitSelectCore(p0 *tree.SelectCore) any { - return returnFunc(func(e *evaluationContext) *Relation { - // we make a new scope so that we can join the tables - // without affecting the outer scope - e2 := e.scope() - // we need to ensure that the relations all have the same shape - res := p0.SimpleSelects[0].Accept(t).(returnFunc)(e2) - - expectedShape := res.Shape() - - for _, sel := range p0.SimpleSelects[1:] { - // we create a separate scope for each select. - selectCtx := e.scope() - r := sel.Accept(t).(returnFunc)(selectCtx) - - shape := r.Shape() - - if len(shape) != len(expectedShape) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s: compound selects must return the same number of columns. Expected %d. Received: %d", ErrCompoundShape.Error(), len(expectedShape), len(shape))) - return newRelation() - } - - for i, col := range shape { - if !col.Equals(expectedShape[i]) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s: compound selects must return the same types: Expected %s Received: %s", ErrCompoundShape.Error(), expectedShape[i].Name, col.Name)) - return newRelation() - } - } - } - - // if this is a compound select, the joined tables from the selects are not in scope, and - // we must instead join an anonymous relation that is the compound select. - // if there is only one select, we can reference the joined tables. - /* example query: - SELECT * FROM ( - SELECT id FROM foo - UNION - SELECT id FROM bar - ) - ORDER BY id - ) - */ - var e3 *evaluationContext - if len(p0.SimpleSelects) > 1 { - // copy in case we are in a correlated subquery - e3 = e.copy() - - // we need to add the first returned relation anonymously to the context - // so that we can use it in the ordering and limit - err := e3.join(&QualifiedRelation{ - Name: "", - Relation: res, - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return newRelation() - } - } else { - e3 = e2 - } - - if p0.OrderBy != nil { - p0.OrderBy.Accept(t).(evalFunc)(e3) - } - - if p0.Limit != nil { - p0.Limit.Accept(t).(evalFunc)(e3) - } - - return res - }) -} - -func (t *typeVisitor) VisitSimpleSelect(p0 *tree.SimpleSelect) any { - return returnFunc(func(e *evaluationContext) *Relation { - if p0.From != nil { - // we need to build the evaluation context based on the relation - p0.From.Accept(t).(evalFunc)(e) - } - - if p0.Where != nil { - a := p0.Where.Accept(t).(attributeFn)(e) - if !a.Attribute.Type.Equals(types.BoolType) { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("%s: where clause must be boolean", ErrInvalidType.Error())) - return newRelation() - } - } - - // make an empty relation for the result - result := newRelation() - - // apply the result columns - for _, col := range p0.Columns { - col.Accept(t).(resultFunc)(e, result) - } - - if p0.GroupBy != nil { - // group by context is a very weird case in postgres. - // It can reference all joined tables, and can use both aliases - // and unaliased columns. We therefore need to create a new context - // that contains all of the old tables, with the aliases added - // anonymously. - - e2 := e.copy() - err := e2.mergeAnonymousSafe(result) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - return newRelation() - } - - p0.GroupBy.Accept(t).(evalFunc)(e2) - } - - return result - }) -} - -// END returnFunc - -// resultFunc is a function that allows modifying a relation -// that will be returned by a relationFunc. -// It returned from ResultColumns and Returning Clauses. -// ResultColumns define the return relation from a SELECT, -// and Returning Clauses define the return relation from -// INSERT, UPDATE, and DELETE (if there is a RETURNING clause). -type resultFunc func(e *evaluationContext, r *Relation) - -// BEGIN resultFunc - -func (t *typeVisitor) VisitResultColumnExpression(p0 *tree.ResultColumnExpression) any { - return resultFunc(func(e *evaluationContext, r *Relation) { - c := p0.Expression.Accept(t).(attributeFn) - val := c(e) - - if p0.Alias != "" { - val.Name = p0.Alias - } - - err := r.AddAttribute(val) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -func (t *typeVisitor) VisitResultColumnStar(p0 *tree.ResultColumnStar) any { - return resultFunc(func(e *evaluationContext, r *Relation) { - err := e.Loop(func(_ string, r2 *Relation) error { - return r.Merge(r2) - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -func (t *typeVisitor) VisitResultColumnTable(p0 *tree.ResultColumnTable) any { - return resultFunc(func(e *evaluationContext, r *Relation) { - tbl, ok := e.joinedTables[p0.TableName] - if !ok { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, fmt.Errorf("table %s not found", p0.TableName)) - return - } - - err := r.Merge(tbl) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -func (t *typeVisitor) VisitReturningClause(p0 *tree.ReturningClause) any { - return resultFunc(func(e *evaluationContext, r *Relation) { - for _, col := range p0.Returned { - col.Accept(t).(resultFunc)(e, r) - } - }) -} - -func (t *typeVisitor) VisitReturningClauseColumn(p0 *tree.ReturningClauseColumn) any { - return resultFunc(func(e *evaluationContext, r *Relation) { - // this can either be return * or return expr - - // case 1: return *, preserving order - if p0.All { - err := e.Loop(func(_ string, r2 *Relation) error { - return r.Merge(r2) - }) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - - return - } - - if p0.Expression == nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, errors.New("invalid returning clause")) - return - } - - // case 2: return expr - attribute := p0.Expression.Accept(t).(attributeFn)(e) - - // attempt to set the alias - // if the attribute is not from a column, - // and there is no alias, this will fail, - // as the attribute will be anonymous - // and therefore not accessible in the - // returned relation. - if p0.Alias != "" { - attribute.Name = p0.Alias - } - - err := r.AddAttribute(attribute) - if err != nil { - t.ErrorListener.NodeErr(p0.GetNode(), parseTypes.ParseErrorTypeSemantic, err) - } - }) -} - -// END resultFunc diff --git a/parse/sql/sqlanalyzer/typing/visitor_test.go b/parse/sql/sqlanalyzer/typing/visitor_test.go deleted file mode 100644 index 89721c8aa..000000000 --- a/parse/sql/sqlanalyzer/typing/visitor_test.go +++ /dev/null @@ -1,494 +0,0 @@ -package typing_test - -import ( - "errors" - "strings" - "testing" - "unicode" - - "github.com/kwilteam/kwil-db/core/types" - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/typing" - "github.com/kwilteam/kwil-db/parse/sql/tree" - parseTypes "github.com/kwilteam/kwil-db/parse/types" - "github.com/stretchr/testify/require" -) - -// Test_Qualification tests that the qualification of column references works as expected. -func Test_Qualification(t *testing.T) { - type testcase struct { - name string - stmt string - want string - wantErr bool - } - - tests := []testcase{ - { - name: "simple select", - stmt: "SELECT id, name FROM users WHERE name = 'satoshi' ORDER BY id LIMIT 10 OFFSET 10;", - want: `SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."name" = 'satoshi' ORDER BY "users"."id" LIMIT 10 OFFSET 10;`, - }, - { - name: "joins", - stmt: `SELECT u1.id, u2.name FROM users AS u1 - INNER JOIN users AS u2 ON u1.id = u2.id - WHERE u1.id = $id AND u2.name = $name;`, - want: `SELECT "u1"."id", "u2"."name" FROM "users" AS "u1" - INNER JOIN "users" AS "u2" ON "u1"."id" = "u2"."id" - WHERE "u1"."id" = $id AND "u2"."name" = $name;`, - }, - { - name: "joins against subquery", - stmt: `SELECT u1.id, u2.username FROM users AS u1 - INNER JOIN (SELECT id, name as username FROM users WHERE id = $id) AS u2 ON u1.id = u2.id - WHERE u1.id = $id AND u2.username = $name;`, - want: `SELECT "u1"."id", "u2"."username" FROM "users" AS "u1" - INNER JOIN (SELECT "users"."id", "users"."name" AS "username" FROM "users" WHERE "users"."id" = $id) AS "u2" ON "u1"."id" = "u2"."id" - WHERE "u1"."id" = $id AND "u2"."username" = $name;`, - }, - { - name: "common table expression", - stmt: `WITH cte AS (SELECT id, name FROM users) SELECT cte.id as userid, posts.title as title FROM cte - INNER JOIN posts ON cte.id = posts.author_id;`, - want: `WITH "cte" AS (SELECT "users"."id", "users"."name" FROM "users") SELECT "cte"."id" AS "userid", "posts"."title" AS "title" FROM "cte" - INNER JOIN "posts" ON "cte"."id" = "posts"."author_id";`, - }, - { - name: "insert returning", - stmt: `INSERT INTO users (id, name) VALUES ($id+1, (select name from users where id = $id)) - RETURNING *, id as userid;`, - want: `INSERT INTO "users" ("id", "name") VALUES ($id+1, (SELECT "users"."name" FROM "users" WHERE "users"."id" = $id)) - RETURNING *, "users"."id" AS "userid";`, - }, - { - name: "insert on conflict", - stmt: `INSERT INTO users as u (id, name) VALUES ($id, $name) ON CONFLICT (id) where id = 1 DO UPDATE SET name = $name WHERE u.id = $id RETURNING u.name;`, - want: `INSERT INTO "users" AS "u" ("id", "name") VALUES ($id, $name) ON CONFLICT ("id") WHERE "u"."id" = 1 DO UPDATE SET "name" = $name WHERE "u"."id" = $id RETURNING "u"."name";`, - }, - { - name: "update returning with qualified table name", - stmt: `UPDATE users as u SET name = u1.name FROM users AS u1 WHERE u.id = $id RETURNING u.name as username, u1.name as uname;`, - want: `UPDATE "users" AS "u" SET "name" = "u1"."name" FROM "users" AS "u1" WHERE "u"."id" = $id RETURNING "u"."name" AS "username", "u1"."name" AS "uname";`, - }, - { - name: "delete returning with qualified table name", - stmt: `DELETE FROM users as u WHERE id = $id RETURNING *, u.id as uid;`, - want: `DELETE FROM "users" AS "u" WHERE "u"."id" = $id - RETURNING *, "u"."id" AS "uid";`, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - ast, err := sqlparser.Parse(test.stmt) - require.NoError(t, err) - - lis := parseTypes.NewErrorListener() - - _, err = typing.AnalyzeTypes(ast, []*types.Table{usersTable, postsTable}, &typing.AnalyzeOptions{ - ArbitraryBinds: true, - Qualify: true, - ErrorListener: lis, - }) - require.NoError(t, err) - if test.wantErr { - require.Error(t, lis.Err()) - return - } - require.NoError(t, err) - - str, err := tree.SafeToSQL(ast) - require.NoError(t, err) - - require.Equal(t, removeWhitespace(test.want), removeWhitespace(str)) - }) - } -} - -func removeWhitespace(s string) string { - return strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return -1 // skip this rune - } - return r - }, s) -} - -// Test_Typing tests that the typing visitor properly -// analyzes the types of the given statement. -func Test_Typing(t *testing.T) { - type testcase struct { - name string - stmt string - relation map[string]*types.DataType - err error // can be nil if no error is expected - } - - tests := []testcase{ - { - name: "simple select", - stmt: "SELECT id, name FROM users WHERE name = 'satoshi' ORDER BY id LIMIT 10 OFFSET 10;", - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "CTE", - stmt: `WITH cte AS (SELECT id, name FROM users) SELECT cte.id as userid, posts.title as title FROM cte - INNER JOIN posts ON cte.id = posts.author_id;`, - relation: map[string]*types.DataType{ - "userid": types.IntType, - "title": types.TextType, - }, - }, - { - name: "select with where, aggregate", - stmt: `SELECT id, name FROM users WHERE id = $id GROUP BY id, name HAVING count(*) > 1;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "subquery", - stmt: `SELECT id, name FROM users WHERE id IN (SELECT author_id FROM posts WHERE title = $title);`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "joins", - stmt: `SELECT u1.id, u2.name FROM users AS u1 - INNER JOIN users AS u2 ON u1.id = u2.id - WHERE u1.id = $id AND u2.name = $name;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "joins against subquery", - stmt: `SELECT u1.id, u2.username FROM users AS u1 - INNER JOIN (SELECT id, name as username FROM users WHERE id = $id) AS u2 ON u1.id = u2.id - WHERE u1.id = $id AND u2.username = $name;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "username": types.TextType, - }, - }, - { - name: "insert", - stmt: `INSERT INTO users (id, name) VALUES ($id+1, (select name from users where id = $id)) - RETURNING *, id as userid;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - "userid": types.IntType, - }, - }, - { - name: "insert invalid literal", - stmt: `INSERT INTO users (id, name) VALUES ($id, 1);`, - err: typing.ErrInvalidType, - }, - { - name: "upsert", - stmt: `INSERT INTO users as u (id, name) VALUES ($id, $name) ON CONFLICT (id) where id = 1 DO UPDATE SET name = $name WHERE u.id = $id RETURNING u.name;`, - relation: map[string]*types.DataType{ - "name": types.TextType, - }, - }, - { - name: "update", - stmt: `UPDATE users as u SET name = u1.name FROM users AS u1 WHERE u.id = $id RETURNING u.name as username;`, - relation: map[string]*types.DataType{ - "username": types.TextType, - }, - }, - { - name: "update return all", - stmt: `UPDATE users as u SET name = $name WHERE id = $id RETURNING *, u.name as username;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - "username": types.TextType, - }, - }, - { - name: "delete", - stmt: `DELETE FROM users as u WHERE id = $id RETURNING *, u.id as uid;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "uid": types.IntType, - "name": types.TextType, - }, - }, - { - name: "compound select", - stmt: `SELECT id, name FROM users UNION SELECT id, name FROM users;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "invalid compound select", - stmt: `SELECT name, id FROM users UNION SELECT id, name FROM users;`, - err: typing.ErrCompoundShape, - }, - { - name: "select table", - stmt: `SELECT u.* FROM users as u inner join users as u1 on u.id=u1.id;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "select *", - stmt: `SELECT * FROM users;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "return unnamed column", - stmt: `SELECT * from (select 1+1);`, - err: errAny, - }, - { - name: "aliased column", - stmt: `SELECT 1+1 as two, (1+3)::text as three;`, - relation: map[string]*types.DataType{ - "two": types.IntType, - "three": types.TextType, - }, - }, - { - name: "between", - stmt: `SELECT * FROM users WHERE id BETWEEN $id AND $id+1;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "case", - stmt: `SELECT CASE WHEN id = $id THEN name ELSE 'default' END as name FROM users;`, - relation: map[string]*types.DataType{ - "name": types.TextType, - }, - }, - { - name: "case with type cast to different types (should fail)", - stmt: `SELECT CASE name = 'satoshi' WHEN id = $id THEN 1 ELSE 2::text END as name FROM users;`, - err: errAny, - }, - { - name: "collate", - stmt: `SELECT * FROM users WHERE name = 'sAtoshi' COLLATE NOCASE;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "exists", - stmt: `SELECT * FROM users WHERE EXISTS (SELECT * FROM posts WHERE author_id = $id);`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "function", - stmt: `SELECT * FROM users WHERE id = $id AND name = 'satoshi' AND length(name) = 7;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "is null", - stmt: `SELECT * FROM users WHERE name IS NULL;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "select in", - stmt: `SELECT * FROM users WHERE id IN (1, 2, 3);`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "boolean literal", - stmt: `SELECT * FROM users WHERE id = $id AND name = 'satoshi' AND TRUE;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "blob literal", - stmt: `SELECT * FROM users WHERE id = $id AND name = 0x01::text;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "string comparison", - stmt: `SELECT * FROM users WHERE name LIKE 'satoshi%';`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "string comparison with escape", - stmt: `SELECT id FROM users WHERE name LIKE 'satoshi\%' ESCAPE '\';`, - relation: map[string]*types.DataType{ - "id": types.IntType, - }, - }, - { - name: "unary operator", - stmt: `SELECT id FROM users WHERE id = $id AND -id = 1;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - }, - }, - { - name: "extremely complex with CTEs and subqueries", - stmt: `WITH cte AS (SELECT id, name FROM users WHERE id = $id) SELECT cte.id as userid, ps.title as title FROM cte - INNER JOIN (SELECT id, title, author_id FROM posts WHERE author_id IN (SELECT users.id FROM users WHERE name = $name)) as ps ON cte.id = ps.author_id;`, - relation: map[string]*types.DataType{ - "userid": types.IntType, - "title": types.TextType, - }, - }, - { - name: "correlated subquery", - stmt: `SELECT id, name FROM users WHERE id = (SELECT id FROM posts WHERE author_id = users.id);`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - { - name: "alias used in having clause", - stmt: `SELECT id, name as username FROM users WHERE id = $id GROUP BY id, username HAVING count(username) > 1;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "username": types.TextType, - }, - }, - { - name: "join with having", - stmt: `SELECT u1.id, u2.name FROM users AS u1 - INNER JOIN users AS u2 ON u1.id = u2.id - GROUP BY u1.id, u2.name - HAVING u1.id = $id AND u2.name = $name;`, - relation: map[string]*types.DataType{ - "id": types.IntType, - "name": types.TextType, - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - ast, err := sqlparser.Parse(test.stmt) - require.NoError(t, err) - - lis := parseTypes.NewErrorListener() - rel, err := typing.AnalyzeTypes(ast, []*types.Table{usersTable, postsTable}, &typing.AnalyzeOptions{ - BindParams: bindParams, - ErrorListener: lis, - }) - require.NoError(t, err) - if test.err != nil { - if errors.Is(test.err, errAny) { - require.Error(t, lis.Err()) - return - } - - // we are expecting an error - require.ErrorAs(t, lis.Err(), &test.err) - return - } else { - require.NoError(t, lis.Err()) - } - - returned := make(map[string]*types.DataType) - err = rel.Loop(func(s string, a *typing.Attribute) error { - returned[s] = a.Type - return nil - }) - require.NoError(t, err) - - require.Equal(t, len(test.relation), len(returned)) - - for k, v := range test.relation { - found, ok := returned[k] - require.True(t, ok) - require.True(t, v.Equals(found)) - } - }) - } -} - -var ( - bindParams = map[string]*types.DataType{ - "$id": types.IntType, - "$name": types.TextType, - "$title": types.TextType, - } - - usersTable = &types.Table{ - Name: "users", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - }, - { - Name: "name", - Type: types.TextType, - }, - }, - } - - postsTable = &types.Table{ - Name: "posts", - Columns: []*types.Column{ - { - Name: "id", - Type: types.IntType, - }, - { - Name: "title", - Type: types.TextType, - }, - { - Name: "content", - Type: types.TextType, - }, - { - Name: "author_id", - Type: types.IntType, - }, - }, - } -) - -// special case error for testing -var errAny = errors.New("any error") diff --git a/parse/sql/sqlanalyzer/utils/column_search.go b/parse/sql/sqlanalyzer/utils/column_search.go deleted file mode 100644 index cf8119579..000000000 --- a/parse/sql/sqlanalyzer/utils/column_search.go +++ /dev/null @@ -1,68 +0,0 @@ -package utils - -import ( - "fmt" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -// TODO: test this -// SearchResultColumns returns a list of columns used the expression. -// It does not return columns used in subqueries. -func SearchResultColumns(expr tree.Expression) []*tree.ExpressionColumn { - if expr == nil { - return nil - } - - switch e := expr.(type) { - case *tree.ExpressionTextLiteral, *tree.ExpressionNumericLiteral, *tree.ExpressionBooleanLiteral, - *tree.ExpressionNullLiteral, *tree.ExpressionBlobLiteral: - return nil - case *tree.ExpressionBindParameter: - return nil - case *tree.ExpressionColumn: - return []*tree.ExpressionColumn{e} - case *tree.ExpressionUnary: - return SearchResultColumns(e.Operand) - case *tree.ExpressionBinaryComparison: - return nil // a binary expression will not return a result column - case *tree.ExpressionFunction: - found := make([]*tree.ExpressionColumn, 0) - for _, arg := range e.Inputs { - found = append(found, SearchResultColumns(arg)...) - } - - return found - case *tree.ExpressionList: - found := make([]*tree.ExpressionColumn, 0) - for _, arg := range e.Expressions { - found = append(found, SearchResultColumns(arg)...) - } - - return found - case *tree.ExpressionCollate: - return SearchResultColumns(e.Expression) - case *tree.ExpressionStringCompare: - return append(SearchResultColumns(e.Left), SearchResultColumns(e.Right)...) - case *tree.ExpressionIs: - return append(SearchResultColumns(e.Left), SearchResultColumns(e.Right)...) - case *tree.ExpressionBetween: - return SearchResultColumns(e.Expression) - case *tree.ExpressionSelect: - return nil - case *tree.ExpressionCase: - found := SearchResultColumns(e.CaseExpression) - for _, pair := range e.WhenThenPairs { - for _, expr := range pair { - found = append(found, SearchResultColumns(expr)...) - } - } - - return append(found, SearchResultColumns(e.ElseExpression)...) - case *tree.ExpressionArithmetic: - return append(SearchResultColumns(e.Left), SearchResultColumns(e.Right)...) - } - - fmt.Println("UNEXPECTED BUG: unhandled expression type in AstListener column search", expr) - return nil -} diff --git a/parse/sql/sqlanalyzer/utils/utils.go b/parse/sql/sqlanalyzer/utils/utils.go deleted file mode 100644 index 05af7f2a9..000000000 --- a/parse/sql/sqlanalyzer/utils/utils.go +++ /dev/null @@ -1,55 +0,0 @@ -package utils - -import ( - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -// GetUsedTables returns the tables that are used or joined in a Join Clause. -// It will search across the base table as well as all joined predicates. -// It will properly scope tables used in subqueries, and not include them in the result. -func GetUsedTables(join tree.Relation) ([]*tree.RelationTable, error) { - tables := make([]*tree.RelationTable, 0) - depth := 0 // depth tracks if we are in a subquery or not - - err := join.Walk(&tree.ImplementedListener{ - FuncEnterExpressionSelect: func(p0 *tree.ExpressionSelect) error { - depth++ - - return nil - }, - FuncExitExpressionSelect: func(p0 *tree.ExpressionSelect) error { - depth-- - return nil - }, - FuncEnterRelationTable: func(p0 *tree.RelationTable) error { - if depth != 0 { - return nil - } - - tables = append(tables, &tree.RelationTable{ - Name: p0.Name, - Alias: p0.Alias, - }) - return nil - }, - FuncEnterRelationSubquery: func(p0 *tree.RelationSubquery) error { - if depth != 0 { - return nil - } - depth++ // we add depth since we do not want to index extra information from the subquery - - // simply call the name and alias the alias of the subquery - tables = append(tables, &tree.RelationTable{ - Name: p0.Alias, - Alias: p0.Alias, - }) - return nil - }, - FuncExitRelationSubquery: func(p0 *tree.RelationSubquery) error { - depth-- - return nil - }, - }) - - return tables, err -} diff --git a/parse/sql/sqlanalyzer/utils/utils_test.go b/parse/sql/sqlanalyzer/utils/utils_test.go deleted file mode 100644 index 5e4f44767..000000000 --- a/parse/sql/sqlanalyzer/utils/utils_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package utils_test - -import ( - "strings" - "testing" - - sqlparser "github.com/kwilteam/kwil-db/parse/sql" - "github.com/kwilteam/kwil-db/parse/sql/sqlanalyzer/utils" - "github.com/kwilteam/kwil-db/parse/sql/tree" - "github.com/stretchr/testify/require" -) - -func Test_JoinSearch(t *testing.T) { - type testcase struct { - name string - stmt string // must be a select statement - tables []*tree.RelationTable - } - - tests := []testcase{ - { - name: "simple select", - stmt: "SELECT * FROM users", - tables: tbls("users"), - }, - { - name: "select with joins and aliases", - stmt: "SELECT * FROM users AS u INNER JOIN posts AS p ON u.id = p.user_id", - tables: tbls("users u", "posts p"), - }, - { - name: "select with joins and subqueries", // it should not register the subquery as a table - stmt: `SELECT p.id, p.title - FROM posts AS p - INNER JOIN followers AS f ON p.user_id = f.user_id - INNER JOIN users ON users.id = f.user_id - INNER JOIN ( - SELECT * FROM SOME_OTHER_TABLE - ) AS l ON l.post_id = p.id - ORDER BY p.post_date DESC NULLS LAST - LIMIT 20 OFFSET $offset;`, - tables: tbls("posts p", "followers f", "users", "l l"), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - stmt, err := sqlparser.Parse(tt.stmt) - require.NoError(t, err) - - topSelect, ok := stmt.(*tree.SelectStmt) - require.True(t, ok) - require.Equal(t, len(topSelect.Stmt.SimpleSelects), 1) - - tbls, err := utils.GetUsedTables(topSelect.Stmt.SimpleSelects[0].From) - require.NoError(t, err) - - require.EqualValues(t, tt.tables, tbls) - }) - } -} - -func tbls(tables ...string) []*tree.RelationTable { - // should either be "tablename" OR "tablename alias" - tbls := make([]*tree.RelationTable, len(tables)) - for i, t := range tables { - split := strings.Split(t, " ") - switch len(split) { - case 1: - tbls[i] = tbl(split[0]) - case 2: - tbls[i] = tbl(split[0], split[1]) - default: - panic("too many aliases") - } - } - - return tbls -} - -// if alias is empty, the table name is used as the alias -func tbl(name string, alias ...string) *tree.RelationTable { - if len(alias) == 0 { - return &tree.RelationTable{ - Name: name, - } - } - if len(alias) > 1 { - panic("too many aliases") - } - - return &tree.RelationTable{ - Name: name, - Alias: alias[0], - } -} diff --git a/parse/sql/tree/CTE.go b/parse/sql/tree/CTE.go deleted file mode 100644 index 2f0f8dbd8..000000000 --- a/parse/sql/tree/CTE.go +++ /dev/null @@ -1,45 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type CTE struct { - types.Node - - Table string - Columns []string - Select *SelectCore -} - -func (c *CTE) Accept(v AstVisitor) any { - return v.VisitCTE(c) -} - -func (c *CTE) Walk(w AstListener) error { - return run( - w.EnterCTE(c), - walk(w, c.Select), - w.ExitCTE(c), - ) -} - -func (c *CTE) ToSQL() string { - stmt := sqlwriter.NewWriter() - stmt.WriteIdent(c.Table) - - if len(c.Columns) > 0 { - stmt.WriteParenList(len(c.Columns), func(i int) { - stmt.WriteIdent(c.Columns[i]) - }) - } - - stmt.Token.As() - - stmt.Token.Lparen() - stmt.WriteString(c.Select.ToSQL()) - stmt.Token.Rparen() - - return stmt.String() -} diff --git a/parse/sql/tree/CTE_test.go b/parse/sql/tree/CTE_test.go deleted file mode 100644 index 7684be558..000000000 --- a/parse/sql/tree/CTE_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestCTE_ToSQL(t *testing.T) { - type fields struct { - Table string - Columns []string - Select *tree.SelectCore - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid cte", - fields: fields{ - Table: "foo", - Columns: []string{"bar", "baz"}, - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - From: &tree.RelationTable{ - Name: "foo", - }, - }, - }, - }, - }, - want: `"foo" ("bar", "baz") AS (SELECT * FROM "foo")`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r != nil { - t.Errorf("CTE.ToSQL() should not have panicked") - } - }() - } - - c := &tree.CTE{ - Table: tt.fields.Table, - Columns: tt.fields.Columns, - Select: tt.fields.Select, - } - - got := c.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("CTE.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} - -var mockCTE = &tree.CTE{ - Table: "foo", - Columns: []string{"bar", "baz"}, - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - From: &tree.RelationTable{ - Name: "foo", - }, - }, - }, - }, -} diff --git a/parse/sql/tree/README.md b/parse/sql/tree/README.md deleted file mode 100644 index 934b027ef..000000000 --- a/parse/sql/tree/README.md +++ /dev/null @@ -1,828 +0,0 @@ -# Kwil SQL AST - -This package contains the specification for the Kwil Engine Statement Interface. It includes information regarding supported functionalities, limitations / restrictions, etc, for Kwil SQL Engine Statements. This document outlines these statements using Golang structs and interfaces. For more information on structs and interfaces, read: [structs]() / [interfaces]() - -**Most users should not use this interface, but instead use the SQL interface.** This interface is meant to provide context on all possible functionalities of Kwil, as well as provide an interface for tooling to be built around. - -## Overview - -There are 4 main structs that are meant to be used as "entry points" / "outermost interfaces" for instructions to the Kwil Database Engine. These structs with transpile to standalone instructions to the SQL engine, and will gracefully handle errors: - -- Insert -- Update -- Delete -- Select - -Other structs can be used from the interface, but they will likely not function as standalone statements, and do not have graceful error handling in the case of being used incorrectly. It is recommended for users to only use these to embed within one of the four "outermost" interfaces. - -### Insert - -Insert is the outermost struct for containing any stand-alone Insert statement. - -```go -type Insert struct { - CTE []*CTE - InsertStmt *InsertStmt -} -``` - -### Update - -Update is the outermost struct for containing any stand-alone Update statement. - -```go -type Update struct { - CTE []*CTE - UpdateStmt *UpdateStmt -} -``` - -### Delete - -Delete is the outermost struct for containing any stand-alone Delete statement. - -```go -type Delete struct { - CTE []*CTE - DeleteStmt *DeleteStmt -} -``` - -### Select - -Select is the outermost struct for containing any stand-alone Select statement. - -```go -type Select struct { - CTE []*CTE - SelectStmt *SelectStmt -} -``` - -## Other Interfaces - -The rest of the structs / interfaces / enumerators supported by Kwil are listed below, alphebetically. - -#### CollationType - -Collations are used for specifying the bit pattern that should be used for characters. - -```go -type CollationType string - -const ( - CollationTypeBinary CollationType = "BINARY" - CollationTypeNoCase CollationType = "NOCASE" - CollationTypeRTrim CollationType = "RTRIM" -) -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -WHERE username = 'sAtoSHi' -# Start of collation -COLLATE NOCASE; -# End of collation -``` - -#### Conflict Target - -A conflict target is used to specify the what indexed column(s) should be watched in the case of a UNIQUE conflict. - -```go -type ConflictTarget struct { - IndexedColumns []string - Where Expression -} -``` - -_In SQL:_ - -```sql -INSERT INTO users (username, age, user_type) -VALUES ('satoshi', '42', 'registered') -# Start of conflict target -ON CONFLICT (username) - WHERE user_type = 'unregistered' - ## End of conflict target - DO UPDATE SET age='42', user_type = 'registered' - WHERE username = 'satoshi'; -``` - -#### CTE - -Common table expressions (CTE) are used to create temporary tables / views that can be used later in a statement. - -```go -type CTE struct { - Table string - Columns []string - Select *SelectStmt -} -``` - -_In SQL:_ - -```sql -# Start of CTE -WITH users_followers AS ( - SELECT followed_id AS followers - FROM followers - WHERE follower_id = ( - SELECT id FROM users - WHERE username = 'satoshi' - ) -) -# End of CTE -SELECT * -FROM posts -WHERE author_id IN ( - SELECT followers - FROM users_followers -) -ORDER BY post_height DESC; -``` - -#### DeleteStmt - -A delete statement is a full statement that specifies a record deletion. Unlike the pure 'Delete' struct, it does not contain common table expressions. - -```go -type DeleteStmt struct { - QualifiedTableName *QualifiedTableName - Where Expression - Returning *ReturningClause -} -``` - -_In SQL:_ - -```sql -# Start of DeleteStmt -DELETE FROM users -WHERE username = 'sbf' -RETURNING ( - SELECT * - FROM users - LIMIT 10 -); -# End of DeleteStmt -``` - -#### Expression - -Expressions are combinations of one or more values, identifiers, comparisons, and other expressions that evaluate to a value / set of values. There are multiple types of expressions in Kwil, so they have [their own page](./expressions.md). - -#### Functions - -Functions are invokable clauses that take inputs and return a value. Functions are valid expressions, and take other expressions as inputs. A full list of functions supported by Kwil can be found on the [Functions page](./functions.md). - -#### GroupBy - -The GROUP BY clause is used to group rows that have the same values in specified columns into aggregated data. - -GROUP BY clauses can also contain a HAVING clause, which filters the returned results based on some condition. - -```go -type GroupBy struct { - Expressions []Expression - Having Expression -} -``` - -_In SQL:_ - -```sql -SELECT u.username, COUNT(f.follower_id) -FROM users AS u -LEFT JOIN followers AS f - ON u.id = f.followed_id -# Start of GROUP BY -GROUP BY f.followed_id, u.id -HAVING COUNT(f.follower_id) > 100; -# End of GROUP BY -``` - -_The above query retrieves the usernames and follower count for all users who have more than 100 followers_ - -#### InsertStmt - -The InsertStmt is the content of an Insert occurring after any common table expressions. - -```go -type InsertStmt struct { - InsertType InsertType - Table string - TableAlias string - Columns []string - Values [][]Expression - Upsert *Upsert - ReturningClause *ReturningClause -} -``` - -_In SQL:_ - -**(TODO: I am quite certain this is not a valid query)** - -```sql -INSERT INTO users (username, age, wallet_address) -VALUES ($username, $age, @caller) -ON CONFLICT (username) - WHERE wallet_address = @caller - DO UPDATE SET - age = $age - WHERE username = $username -RETURNING ( - SELECT username - FROM users - WHERE age = $age - LIMIT 10 -); -``` - -_The above query inserts a new user into a table, owned by the wallet address calling the query. If the username is already registered and owned by the caller, it will update the age to the new value. The query then returns up to 10 other users who have the same age._ - -#### InsertType - -The Kwil interface contains different InsertType enumerations to specify different Insert operations. The default is 'InsertTypeInsert' - -```go -type InsertType uint8 - -const ( - InsertTypeInsert InsertType = iota - InsertTypeReplace - InsertTypeInsertOrReplace -) -``` - -_In SQL:_ - -```sql -# Begin InsertType -INSERT OR REPLACE /*End InsertType*/ INTO users (username, age) -VALUES ('satoshi', 42) -``` - -#### Relation -A Relation is used to specify the table(s) that should be used in a SELECT statement. -It can be a table, a subquery, or joined tables. - -#### RelationTable - -A RelationTable is used to specify a table that should be used in a SELECT statement. - -```go -type RelationTable struct { - Name string - Alias string -} - -``` - -_In SQL:_ - -```sql -SELECT * -# Start of RelationTable -FROM users AS u -# End of RelationTable -WHERE username = 'satoshi'; -``` - -#### RelationSubquery - -A RelationSubquery is used to specify a subquery that should be used in a SELECT statement. - -```go -type RelationSubquery struct { - Select *SelectStmt - Alias string -} -``` - -_In SQL:_ - -```sql -SELECT * -# Start of RelationSubquery -FROM ( - SELECT * - FROM users - WHERE age > 18 -) AS u -# End of RelationSubquery -WHERE username = 'satoshi'; -``` - -#### RelationJoin - -A RelationJoin is used to specify joined tables that should be used in a SELECT statement. - -```go -type RelationJoin struct { - Relation Relation - Joins []*JoinPredicate -} -``` - -_In SQL:_ - -```sql -SELECT p.title, p.content -# Start of RelationJoin -FROM posts AS p -INNER JOIN users as u - ON p.author_id = u.id -# End of JoinClause -``` - -#### JoinPredicate - -A join predicate contains the type of join, the subject / target table of the join, and the ON predicate (a.k.a. 'Contraint') on which the tables should be joined. - -```go -type JoinPredicate struct { - JoinOperator *JoinOperator - Table Relation - Constraint Expression -} -``` - -_In SQL:_ - -```sql -SELECT p.title, p.content -FROM posts AS p -# Start of JoinPredicate -INNER JOIN users as u - ON p.author_id = u.id -# End of JoinPredicate -``` - -#### JoinOperator - -The JoinOperator specifies the type of join that should be performed. It takes a join type, and has the option to make them "natural" and "outer" joins. Inner joins and regular joins cannot be made "outer". - -```go -type JoinOperator struct { - Natural bool - JoinType JoinType - Outer bool -} -``` - -_In SQL:_ - -```sql -SELECT p.title, p.content -FROM posts AS p -/*Start of JoinOperator*/OUTER LEFT JOIN /*End of JoinOperator*/ users as u - ON p.author_id = u.id -``` - -#### JoinType - -The JoinType is an enumerator that specifies the type of join to be performed. - -```go -type JoinType uint8 - -const ( - JoinTypeJoin JoinType = iota - JoinTypeInner - JoinTypeLeft - JoinTypeRight - JoinTypeFull -) -``` - -_In SQL:_ - -```sql -SELECT p.title, p.content -FROM posts AS p -OUTER /*Start of JoinType*/ LEFT JOIN /*End of JoinType*/ users as u - ON p.author_id = u.id -``` - -#### Limit - -A LIMIT clause is used to specify record limits. It takes an expression to limit (usually a literal, but can be anything). It optionally takes an offset as well, or a second expression. - -```go -type Limit struct { - Expression Expression - Offset Expression - SecondExpression Expression -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -# Limit clause: -LIMIT 10 OFFSET 20 -``` - -#### OrderBy - -An ORDER BY clause specifies the way in which query results should be ordered. A single ORDER BY can contain multiple ordering terms. - -```go -type OrderBy struct { - OrderingTerms []*OrderingTerm -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -## OrderBy with 2 ordering terms -ORDER BY username COLLATE BINARY, -age ASC NULLS LAST -``` - -#### OrderingTerm - -An ordering term is a singular elements of an ORDER BY clause. It contains an expression to order on, and an optional collation, order type (ASC/DESC), and terms for null ordering. - -```go -type OrderingTerm struct { - Expression Expression - Collation CollationType - OrderType OrderType - NullOrdering NullOrderingType -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -## ordering term 1 -ORDER BY username COLLATE BINARY, -## ordering term 2 -age ASC NULLS LAST -``` - -#### OrderType - -The OrderType is used to specify the order in which nuemeric values should appear. - -```go -type OrderType string - -const ( - OrderTypeNone OrderType = "" - OrderTypeAsc OrderType = "ASC" - OrderTypeDesc OrderType = "DESC" -) -``` - -#### NullOrderingType - -The NullOrderingType specifies the order in which nulls should be returned in a query. - -```go -type NullOrderingType string - -const ( - NullOrderingTypeNone NullOrderingType = "" - NullOrderingTypeFirst NullOrderingType = "NULLS FIRST" - NullOrderingTypeLast NullOrderingType = "NULLS LAST" -) -``` - -#### QualifiedTableName - -A QualifiedTableName (QTN) is used to specify update and delete target tables. Unlike Insert and Select (which do not except QTNs), QTNs in Update and Delete can optionally contain instructions for whether or not indexes should apply. - -```go -type QualifiedTableName struct { - TableName string - TableAlias string - IndexedBy string - NotIndexed bool -} -``` - -_In SQL:_ - -```sql -DELETE FROM -# Start of qualified table name -comments INDEXED BY comment_index -# End of qualified table name -WHERE post_id = 5; -``` - -#### Returning Clause - -A returning clause is used to specify data that should be returned from a query that is not a SELECT. - -```go -type ReturningClause struct { - Returned []*ReturningClauseColumn -} -``` - -_In SQL:_ - -```sql -INSERT INTO posts (id, title, content, author_id) -VALUES ($id, $title, $content, $author_id) -# Returning Clause -RETURNING id, title, content -``` - -#### ReturningClauseColumn - -A returning clause column is used to specify what column should be returned in a returning clause. - -```go -type ReturningClauseColumn struct { - All bool - Expression Expression - Alias string -} -``` - -_In SQL:_ - -```sql -INSERT INTO posts (id, title, content, author_id) -VALUES ($id, $title, $content, $author_id) -# id, title, content are all returning clause columns: -RETURNING id, title, content -``` - -#### SelectStmt - -The SelectStmt is the a select statement without common table expressions. - -```go -type SelectStmt struct { - SelectCore *SelectCore - OrderBy *OrderBy - Limit *Limit -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -ORDER BY username -LIMIT 10 -``` - -#### SelectCore - -The SelectCore is the select statement without OrderBy and Limit. SelectCore's can be compounded on each other using CompoundOperators. - -```go -type SelectCore struct { - SelectType SelectType - Columns []string - From *FromClause - Where Expression - GroupBy *GroupBy - Compound *CompoundOperator -} -``` - -_In SQL:_ - -```sql -SELECT u.username, COUNT(f.follower_id) -FROM users AS u -LEFT JOIN followers AS f - ON u.id = f.followed_id -GROUP BY f.followed_id, u.id -HAVING COUNT(f.follower_id) > 100; -``` - -#### SelectType - -SelectType is an enumerator that specifies the type of SELECT that should be performed. The default type is SelectTypeAll. - -```go -type SelectType uint8 - -const ( - SelectTypeAll SelectType = iota - SelectTypeDistinct -) -``` - -#### FromClause - -The FROM clause is a wrapper around Relation. The differentiation is necessary to make future features easier to -implement. - -```go -type FromClause struct { - Relation Relation -} -``` - -_In SQL:_ - -```sql -SELECT u.username, COUNT(f.follower_id) -# Start FromClause -FROM users AS u -LEFT JOIN followers AS f - ON u.id = f.followed_id -# End FromClause -GROUP BY f.followed_id, u.id -HAVING COUNT(f.follower_id) > 100; -``` - -#### CompoundOperator - -A compound operator is used to combine two SelectCores into a single set. - -```go -type CompoundOperator struct { - Operator CompoundOperatorType - SelectClause *SelectCore -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM posts -WHERE author_id = 1 -# Begin compound operator -UNION ALL -SELECT * -FROM posts -WHERE author_id = 2 -# End compound operator -``` - -_This is not the best way to write this query, but it displays how CompoundOperator can be used_ - -#### CompoundOperatorType - -The compound operator type is an enumerator specifiyng the type of compound operator that should be used. - -```go -type CompoundOperatorType uint8 - -const ( - CompoundOperatorTypeUnion CompoundOperatorType = iota - CompoundOperatorTypeUnionAll - CompoundOperatorTypeIntersect - CompoundOperatorTypeExcept -) -``` - -#### Relation - -The Relation is used to specify a value that can be either a table or a subquery or a join clause. There are several -different types, -which are displayed below: - -```go -type RelationTable struct { - Name string - Alias string -} - -type RelationSubquery struct { - Select *SelectStmt - Alias string -} - -type RelationJoin struct { - Relation Relation - Joins []*JoinPredicate -} -``` - -_In SQL:_ - -```sql -SELECT u.username, COUNT(f.follower_id) -# Start -FROM users AS u -# End -LEFT JOIN followers AS f - ON u.id = f.followed_id -GROUP BY f.followed_id, u.id -HAVING COUNT(f.follower_id) > 100; -``` - -#### UpdateStmt - -The UpdateStmt is an Update without common table expressions. - -```go -type UpdateStmt struct { - Or UpdateOr - QualifiedTableName *QualifiedTableName - UpdateSetClause []*UpdateSetClause - From *FromClause - Where Expression - Returning *ReturningClause -} -``` - -_In SQL:_ - -```sql -UPDATE users -SET age = 25 -WHERE username = 'satoshi' -``` - -#### UpdateOr - -The UpdateOr clause is used to specify if there should be an alternative for the OR statement. - -```go -type UpdateOr string - -const ( - UpdateOrAbort UpdateOr = "ABORT" - UpdateOrFail UpdateOr = "FAIL" - UpdateOrIgnore UpdateOr = "IGNORE" - UpdateOrReplace UpdateOr = "REPLACE" - UpdateOrRollback UpdateOr = "ROLLBACK" -) -``` - -#### UpdateSetClause - -The UpdateSetClause is used to specify what column(s) should be used in an update statement. - -```go -type UpdateSetClause struct { - Columns []string - Expression Expression -} -``` - -_In SQL:_ - -```sql -UPDATE users -# Begin singular UpdateSetClause -SET age = 25 -# End UpdateSetClause -WHERE username = 'satoshi' -``` - -#### Upsert - -An Upsert clause is used to specify actions that should occur when a UNIQUE conflict occurs. - -```go -type Upsert struct { - ConflictTarget *ConflictTarget - Type UpsertType - Updates []*UpdateSetClause - Where Expression -} -``` - -_In SQL:_ - -```sql -INSERT INTO users (username, age, user_type) -VALUES ('satoshi', '42', 'registered') -# Start of conflict target -ON CONFLICT (username) - WHERE user_type = 'unregistered' - ## End of conflict target - DO UPDATE SET age='42', user_type = 'registered' - WHERE username = 'satoshi'; -``` - -#### UpsertType - -The UpsertType is used to specify what should occur on an upsert: - -```go -type UpsertType uint8 - -const ( - UpsertTypeDoNothing UpsertType = iota - UpsertTypeDoUpdate -) -``` diff --git a/parse/sql/tree/ast.go b/parse/sql/tree/ast.go deleted file mode 100644 index ebf727a35..000000000 --- a/parse/sql/tree/ast.go +++ /dev/null @@ -1,36 +0,0 @@ -package tree - -import ( - "github.com/antlr4-go/antlr/v4" - "github.com/kwilteam/kwil-db/parse/types" -) - -// AstNode represents an AST node. -type AstNode interface { - AstWalker - GetNode() *types.Node - Set(rule antlr.ParserRuleContext) - SetToken(tok antlr.Token) - - // ToSQL converts the node to a SQL string. - ToSQL() string - // Accept accepts an AstVisitor to visit itself. - Accept(AstVisitor) any -} - -type Statement interface { - AstNode - - statement() -} - -type Expression interface { - AstNode - joinable -} - -type ResultColumn interface { - AstNode - - resultColumn() -} diff --git a/parse/sql/tree/ast_listener.go b/parse/sql/tree/ast_listener.go deleted file mode 100644 index 3946cb1c1..000000000 --- a/parse/sql/tree/ast_listener.go +++ /dev/null @@ -1,1366 +0,0 @@ -package tree - -// AstListener defines the interface for walking through the AstNode. -type AstListener interface { - EnterConflictTarget(*ConflictTarget) error - ExitConflictTarget(*ConflictTarget) error - EnterCTE(*CTE) error - ExitCTE(*CTE) error - EnterDeleteStmt(*DeleteStmt) error - ExitDeleteStmt(*DeleteStmt) error - EnterDeleteCore(*DeleteCore) error - ExitDeleteCore(*DeleteCore) error - EnterExpressionTextLiteral(*ExpressionTextLiteral) error - ExitExpressionTextLiteral(*ExpressionTextLiteral) error - EnterExpressionNumericLiteral(*ExpressionNumericLiteral) error - ExitExpressionNumericLiteral(*ExpressionNumericLiteral) error - EnterExpressionBooleanLiteral(*ExpressionBooleanLiteral) error - ExitExpressionBooleanLiteral(*ExpressionBooleanLiteral) error - EnterExpressionNullLiteral(*ExpressionNullLiteral) error - ExitExpressionNullLiteral(*ExpressionNullLiteral) error - EnterExpressionBlobLiteral(*ExpressionBlobLiteral) error - ExitExpressionBlobLiteral(*ExpressionBlobLiteral) error - EnterExpressionBindParameter(*ExpressionBindParameter) error - ExitExpressionBindParameter(*ExpressionBindParameter) error - EnterExpressionColumn(*ExpressionColumn) error - ExitExpressionColumn(*ExpressionColumn) error - EnterExpressionUnary(*ExpressionUnary) error - ExitExpressionUnary(*ExpressionUnary) error - EnterExpressionBinaryComparison(*ExpressionBinaryComparison) error - ExitExpressionBinaryComparison(*ExpressionBinaryComparison) error - EnterExpressionFunction(*ExpressionFunction) error - ExitExpressionFunction(*ExpressionFunction) error - EnterExpressionList(*ExpressionList) error - ExitExpressionList(*ExpressionList) error - EnterExpressionCollate(*ExpressionCollate) error - ExitExpressionCollate(*ExpressionCollate) error - EnterExpressionStringCompare(*ExpressionStringCompare) error - ExitExpressionStringCompare(*ExpressionStringCompare) error - EnterExpressionIs(*ExpressionIs) error - ExitExpressionIs(*ExpressionIs) error - EnterExpressionBetween(*ExpressionBetween) error - ExitExpressionBetween(*ExpressionBetween) error - EnterExpressionSelect(*ExpressionSelect) error - ExitExpressionSelect(*ExpressionSelect) error - EnterExpressionCase(*ExpressionCase) error - ExitExpressionCase(*ExpressionCase) error - EnterExpressionArithmetic(*ExpressionArithmetic) error - ExitExpressionArithmetic(*ExpressionArithmetic) error - EnterGroupBy(*GroupBy) error - ExitGroupBy(*GroupBy) error - EnterInsertStmt(*InsertStmt) error - ExitInsertStmt(*InsertStmt) error - EnterInsertCore(*InsertCore) error - ExitInsertCore(*InsertCore) error - EnterJoinPredicate(*JoinPredicate) error - ExitJoinPredicate(*JoinPredicate) error - EnterJoinOperator(*JoinOperator) error - ExitJoinOperator(*JoinOperator) error - EnterLimit(*Limit) error - ExitLimit(*Limit) error - EnterOrderBy(*OrderBy) error - ExitOrderBy(*OrderBy) error - EnterOrderingTerm(*OrderingTerm) error - ExitOrderingTerm(*OrderingTerm) error - EnterQualifiedTableName(*QualifiedTableName) error - ExitQualifiedTableName(*QualifiedTableName) error - EnterRelationTable(*RelationTable) error - ExitRelationTable(*RelationTable) error - EnterRelationFunction(*RelationFunction) error - ExitRelationFunction(*RelationFunction) error - EnterRelationSubquery(*RelationSubquery) error - ExitRelationSubquery(*RelationSubquery) error - EnterRelationJoin(*RelationJoin) error - ExitRelationJoin(*RelationJoin) error - EnterResultColumnStar(*ResultColumnStar) error - ExitResultColumnStar(*ResultColumnStar) error - EnterResultColumnExpression(*ResultColumnExpression) error - ExitResultColumnExpression(*ResultColumnExpression) error - EnterResultColumnTable(*ResultColumnTable) error - ExitResultColumnTable(*ResultColumnTable) error - EnterReturningClause(*ReturningClause) error - ExitReturningClause(*ReturningClause) error - EnterReturningClauseColumn(*ReturningClauseColumn) error - ExitReturningClauseColumn(*ReturningClauseColumn) error - EnterSelectStmt(*SelectStmt) error - ExitSelectStmt(*SelectStmt) error - EnterSimpleSelect(*SimpleSelect) error - ExitSimpleSelect(*SimpleSelect) error - EnterSelectCore(*SelectCore) error - ExitSelectCore(*SelectCore) error - EnterCompoundOperator(*CompoundOperator) error - ExitCompoundOperator(*CompoundOperator) error - EnterUpdateSetClause(*UpdateSetClause) error - ExitUpdateSetClause(*UpdateSetClause) error - EnterUpdateStmt(*UpdateStmt) error - ExitUpdateStmt(*UpdateStmt) error - EnterUpdateCore(*UpdateCore) error - ExitUpdateCore(*UpdateCore) error - EnterUpsert(*Upsert) error - ExitUpsert(*Upsert) error -} - -type BaseListener struct{} - -var _ AstListener = &BaseListener{} - -func NewBaseListener() AstListener { - return &BaseListener{} -} - -func (b *BaseListener) EnterCTE(p0 *CTE) error { - return nil -} - -func (b *BaseListener) ExitCTE(p0 *CTE) error { - return nil -} - -func (b *BaseListener) EnterCompoundOperator(p0 *CompoundOperator) error { - return nil -} - -func (b *BaseListener) ExitCompoundOperator(p0 *CompoundOperator) error { - return nil -} - -func (b *BaseListener) EnterConflictTarget(p0 *ConflictTarget) error { - return nil -} - -func (b *BaseListener) ExitConflictTarget(p0 *ConflictTarget) error { - return nil -} - -func (b *BaseListener) EnterDeleteStmt(p0 *DeleteStmt) error { - return nil -} - -func (b *BaseListener) ExitDeleteStmt(p0 *DeleteStmt) error { - return nil -} - -func (b *BaseListener) EnterDeleteCore(p0 *DeleteCore) error { - return nil -} - -func (b *BaseListener) ExitDeleteCore(p0 *DeleteCore) error { - return nil -} - -func (b *BaseListener) EnterExpressionArithmetic(p0 *ExpressionArithmetic) error { - return nil -} - -func (b *BaseListener) ExitExpressionArithmetic(p0 *ExpressionArithmetic) error { - return nil -} - -func (b *BaseListener) EnterExpressionBetween(p0 *ExpressionBetween) error { - return nil -} - -func (b *BaseListener) ExitExpressionBetween(p0 *ExpressionBetween) error { - return nil -} - -func (b *BaseListener) EnterExpressionBinaryComparison(p0 *ExpressionBinaryComparison) error { - return nil -} - -func (b *BaseListener) ExitExpressionBinaryComparison(p0 *ExpressionBinaryComparison) error { - return nil -} - -func (b *BaseListener) EnterExpressionBindParameter(p0 *ExpressionBindParameter) error { - return nil -} - -func (b *BaseListener) ExitExpressionBindParameter(p0 *ExpressionBindParameter) error { - return nil -} - -func (b *BaseListener) EnterExpressionCase(p0 *ExpressionCase) error { - return nil -} - -func (b *BaseListener) ExitExpressionCase(p0 *ExpressionCase) error { - return nil -} - -func (b *BaseListener) EnterExpressionCollate(p0 *ExpressionCollate) error { - return nil -} - -func (b *BaseListener) ExitExpressionCollate(p0 *ExpressionCollate) error { - return nil -} - -func (b *BaseListener) EnterExpressionColumn(p0 *ExpressionColumn) error { - return nil -} - -func (b *BaseListener) ExitExpressionColumn(p0 *ExpressionColumn) error { - return nil -} - -func (b *BaseListener) EnterExpressionFunction(p0 *ExpressionFunction) error { - return nil -} - -func (b *BaseListener) ExitExpressionFunction(p0 *ExpressionFunction) error { - return nil -} - -func (b *BaseListener) EnterExpressionIs(p0 *ExpressionIs) error { - return nil -} - -func (b *BaseListener) ExitExpressionIs(p0 *ExpressionIs) error { - return nil -} - -func (b *BaseListener) EnterExpressionList(p0 *ExpressionList) error { - return nil -} - -func (b *BaseListener) ExitExpressionList(p0 *ExpressionList) error { - return nil -} - -func (b *BaseListener) EnterExpressionTextLiteral(p0 *ExpressionTextLiteral) error { - return nil -} - -func (b *BaseListener) ExitExpressionTextLiteral(p0 *ExpressionTextLiteral) error { - return nil -} - -func (b *BaseListener) EnterExpressionNumericLiteral(p0 *ExpressionNumericLiteral) error { - return nil -} - -func (b *BaseListener) ExitExpressionNumericLiteral(p0 *ExpressionNumericLiteral) error { - return nil -} - -func (b *BaseListener) EnterExpressionBooleanLiteral(p0 *ExpressionBooleanLiteral) error { - return nil -} - -func (b *BaseListener) ExitExpressionBooleanLiteral(p0 *ExpressionBooleanLiteral) error { - return nil -} - -func (b *BaseListener) EnterExpressionNullLiteral(p0 *ExpressionNullLiteral) error { - return nil -} - -func (b *BaseListener) ExitExpressionNullLiteral(p0 *ExpressionNullLiteral) error { - return nil -} - -func (b *BaseListener) EnterExpressionBlobLiteral(p0 *ExpressionBlobLiteral) error { - return nil -} - -func (b *BaseListener) ExitExpressionBlobLiteral(p0 *ExpressionBlobLiteral) error { - return nil -} - -func (b *BaseListener) EnterExpressionSelect(p0 *ExpressionSelect) error { - return nil -} - -func (b *BaseListener) ExitExpressionSelect(p0 *ExpressionSelect) error { - return nil -} - -func (b *BaseListener) EnterExpressionStringCompare(p0 *ExpressionStringCompare) error { - return nil -} - -func (b *BaseListener) ExitExpressionStringCompare(p0 *ExpressionStringCompare) error { - return nil -} - -func (b *BaseListener) EnterExpressionUnary(p0 *ExpressionUnary) error { - return nil -} - -func (b *BaseListener) ExitExpressionUnary(p0 *ExpressionUnary) error { - return nil -} - -func (b *BaseListener) EnterGroupBy(p0 *GroupBy) error { - return nil -} - -func (b *BaseListener) ExitGroupBy(p0 *GroupBy) error { - return nil -} - -func (b *BaseListener) EnterInsertStmt(p0 *InsertStmt) error { - return nil -} - -func (b *BaseListener) ExitInsertStmt(p0 *InsertStmt) error { - return nil -} - -func (b *BaseListener) EnterInsertCore(p0 *InsertCore) error { - return nil -} - -func (b *BaseListener) ExitInsertCore(p0 *InsertCore) error { - return nil -} - -func (b *BaseListener) EnterJoinOperator(p0 *JoinOperator) error { - return nil -} - -func (b *BaseListener) ExitJoinOperator(p0 *JoinOperator) error { - return nil -} - -func (b *BaseListener) EnterJoinPredicate(p0 *JoinPredicate) error { - return nil -} - -func (b *BaseListener) ExitJoinPredicate(p0 *JoinPredicate) error { - return nil -} - -func (b *BaseListener) EnterLimit(p0 *Limit) error { - return nil -} - -func (b *BaseListener) ExitLimit(p0 *Limit) error { - return nil -} - -func (b *BaseListener) EnterOrderBy(p0 *OrderBy) error { - return nil -} - -func (b *BaseListener) ExitOrderBy(p0 *OrderBy) error { - return nil -} - -func (b *BaseListener) EnterOrderingTerm(p0 *OrderingTerm) error { - return nil -} - -func (b *BaseListener) ExitOrderingTerm(p0 *OrderingTerm) error { - return nil -} - -func (b *BaseListener) EnterQualifiedTableName(p0 *QualifiedTableName) error { - return nil -} - -func (b *BaseListener) ExitQualifiedTableName(p0 *QualifiedTableName) error { - return nil -} - -func (b *BaseListener) EnterRelationJoin(p0 *RelationJoin) error { - return nil -} - -func (b *BaseListener) ExitRelationJoin(p0 *RelationJoin) error { - return nil -} - -func (b *BaseListener) EnterRelationSubquery(p0 *RelationSubquery) error { - return nil -} - -func (b *BaseListener) ExitRelationSubquery(p0 *RelationSubquery) error { - return nil -} - -func (b *BaseListener) EnterRelationTable(p0 *RelationTable) error { - return nil -} - -func (b *BaseListener) ExitRelationTable(p0 *RelationTable) error { - return nil -} - -func (b *BaseListener) EnterRelationFunction(p0 *RelationFunction) error { - return nil -} - -func (b *BaseListener) ExitRelationFunction(p0 *RelationFunction) error { - return nil -} - -func (b *BaseListener) EnterResultColumnExpression(p0 *ResultColumnExpression) error { - return nil -} - -func (b *BaseListener) ExitResultColumnExpression(p0 *ResultColumnExpression) error { - return nil -} - -func (b *BaseListener) EnterResultColumnStar(p0 *ResultColumnStar) error { - return nil -} - -func (b *BaseListener) ExitResultColumnStar(p0 *ResultColumnStar) error { - return nil -} - -func (b *BaseListener) EnterResultColumnTable(p0 *ResultColumnTable) error { - return nil -} - -func (b *BaseListener) ExitResultColumnTable(p0 *ResultColumnTable) error { - return nil -} - -func (b *BaseListener) EnterReturningClause(p0 *ReturningClause) error { - return nil -} - -func (b *BaseListener) ExitReturningClause(p0 *ReturningClause) error { - return nil -} - -func (b *BaseListener) EnterReturningClauseColumn(p0 *ReturningClauseColumn) error { - return nil -} - -func (b *BaseListener) ExitReturningClauseColumn(p0 *ReturningClauseColumn) error { - return nil -} - -func (b *BaseListener) EnterSelectStmt(p0 *SelectStmt) error { - return nil -} - -func (b *BaseListener) ExitSelectStmt(p0 *SelectStmt) error { - return nil -} - -func (b *BaseListener) EnterSimpleSelect(p0 *SimpleSelect) error { - return nil -} - -func (b *BaseListener) ExitSimpleSelect(p0 *SimpleSelect) error { - return nil -} - -func (b *BaseListener) EnterSelectCore(p0 *SelectCore) error { - return nil -} - -func (b *BaseListener) ExitSelectCore(p0 *SelectCore) error { - return nil -} - -func (b *BaseListener) EnterUpdateStmt(p0 *UpdateStmt) error { - return nil -} - -func (b *BaseListener) ExitUpdateStmt(p0 *UpdateStmt) error { - return nil -} - -func (b *BaseListener) EnterUpdateSetClause(p0 *UpdateSetClause) error { - return nil -} - -func (b *BaseListener) ExitUpdateSetClause(p0 *UpdateSetClause) error { - return nil -} - -func (b *BaseListener) EnterUpdateCore(p0 *UpdateCore) error { - return nil -} - -func (b *BaseListener) ExitUpdateCore(p0 *UpdateCore) error { - return nil -} - -func (b *BaseListener) EnterUpsert(p0 *Upsert) error { - return nil -} - -func (b *BaseListener) ExitUpsert(p0 *Upsert) error { - return nil -} - -// ImplementedListener implements the AstListener interface. -// Unlike BaseListener, it holds the methods to be implemented -// as functions in a struct. This makes it easier to implement -// for small, one-off walkers. -type ImplementedListener struct { - FuncEnterCTE func(p0 *CTE) error - FuncExitCTE func(p0 *CTE) error - FuncEnterCompoundOperator func(p0 *CompoundOperator) error - FuncExitCompoundOperator func(p0 *CompoundOperator) error - FuncEnterConflictTarget func(p0 *ConflictTarget) error - FuncExitConflictTarget func(p0 *ConflictTarget) error - FuncEnterDeleteStmt func(p0 *DeleteStmt) error - FuncExitDeleteStmt func(p0 *DeleteStmt) error - FuncEnterDeleteCore func(p0 *DeleteCore) error - FuncExitDeleteCore func(p0 *DeleteCore) error - FuncEnterExpressionArithmetic func(p0 *ExpressionArithmetic) error - FuncExitExpressionArithmetic func(p0 *ExpressionArithmetic) error - FuncEnterExpressionBetween func(p0 *ExpressionBetween) error - FuncExitExpressionBetween func(p0 *ExpressionBetween) error - FuncEnterExpressionBinaryComparison func(p0 *ExpressionBinaryComparison) error - FuncExitExpressionBinaryComparison func(p0 *ExpressionBinaryComparison) error - FuncEnterExpressionBindParameter func(p0 *ExpressionBindParameter) error - FuncExitExpressionBindParameter func(p0 *ExpressionBindParameter) error - FuncEnterExpressionCase func(p0 *ExpressionCase) error - FuncExitExpressionCase func(p0 *ExpressionCase) error - FuncEnterExpressionCollate func(p0 *ExpressionCollate) error - FuncExitExpressionCollate func(p0 *ExpressionCollate) error - FuncEnterExpressionColumn func(p0 *ExpressionColumn) error - FuncExitExpressionColumn func(p0 *ExpressionColumn) error - FuncEnterExpressionFunction func(p0 *ExpressionFunction) error - FuncExitExpressionFunction func(p0 *ExpressionFunction) error - FuncEnterExpressionIs func(p0 *ExpressionIs) error - FuncExitExpressionIs func(p0 *ExpressionIs) error - FuncEnterExpressionList func(p0 *ExpressionList) error - FuncExitExpressionList func(p0 *ExpressionList) error - FuncEnterExpressionTextLiteral func(p0 *ExpressionTextLiteral) error - FuncExitExpressionTextLiteral func(p0 *ExpressionTextLiteral) error - FuncEnterExpressionNumericLiteral func(p0 *ExpressionNumericLiteral) error - FuncExitExpressionNumericLiteral func(p0 *ExpressionNumericLiteral) error - FuncEnterExpressionBooleanLiteral func(p0 *ExpressionBooleanLiteral) error - FuncExitExpressionBooleanLiteral func(p0 *ExpressionBooleanLiteral) error - FuncEnterExpressionNullLiteral func(p0 *ExpressionNullLiteral) error - FuncExitExpressionNullLiteral func(p0 *ExpressionNullLiteral) error - FuncEnterExpressionBlobLiteral func(p0 *ExpressionBlobLiteral) error - FuncExitExpressionBlobLiteral func(p0 *ExpressionBlobLiteral) error - FuncEnterExpressionSelect func(p0 *ExpressionSelect) error - FuncExitExpressionSelect func(p0 *ExpressionSelect) error - FuncEnterExpressionStringCompare func(p0 *ExpressionStringCompare) error - FuncExitExpressionStringCompare func(p0 *ExpressionStringCompare) error - FuncEnterExpressionUnary func(p0 *ExpressionUnary) error - FuncExitExpressionUnary func(p0 *ExpressionUnary) error - FuncEnterGroupBy func(p0 *GroupBy) error - FuncExitGroupBy func(p0 *GroupBy) error - FuncEnterInsertStmt func(p0 *InsertStmt) error - FuncExitInsertStmt func(p0 *InsertStmt) error - FuncEnterInsertCore func(p0 *InsertCore) error - FuncExitInsertCore func(p0 *InsertCore) error - FuncEnterJoinOperator func(p0 *JoinOperator) error - FuncExitJoinOperator func(p0 *JoinOperator) error - FuncEnterJoinPredicate func(p0 *JoinPredicate) error - FuncExitJoinPredicate func(p0 *JoinPredicate) error - FuncEnterLimit func(p0 *Limit) error - FuncExitLimit func(p0 *Limit) error - FuncEnterOrderBy func(p0 *OrderBy) error - FuncExitOrderBy func(p0 *OrderBy) error - FuncEnterOrderingTerm func(p0 *OrderingTerm) error - FuncExitOrderingTerm func(p0 *OrderingTerm) error - FuncEnterQualifiedTableName func(p0 *QualifiedTableName) error - FuncExitQualifiedTableName func(p0 *QualifiedTableName) error - FuncEnterRelationFunction func(p0 *RelationFunction) error - FuncExitRelationFunction func(p0 *RelationFunction) error - FuncEnterRelationJoin func(p0 *RelationJoin) error - FuncExitRelationJoin func(p0 *RelationJoin) error - FuncEnterRelationSubquery func(p0 *RelationSubquery) error - FuncExitRelationSubquery func(p0 *RelationSubquery) error - FuncEnterRelationTable func(p0 *RelationTable) error - FuncExitRelationTable func(p0 *RelationTable) error - FuncEnterResultColumnExpression func(p0 *ResultColumnExpression) error - FuncExitResultColumnExpression func(p0 *ResultColumnExpression) error - FuncEnterResultColumnStar func(p0 *ResultColumnStar) error - FuncExitResultColumnStar func(p0 *ResultColumnStar) error - FuncEnterResultColumnTable func(p0 *ResultColumnTable) error - FuncExitResultColumnTable func(p0 *ResultColumnTable) error - FuncEnterReturningClause func(p0 *ReturningClause) error - FuncExitReturningClause func(p0 *ReturningClause) error - FuncEnterReturningClauseColumn func(p0 *ReturningClauseColumn) error - FuncExitReturningClauseColumn func(p0 *ReturningClauseColumn) error - FuncEnterSelectStmt func(p0 *SelectStmt) error - FuncExitSelectStmt func(p0 *SelectStmt) error - FuncEnterSimpleSelect func(p0 *SimpleSelect) error - FuncExitSimpleSelect func(p0 *SimpleSelect) error - FuncEnterSelectCore func(p0 *SelectCore) error - FuncExitSelectCore func(p0 *SelectCore) error - FuncEnterUpdateStmt func(p0 *UpdateStmt) error - FuncExitUpdateStmt func(p0 *UpdateStmt) error - FuncEnterUpdateSetClause func(p0 *UpdateSetClause) error - FuncExitUpdateSetClause func(p0 *UpdateSetClause) error - FuncEnterUpdateCore func(p0 *UpdateCore) error - FuncExitUpdateCore func(p0 *UpdateCore) error - FuncEnterUpsert func(p0 *Upsert) error - FuncExitUpsert func(p0 *Upsert) error -} - -var _ AstListener = &ImplementedListener{} - -func (b *ImplementedListener) EnterCTE(p0 *CTE) error { - if b.FuncEnterCTE == nil { - return nil - } - - return b.FuncEnterCTE(p0) -} - -func (b *ImplementedListener) ExitCTE(p0 *CTE) error { - if b.FuncExitCTE == nil { - return nil - } - - return b.FuncExitCTE(p0) -} - -func (b *ImplementedListener) EnterCompoundOperator(p0 *CompoundOperator) error { - if b.FuncEnterCompoundOperator == nil { - return nil - } - - return b.FuncEnterCompoundOperator(p0) -} - -func (b *ImplementedListener) ExitCompoundOperator(p0 *CompoundOperator) error { - if b.FuncExitCompoundOperator == nil { - return nil - } - - return b.FuncExitCompoundOperator(p0) -} - -func (b *ImplementedListener) EnterConflictTarget(p0 *ConflictTarget) error { - if b.FuncEnterConflictTarget == nil { - return nil - } - - return b.FuncEnterConflictTarget(p0) -} - -func (b *ImplementedListener) ExitConflictTarget(p0 *ConflictTarget) error { - if b.FuncExitConflictTarget == nil { - return nil - } - - return b.FuncExitConflictTarget(p0) -} - -func (b *ImplementedListener) EnterDeleteStmt(p0 *DeleteStmt) error { - if b.FuncEnterDeleteStmt == nil { - return nil - } - - return b.FuncEnterDeleteStmt(p0) -} - -func (b *ImplementedListener) ExitDeleteStmt(p0 *DeleteStmt) error { - if b.FuncExitDeleteStmt == nil { - return nil - } - - return b.FuncExitDeleteStmt(p0) -} - -func (b *ImplementedListener) EnterDeleteCore(p0 *DeleteCore) error { - if b.FuncEnterDeleteCore == nil { - return nil - } - - return b.FuncEnterDeleteCore(p0) -} - -func (b *ImplementedListener) ExitDeleteCore(p0 *DeleteCore) error { - if b.FuncExitDeleteCore == nil { - return nil - } - - return b.FuncExitDeleteCore(p0) -} - -func (b *ImplementedListener) EnterExpressionArithmetic(p0 *ExpressionArithmetic) error { - if b.FuncEnterExpressionArithmetic == nil { - return nil - } - - return b.FuncEnterExpressionArithmetic(p0) -} - -func (b *ImplementedListener) ExitExpressionArithmetic(p0 *ExpressionArithmetic) error { - if b.FuncExitExpressionArithmetic == nil { - return nil - } - - return b.FuncExitExpressionArithmetic(p0) -} - -func (b *ImplementedListener) EnterExpressionBetween(p0 *ExpressionBetween) error { - if b.FuncEnterExpressionBetween == nil { - return nil - } - - return b.FuncEnterExpressionBetween(p0) -} - -func (b *ImplementedListener) ExitExpressionBetween(p0 *ExpressionBetween) error { - if b.FuncExitExpressionBetween == nil { - return nil - } - - return b.FuncExitExpressionBetween(p0) -} - -func (b *ImplementedListener) EnterExpressionBinaryComparison(p0 *ExpressionBinaryComparison) error { - if b.FuncEnterExpressionBinaryComparison == nil { - return nil - } - - return b.FuncEnterExpressionBinaryComparison(p0) -} - -func (b *ImplementedListener) ExitExpressionBinaryComparison(p0 *ExpressionBinaryComparison) error { - if b.FuncExitExpressionBinaryComparison == nil { - return nil - } - - return b.FuncExitExpressionBinaryComparison(p0) -} - -func (b *ImplementedListener) EnterExpressionBindParameter(p0 *ExpressionBindParameter) error { - if b.FuncEnterExpressionBindParameter == nil { - return nil - } - - return b.FuncEnterExpressionBindParameter(p0) -} - -func (b *ImplementedListener) ExitExpressionBindParameter(p0 *ExpressionBindParameter) error { - if b.FuncExitExpressionBindParameter == nil { - return nil - } - - return b.FuncExitExpressionBindParameter(p0) -} - -func (b *ImplementedListener) EnterExpressionCase(p0 *ExpressionCase) error { - if b.FuncEnterExpressionCase == nil { - return nil - } - - return b.FuncEnterExpressionCase(p0) -} - -func (b *ImplementedListener) ExitExpressionCase(p0 *ExpressionCase) error { - if b.FuncExitExpressionCase == nil { - return nil - } - - return b.FuncExitExpressionCase(p0) -} - -func (b *ImplementedListener) EnterExpressionCollate(p0 *ExpressionCollate) error { - if b.FuncEnterExpressionCollate == nil { - return nil - } - - return b.FuncEnterExpressionCollate(p0) -} - -func (b *ImplementedListener) ExitExpressionCollate(p0 *ExpressionCollate) error { - if b.FuncExitExpressionCollate == nil { - return nil - } - - return b.FuncExitExpressionCollate(p0) -} - -func (b *ImplementedListener) EnterExpressionColumn(p0 *ExpressionColumn) error { - if b.FuncEnterExpressionColumn == nil { - return nil - } - - return b.FuncEnterExpressionColumn(p0) -} - -func (b *ImplementedListener) ExitExpressionColumn(p0 *ExpressionColumn) error { - if b.FuncExitExpressionColumn == nil { - return nil - } - - return b.FuncExitExpressionColumn(p0) -} - -func (b *ImplementedListener) EnterExpressionFunction(p0 *ExpressionFunction) error { - if b.FuncEnterExpressionFunction == nil { - return nil - } - - return b.FuncEnterExpressionFunction(p0) -} - -func (b *ImplementedListener) ExitExpressionFunction(p0 *ExpressionFunction) error { - if b.FuncExitExpressionFunction == nil { - return nil - } - - return b.FuncExitExpressionFunction(p0) -} - -func (b *ImplementedListener) EnterExpressionIs(p0 *ExpressionIs) error { - if b.FuncEnterExpressionIs == nil { - return nil - } - - return b.FuncEnterExpressionIs(p0) -} - -func (b *ImplementedListener) ExitExpressionIs(p0 *ExpressionIs) error { - if b.FuncExitExpressionIs == nil { - return nil - } - - return b.FuncExitExpressionIs(p0) -} - -func (b *ImplementedListener) EnterExpressionList(p0 *ExpressionList) error { - if b.FuncEnterExpressionList == nil { - return nil - } - - return b.FuncEnterExpressionList(p0) -} - -func (b *ImplementedListener) ExitExpressionList(p0 *ExpressionList) error { - if b.FuncExitExpressionList == nil { - return nil - } - - return b.FuncExitExpressionList(p0) -} - -func (b *ImplementedListener) EnterExpressionTextLiteral(p0 *ExpressionTextLiteral) error { - if b.FuncEnterExpressionTextLiteral == nil { - return nil - } - - return b.FuncEnterExpressionTextLiteral(p0) -} - -func (b *ImplementedListener) ExitExpressionTextLiteral(p0 *ExpressionTextLiteral) error { - if b.FuncExitExpressionTextLiteral == nil { - return nil - } - - return b.FuncExitExpressionTextLiteral(p0) -} - -func (b *ImplementedListener) EnterExpressionNumericLiteral(p0 *ExpressionNumericLiteral) error { - if b.FuncEnterExpressionNumericLiteral == nil { - return nil - } - - return b.FuncEnterExpressionNumericLiteral(p0) -} - -func (b *ImplementedListener) ExitExpressionNumericLiteral(p0 *ExpressionNumericLiteral) error { - if b.FuncExitExpressionNumericLiteral == nil { - return nil - } - - return b.FuncExitExpressionNumericLiteral(p0) -} - -func (b *ImplementedListener) EnterExpressionBooleanLiteral(p0 *ExpressionBooleanLiteral) error { - if b.FuncEnterExpressionBooleanLiteral == nil { - return nil - } - - return b.FuncEnterExpressionBooleanLiteral(p0) -} - -func (b *ImplementedListener) ExitExpressionBooleanLiteral(p0 *ExpressionBooleanLiteral) error { - if b.FuncExitExpressionBooleanLiteral == nil { - return nil - } - - return b.FuncExitExpressionBooleanLiteral(p0) -} - -func (b *ImplementedListener) EnterExpressionNullLiteral(p0 *ExpressionNullLiteral) error { - if b.FuncEnterExpressionNullLiteral == nil { - return nil - } - - return b.FuncEnterExpressionNullLiteral(p0) -} - -func (b *ImplementedListener) ExitExpressionNullLiteral(p0 *ExpressionNullLiteral) error { - if b.FuncExitExpressionNullLiteral == nil { - return nil - } - - return b.FuncExitExpressionNullLiteral(p0) -} - -func (b *ImplementedListener) EnterExpressionBlobLiteral(p0 *ExpressionBlobLiteral) error { - if b.FuncEnterExpressionBlobLiteral == nil { - return nil - } - - return b.FuncEnterExpressionBlobLiteral(p0) -} - -func (b *ImplementedListener) ExitExpressionBlobLiteral(p0 *ExpressionBlobLiteral) error { - if b.FuncExitExpressionBlobLiteral == nil { - return nil - } - - return b.FuncExitExpressionBlobLiteral(p0) -} - -func (b *ImplementedListener) EnterExpressionSelect(p0 *ExpressionSelect) error { - if b.FuncEnterExpressionSelect == nil { - return nil - } - - return b.FuncEnterExpressionSelect(p0) -} - -func (b *ImplementedListener) ExitExpressionSelect(p0 *ExpressionSelect) error { - if b.FuncExitExpressionSelect == nil { - return nil - } - - return b.FuncExitExpressionSelect(p0) -} - -func (b *ImplementedListener) EnterExpressionStringCompare(p0 *ExpressionStringCompare) error { - if b.FuncEnterExpressionStringCompare == nil { - return nil - } - - return b.FuncEnterExpressionStringCompare(p0) -} - -func (b *ImplementedListener) ExitExpressionStringCompare(p0 *ExpressionStringCompare) error { - if b.FuncExitExpressionStringCompare == nil { - return nil - } - - return b.FuncExitExpressionStringCompare(p0) -} - -func (b *ImplementedListener) EnterExpressionUnary(p0 *ExpressionUnary) error { - if b.FuncEnterExpressionUnary == nil { - return nil - } - - return b.FuncEnterExpressionUnary(p0) -} - -func (b *ImplementedListener) ExitExpressionUnary(p0 *ExpressionUnary) error { - if b.FuncExitExpressionUnary == nil { - return nil - } - - return b.FuncExitExpressionUnary(p0) -} - -func (b *ImplementedListener) EnterGroupBy(p0 *GroupBy) error { - if b.FuncEnterGroupBy == nil { - return nil - } - - return b.FuncEnterGroupBy(p0) -} - -func (b *ImplementedListener) ExitGroupBy(p0 *GroupBy) error { - if b.FuncExitGroupBy == nil { - return nil - } - - return b.FuncExitGroupBy(p0) -} - -func (b *ImplementedListener) EnterInsertStmt(p0 *InsertStmt) error { - if b.FuncEnterInsertStmt == nil { - return nil - } - - return b.FuncEnterInsertStmt(p0) -} - -func (b *ImplementedListener) ExitInsertStmt(p0 *InsertStmt) error { - if b.FuncExitInsertStmt == nil { - return nil - } - - return b.FuncExitInsertStmt(p0) -} - -func (b *ImplementedListener) EnterInsertCore(p0 *InsertCore) error { - if b.FuncEnterInsertCore == nil { - return nil - } - - return b.FuncEnterInsertCore(p0) -} - -func (b *ImplementedListener) ExitInsertCore(p0 *InsertCore) error { - if b.FuncExitInsertCore == nil { - return nil - } - - return b.FuncExitInsertCore(p0) -} - -func (b *ImplementedListener) EnterJoinOperator(p0 *JoinOperator) error { - if b.FuncEnterJoinOperator == nil { - return nil - } - - return b.FuncEnterJoinOperator(p0) -} - -func (b *ImplementedListener) ExitJoinOperator(p0 *JoinOperator) error { - if b.FuncExitJoinOperator == nil { - return nil - } - - return b.FuncExitJoinOperator(p0) -} - -func (b *ImplementedListener) EnterJoinPredicate(p0 *JoinPredicate) error { - if b.FuncEnterJoinPredicate == nil { - return nil - } - - return b.FuncEnterJoinPredicate(p0) -} - -func (b *ImplementedListener) ExitJoinPredicate(p0 *JoinPredicate) error { - if b.FuncExitJoinPredicate == nil { - return nil - } - - return b.FuncExitJoinPredicate(p0) -} - -func (b *ImplementedListener) EnterLimit(p0 *Limit) error { - if b.FuncEnterLimit == nil { - return nil - } - - return b.FuncEnterLimit(p0) -} - -func (b *ImplementedListener) ExitLimit(p0 *Limit) error { - if b.FuncExitLimit == nil { - return nil - } - - return b.FuncExitLimit(p0) -} - -func (b *ImplementedListener) EnterOrderBy(p0 *OrderBy) error { - if b.FuncEnterOrderBy == nil { - return nil - } - - return b.FuncEnterOrderBy(p0) -} - -func (b *ImplementedListener) ExitOrderBy(p0 *OrderBy) error { - if b.FuncExitOrderBy == nil { - return nil - } - - return b.FuncExitOrderBy(p0) -} - -func (b *ImplementedListener) EnterOrderingTerm(p0 *OrderingTerm) error { - if b.FuncEnterOrderingTerm == nil { - return nil - } - - return b.FuncEnterOrderingTerm(p0) -} - -func (b *ImplementedListener) ExitOrderingTerm(p0 *OrderingTerm) error { - if b.FuncExitOrderingTerm == nil { - return nil - } - - return b.FuncExitOrderingTerm(p0) -} - -func (b *ImplementedListener) EnterQualifiedTableName(p0 *QualifiedTableName) error { - if b.FuncEnterQualifiedTableName == nil { - return nil - } - - return b.FuncEnterQualifiedTableName(p0) -} - -func (b *ImplementedListener) ExitQualifiedTableName(p0 *QualifiedTableName) error { - if b.FuncExitQualifiedTableName == nil { - return nil - } - - return b.FuncExitQualifiedTableName(p0) -} - -func (b *ImplementedListener) EnterRelationJoin(p0 *RelationJoin) error { - if b.FuncEnterRelationJoin == nil { - return nil - } - - return b.FuncEnterRelationJoin(p0) -} - -func (b *ImplementedListener) ExitRelationJoin(p0 *RelationJoin) error { - if b.FuncExitRelationJoin == nil { - return nil - } - - return b.FuncExitRelationJoin(p0) -} - -func (b *ImplementedListener) EnterRelationFunction(p0 *RelationFunction) error { - if b.FuncEnterRelationFunction == nil { - return nil - } - - return b.FuncEnterRelationFunction(p0) -} - -func (b *ImplementedListener) ExitRelationFunction(p0 *RelationFunction) error { - if b.FuncExitRelationFunction == nil { - return nil - } - - return b.FuncExitRelationFunction(p0) -} - -func (b *ImplementedListener) EnterRelationSubquery(p0 *RelationSubquery) error { - if b.FuncEnterRelationSubquery == nil { - return nil - } - - return b.FuncEnterRelationSubquery(p0) -} - -func (b *ImplementedListener) ExitRelationSubquery(p0 *RelationSubquery) error { - if b.FuncExitRelationSubquery == nil { - return nil - } - - return b.FuncExitRelationSubquery(p0) -} - -func (b *ImplementedListener) EnterRelationTable(p0 *RelationTable) error { - if b.FuncEnterRelationTable == nil { - return nil - } - - return b.FuncEnterRelationTable(p0) -} - -func (b *ImplementedListener) ExitRelationTable(p0 *RelationTable) error { - if b.FuncExitRelationTable == nil { - return nil - } - - return b.FuncExitRelationTable(p0) -} - -func (b *ImplementedListener) EnterResultColumnExpression(p0 *ResultColumnExpression) error { - if b.FuncEnterResultColumnExpression == nil { - return nil - } - - return b.FuncEnterResultColumnExpression(p0) -} - -func (b *ImplementedListener) ExitResultColumnExpression(p0 *ResultColumnExpression) error { - if b.FuncExitResultColumnExpression == nil { - return nil - } - - return b.FuncExitResultColumnExpression(p0) -} - -func (b *ImplementedListener) EnterResultColumnStar(p0 *ResultColumnStar) error { - if b.FuncEnterResultColumnStar == nil { - return nil - } - - return b.FuncEnterResultColumnStar(p0) -} - -func (b *ImplementedListener) ExitResultColumnStar(p0 *ResultColumnStar) error { - if b.FuncExitResultColumnStar == nil { - return nil - } - - return b.FuncExitResultColumnStar(p0) -} - -func (b *ImplementedListener) EnterResultColumnTable(p0 *ResultColumnTable) error { - if b.FuncEnterResultColumnTable == nil { - return nil - } - - return b.FuncEnterResultColumnTable(p0) -} - -func (b *ImplementedListener) ExitResultColumnTable(p0 *ResultColumnTable) error { - if b.FuncExitResultColumnTable == nil { - return nil - } - - return b.FuncExitResultColumnTable(p0) -} - -func (b *ImplementedListener) EnterReturningClause(p0 *ReturningClause) error { - if b.FuncEnterReturningClause == nil { - return nil - } - - return b.FuncEnterReturningClause(p0) -} - -func (b *ImplementedListener) ExitReturningClause(p0 *ReturningClause) error { - if b.FuncExitReturningClause == nil { - return nil - } - - return b.FuncExitReturningClause(p0) -} - -func (b *ImplementedListener) EnterReturningClauseColumn(p0 *ReturningClauseColumn) error { - if b.FuncEnterReturningClauseColumn == nil { - return nil - } - - return b.FuncEnterReturningClauseColumn(p0) -} - -func (b *ImplementedListener) ExitReturningClauseColumn(p0 *ReturningClauseColumn) error { - if b.FuncExitReturningClauseColumn == nil { - return nil - } - - return b.FuncExitReturningClauseColumn(p0) -} - -func (b *ImplementedListener) EnterSelectStmt(p0 *SelectStmt) error { - if b.FuncEnterSelectStmt == nil { - return nil - } - - return b.FuncEnterSelectStmt(p0) -} - -func (b *ImplementedListener) ExitSelectStmt(p0 *SelectStmt) error { - if b.FuncExitSelectStmt == nil { - return nil - } - - return b.FuncExitSelectStmt(p0) -} - -func (b *ImplementedListener) EnterSimpleSelect(p0 *SimpleSelect) error { - if b.FuncEnterSimpleSelect == nil { - return nil - } - - return b.FuncEnterSimpleSelect(p0) -} - -func (b *ImplementedListener) ExitSimpleSelect(p0 *SimpleSelect) error { - if b.FuncExitSimpleSelect == nil { - return nil - } - - return b.FuncExitSimpleSelect(p0) -} - -func (b *ImplementedListener) EnterSelectCore(p0 *SelectCore) error { - if b.FuncEnterSelectCore == nil { - return nil - } - - return b.FuncEnterSelectCore(p0) -} - -func (b *ImplementedListener) ExitSelectCore(p0 *SelectCore) error { - if b.FuncExitSelectCore == nil { - return nil - } - - return b.FuncExitSelectCore(p0) -} - -func (b *ImplementedListener) EnterUpdateStmt(p0 *UpdateStmt) error { - if b.FuncEnterUpdateStmt == nil { - return nil - } - - return b.FuncEnterUpdateStmt(p0) -} - -func (b *ImplementedListener) ExitUpdateStmt(p0 *UpdateStmt) error { - if b.FuncExitUpdateStmt == nil { - return nil - } - - return b.FuncExitUpdateStmt(p0) -} - -func (b *ImplementedListener) EnterUpdateSetClause(p0 *UpdateSetClause) error { - if b.FuncEnterUpdateSetClause == nil { - return nil - } - - return b.FuncEnterUpdateSetClause(p0) -} - -func (b *ImplementedListener) ExitUpdateSetClause(p0 *UpdateSetClause) error { - if b.FuncExitUpdateSetClause == nil { - return nil - } - - return b.FuncExitUpdateSetClause(p0) -} - -func (b *ImplementedListener) EnterUpdateCore(p0 *UpdateCore) error { - if b.FuncEnterUpdateCore == nil { - return nil - } - - return b.FuncEnterUpdateCore(p0) -} - -func (b *ImplementedListener) ExitUpdateCore(p0 *UpdateCore) error { - if b.FuncExitUpdateCore == nil { - return nil - } - - return b.FuncExitUpdateCore(p0) -} - -func (b *ImplementedListener) EnterUpsert(p0 *Upsert) error { - if b.FuncEnterUpsert == nil { - return nil - } - - return b.FuncEnterUpsert(p0) -} - -func (b *ImplementedListener) ExitUpsert(p0 *Upsert) error { - if b.FuncExitUpsert == nil { - return nil - } - - return b.FuncExitUpsert(p0) -} diff --git a/parse/sql/tree/ast_visitor.go b/parse/sql/tree/ast_visitor.go deleted file mode 100644 index e56fd6c75..000000000 --- a/parse/sql/tree/ast_visitor.go +++ /dev/null @@ -1,258 +0,0 @@ -package tree - -// AstVisitor defines visitor for AstNode. -type AstVisitor interface { - Visit(AstNode) interface{} - VisitConflictTarget(*ConflictTarget) any - VisitCompoundOperator(*CompoundOperator) any - VisitCTE(*CTE) any - VisitDeleteStmt(*DeleteStmt) any - VisitDeleteCore(*DeleteCore) any - VisitExpressionTextLiteral(*ExpressionTextLiteral) any - VisitExpressionNumericLiteral(*ExpressionNumericLiteral) any - VisitExpressionBooleanLiteral(*ExpressionBooleanLiteral) any - VisitExpressionNullLiteral(*ExpressionNullLiteral) any - VisitExpressionBlobLiteral(*ExpressionBlobLiteral) any - VisitExpressionBindParameter(*ExpressionBindParameter) any - VisitExpressionColumn(*ExpressionColumn) any - VisitExpressionUnary(*ExpressionUnary) any - VisitExpressionBinaryComparison(*ExpressionBinaryComparison) any - VisitExpressionFunction(*ExpressionFunction) any - VisitExpressionList(*ExpressionList) any - VisitExpressionCollate(*ExpressionCollate) any - VisitExpressionStringCompare(*ExpressionStringCompare) any - VisitExpressionIs(*ExpressionIs) any - VisitExpressionBetween(*ExpressionBetween) any - VisitExpressionSelect(*ExpressionSelect) any - VisitExpressionCase(*ExpressionCase) any - VisitExpressionArithmetic(*ExpressionArithmetic) any - VisitGroupBy(*GroupBy) any - VisitInsertStmt(*InsertStmt) any - VisitInsertCore(*InsertCore) any - VisitJoinPredicate(*JoinPredicate) any - VisitJoinOperator(*JoinOperator) any - VisitLimit(*Limit) any - VisitOrderBy(*OrderBy) any - VisitOrderingTerm(*OrderingTerm) any - VisitQualifiedTableName(*QualifiedTableName) any - VisitRelationTable(*RelationTable) any - VisitRelationFunction(*RelationFunction) any - VisitRelationSubquery(*RelationSubquery) any - VisitRelationJoin(*RelationJoin) any - VisitResultColumnStar(*ResultColumnStar) any - VisitResultColumnExpression(*ResultColumnExpression) any - VisitResultColumnTable(*ResultColumnTable) any - VisitReturningClause(*ReturningClause) any - VisitReturningClauseColumn(*ReturningClauseColumn) any - VisitSelectStmt(*SelectStmt) any - VisitSimpleSelect(*SimpleSelect) any - VisitSelectCore(*SelectCore) any - VisitUpdateSetClause(*UpdateSetClause) any - VisitUpdateStmt(*UpdateStmt) any - VisitUpdateCore(*UpdateCore) any - VisitUpsert(*Upsert) any -} - -// BaseAstVisitor implements AstVisitor interface, it can be embedded in -// other structs to provide default implementation for all methods. -type BaseAstVisitor struct { -} - -var _ AstVisitor = &BaseAstVisitor{} - -func (v *BaseAstVisitor) Visit(node AstNode) interface{} { - // dispatch to the concrete visit method - return node.Accept(v) -} - -func (v *BaseAstVisitor) VisitConflictTarget(node *ConflictTarget) any { - return nil -} - -func (v *BaseAstVisitor) VisitCompoundOperator(node *CompoundOperator) any { - return nil -} - -func (v *BaseAstVisitor) VisitCTE(node *CTE) any { - return nil -} - -func (v *BaseAstVisitor) VisitDeleteStmt(node *DeleteStmt) any { - return nil -} - -func (v *BaseAstVisitor) VisitDeleteCore(node *DeleteCore) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionTextLiteral(node *ExpressionTextLiteral) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionNumericLiteral(node *ExpressionNumericLiteral) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionBooleanLiteral(node *ExpressionBooleanLiteral) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionNullLiteral(node *ExpressionNullLiteral) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionBlobLiteral(node *ExpressionBlobLiteral) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionBindParameter(node *ExpressionBindParameter) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionColumn(node *ExpressionColumn) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionUnary(node *ExpressionUnary) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionBinaryComparison(node *ExpressionBinaryComparison) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionFunction(node *ExpressionFunction) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionList(node *ExpressionList) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionCollate(node *ExpressionCollate) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionStringCompare(node *ExpressionStringCompare) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionIs(node *ExpressionIs) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionBetween(node *ExpressionBetween) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionSelect(node *ExpressionSelect) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionCase(node *ExpressionCase) any { - return nil -} - -func (v *BaseAstVisitor) VisitExpressionArithmetic(node *ExpressionArithmetic) any { - return nil -} - -func (v *BaseAstVisitor) VisitGroupBy(node *GroupBy) any { - return nil -} - -func (v *BaseAstVisitor) VisitInsertStmt(node *InsertStmt) any { - return nil -} - -func (v *BaseAstVisitor) VisitInsertCore(node *InsertCore) any { - return nil -} - -func (v *BaseAstVisitor) VisitJoinPredicate(node *JoinPredicate) any { - return nil -} - -func (v *BaseAstVisitor) VisitJoinOperator(node *JoinOperator) any { - return nil -} - -func (v *BaseAstVisitor) VisitLimit(node *Limit) any { - return nil -} - -func (v *BaseAstVisitor) VisitOrderBy(node *OrderBy) any { - return nil -} - -func (v *BaseAstVisitor) VisitOrderingTerm(node *OrderingTerm) any { - return nil -} - -func (v *BaseAstVisitor) VisitQualifiedTableName(node *QualifiedTableName) any { - return nil -} - -func (v *BaseAstVisitor) VisitResultColumnStar(node *ResultColumnStar) any { - return nil -} - -func (v *BaseAstVisitor) VisitResultColumnExpression(node *ResultColumnExpression) any { - return nil -} - -func (v *BaseAstVisitor) VisitResultColumnTable(node *ResultColumnTable) any { - return nil -} - -func (v *BaseAstVisitor) VisitReturningClause(node *ReturningClause) any { - return nil -} - -func (v *BaseAstVisitor) VisitReturningClauseColumn(node *ReturningClauseColumn) any { - return nil -} - -func (v *BaseAstVisitor) VisitSelectStmt(node *SelectStmt) any { - return nil -} - -func (v *BaseAstVisitor) VisitSimpleSelect(node *SimpleSelect) any { - return nil -} - -func (v *BaseAstVisitor) VisitSelectCore(node *SelectCore) any { - return nil -} - -func (v *BaseAstVisitor) VisitRelationTable(node *RelationTable) any { - return nil -} - -func (v *BaseAstVisitor) VisitRelationFunction(node *RelationFunction) any { - return nil -} - -func (v *BaseAstVisitor) VisitRelationSubquery(node *RelationSubquery) any { - return nil -} - -func (v *BaseAstVisitor) VisitRelationJoin(node *RelationJoin) any { - return nil -} - -func (v *BaseAstVisitor) VisitUpdateSetClause(node *UpdateSetClause) any { - return nil -} - -func (v *BaseAstVisitor) VisitUpdateStmt(node *UpdateStmt) any { - return nil -} - -func (v *BaseAstVisitor) VisitUpdateCore(node *UpdateCore) any { - return nil -} - -func (v *BaseAstVisitor) VisitUpsert(node *Upsert) any { - return nil -} diff --git a/parse/sql/tree/collate.go b/parse/sql/tree/collate.go deleted file mode 100644 index 2de0809e7..000000000 --- a/parse/sql/tree/collate.go +++ /dev/null @@ -1,39 +0,0 @@ -package tree - -import ( - "fmt" - "strings" -) - -type CollationType string - -const ( - CollationTypeNoCase CollationType = "NOCASE" -) - -func (c CollationType) String() string { - return string(c) -} - -// Valid checks if the collation type is valid. -// Empty collation types are considered valid. -func (c *CollationType) Valid() error { - if c.Empty() { - return nil - } - - newC := CollationType(strings.ToUpper(string(*c))) - - switch newC { - case CollationTypeNoCase: - default: - return fmt.Errorf("invalid collation type: %s", c) - } - *c = newC - - return nil -} - -func (c CollationType) Empty() bool { - return c == "" -} diff --git a/parse/sql/tree/conflict-target.go b/parse/sql/tree/conflict-target.go deleted file mode 100644 index 4f0df19e1..000000000 --- a/parse/sql/tree/conflict-target.go +++ /dev/null @@ -1,42 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type ConflictTarget struct { - types.Node - - IndexedColumns []string - Where Expression -} - -func (c *ConflictTarget) Accept(v AstVisitor) any { - return v.VisitConflictTarget(c) -} - -func (c *ConflictTarget) Walk(w AstListener) error { - return run( - w.EnterConflictTarget(c), - walk(w, c.Where), - w.ExitConflictTarget(c), - ) -} - -func (c *ConflictTarget) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(c.IndexedColumns) > 0 { - stmt.WriteParenList(len(c.IndexedColumns), func(i int) { - stmt.WriteIdent(c.IndexedColumns[i]) - }) - } - - if c.Where != nil { - stmt.Token.Where() - stmt.WriteString(c.Where.ToSQL()) - } - - return stmt.String() -} diff --git a/parse/sql/tree/conflict-target_test.go b/parse/sql/tree/conflict-target_test.go deleted file mode 100644 index c7166c9d7..000000000 --- a/parse/sql/tree/conflict-target_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestConflictTarget_ToSQL(t *testing.T) { - type fields struct { - ConflictTarget *tree.ConflictTarget - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid conflict target", - fields: fields{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"bar", "baz"}, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionList{ - Expressions: []tree.Expression{ - &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "baz"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$c"}, - }, - }, - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$d"}, - }, - }, - }, - want: `("bar", "baz") WHERE ("baz" = $c) = $d`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := tt.fields.ConflictTarget - - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("ConflictTarget.String() should have panicked") - } - }() - } - - got := c.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("ConflictTarget.String() = %v, want %v", got, tt.want) - } - }) - } -} - -/* -func TestConflictTarget_ToSQL(t *testing.T) { - type fields struct { - IndexedColumns []*tree.IndexedColumn - Where tree.Expression - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "valid conflict target", - fields: fields{ - IndexedColumns: []*tree.IndexedColumn{ - { - Column: "bar", - }, - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "baz"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$c"}, - }, - }, - }, - want: `("bar") WHERE ("baz" = $c)`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &tree.ConflictTarget{ - IndexedColumns: tt.fields.IndexedColumns, - Where: tt.fields.Where, - } - if got := c.ToSQL(); got != tt.want { - t.Errorf("ConflictTarget.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} -*/ diff --git a/parse/sql/tree/delete.go b/parse/sql/tree/delete.go deleted file mode 100644 index 104ab5cf2..000000000 --- a/parse/sql/tree/delete.go +++ /dev/null @@ -1,90 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type DeleteStmt struct { - types.Node - - CTE []*CTE - Core *DeleteCore -} - -func (d *DeleteStmt) Accept(v AstVisitor) any { - return v.VisitDeleteStmt(d) -} - -func (d *DeleteStmt) Walk(w AstListener) error { - return run( - w.EnterDeleteStmt(d), - walkMany(w, d.CTE), - walk(w, d.Core), - w.ExitDeleteStmt(d), - ) -} - -func (d *DeleteStmt) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(d.CTE) > 0 { - stmt.Token.With() - stmt.WriteList(len(d.CTE), func(i int) { - stmt.WriteString(d.CTE[i].ToSQL()) - }) - } - - stmt.WriteString(d.Core.ToSQL()) - - stmt.Token.Semicolon() - - return stmt.String() -} - -func (d *DeleteStmt) statement() {} - -type DeleteCore struct { - types.Node - - QualifiedTableName *QualifiedTableName - Where Expression - Returning *ReturningClause -} - -func (d *DeleteCore) Accept(v AstVisitor) any { - return v.VisitDeleteCore(d) -} - -func (d *DeleteCore) Walk(w AstListener) error { - return run( - w.EnterDeleteCore(d), - walk(w, d.QualifiedTableName), - walk(w, d.Where), - walk(w, d.Returning), - w.ExitDeleteCore(d), - ) -} - -func (d *DeleteCore) ToSQL() string { - d.check() - - stmt := sqlwriter.NewWriter() - stmt.Token.Delete().From() - stmt.WriteString(d.QualifiedTableName.ToSQL()) - if d.Where != nil { - stmt.Token.Where() - stmt.WriteString(d.Where.ToSQL()) - } - if d.Returning != nil { - stmt.WriteString(d.Returning.ToSQL()) - } - - return stmt.String() -} - -func (d *DeleteCore) check() { - if d.QualifiedTableName == nil { - panic("qualified table name is nil") - } -} diff --git a/parse/sql/tree/delete_test.go b/parse/sql/tree/delete_test.go deleted file mode 100644 index 4551174cc..000000000 --- a/parse/sql/tree/delete_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestDelete_ToSQL(t *testing.T) { - type fields struct { - CTE []*tree.CTE - DeleteStmt *tree.DeleteCore - } - tests := []struct { - name string - fields fields - wantStr string - wantErr bool - }{ - { - name: "valid delete", - fields: fields{ - CTE: []*tree.CTE{ - mockCTE, - }, - DeleteStmt: &tree.DeleteCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "foo", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "foo"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - Returning: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - }, - }, - wantStr: `WITH ` + mockCTE.ToSQL() + ` DELETE FROM "foo" WHERE "foo" = $a RETURNING *;`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - d := &tree.DeleteStmt{ - CTE: tt.fields.CTE, - Core: tt.fields.DeleteStmt, - } - gotStr, err := tree.SafeToSQL(d) - if (err != nil) != tt.wantErr { - t.Errorf("DeleteStmt.ToSQL() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !compareIgnoringWhitespace(gotStr, tt.wantStr) { - t.Errorf("DeleteStmt.ToSQL() = %v, want %v", gotStr, tt.wantStr) - } - }) - } -} diff --git a/parse/sql/tree/expression-join.go b/parse/sql/tree/expression-join.go deleted file mode 100644 index 2fdfcf01a..000000000 --- a/parse/sql/tree/expression-join.go +++ /dev/null @@ -1,151 +0,0 @@ -package tree - -/* - This file contains functionality for evaluating expressions as join conditions. - due to SQLite's propensity for cartesian joins, we need to impose very strict standards - on what constitutes a valid join condition. - - In the context of Kwil and SQLite, the terms "join condition" and "join constraint" are - used interchangeably. - - As per the SQLite docs: - - ` - All joins in SQLite are based on the cartesian product of the left and right-hand datasets. - The columns of the cartesian product dataset are, in order, all the columns of the left-hand - dataset followed by all the columns of the right-hand dataset. There is a row in the - cartesian product dataset formed by combining each unique combination of a row from the - left-hand and right-hand datasets. In other words, if the left-hand dataset consists of Nleft - rows of Mleft columns, and the right-hand dataset of Nright rows of Mright columns, then the - cartesian product is a dataset of Nleft×Nright rows, each containing Mleft+Mright columns. - - If the join-operator is "CROSS JOIN", "INNER JOIN", "JOIN" or a comma (",") and there is no - ON or USING clause, then the result of the join is simply the cartesian product of the left and - right-hand datasets. If join-operator does have ON or USING clauses, those are handled according - to the following bullet points: - - - If there is an ON clause then the ON expression is evaluated for each row of the cartesian - product as a boolean expression. Only rows for which the expression evaluates to true - are included from the dataset. - ` - - There are more bullet points, however this is the only one that is relevant to us. - - Due to this behavior, we need to ensure that join conditions: - - Are binary comparisons - - Contain columns from both sides of the join - - Do not contain any subqueries - - Do not contain any function calls - - Are joined with an "=" operator - - Each side of the join condition will be evaluated recursively - - There are 3 states that an expression can be in: - - Invalid: The expression automatically disqualifies the join - - ContainsColumn: The expressions contains a column, and therefore can be used as one side of a join condition - - Valid: The expression is a binary comparison where each side is 'ContainsColumn', joined with an "=", and therefore can be used as a join condition -*/ - -type joinable interface { - joinable() joinableStatus -} - -type joinableStatus uint8 - -const ( - joinableStatusInvalid joinableStatus = iota - joinableStatusContainsColumn - joinableStatusValid -) - -func (e *ExpressionTextLiteral) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionNumericLiteral) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionBlobLiteral) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionNullLiteral) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionBooleanLiteral) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionBindParameter) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionColumn) joinable() joinableStatus { - return joinableStatusContainsColumn -} - -func (e *ExpressionUnary) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionBinaryComparison) joinable() joinableStatus { - if e.Left.joinable() == joinableStatusContainsColumn && e.Right.joinable() == joinableStatusContainsColumn && e.Operator == ComparisonOperatorEqual { - return joinableStatusValid - } - - if e.Left.joinable() == joinableStatusContainsColumn || e.Right.joinable() == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid -} - -func (e *ExpressionFunction) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionList) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionCollate) joinable() joinableStatus { - return e.Expression.joinable() -} - -func (e *ExpressionStringCompare) joinable() joinableStatus { - if e.Left.joinable() == joinableStatusContainsColumn || e.Right.joinable() == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid -} - -func (e *ExpressionIs) joinable() joinableStatus { - if e.Left.joinable() == joinableStatusContainsColumn || e.Right.joinable() == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid -} - -func (e *ExpressionBetween) joinable() joinableStatus { - return e.Expression.joinable() -} - -func (e *ExpressionSelect) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionCase) joinable() joinableStatus { - return joinableStatusInvalid -} - -func (e *ExpressionArithmetic) joinable() joinableStatus { - if e.Left.joinable() == joinableStatusContainsColumn || e.Right.joinable() == joinableStatusContainsColumn { - return joinableStatusContainsColumn - } - - return joinableStatusInvalid -} diff --git a/parse/sql/tree/expression.go b/parse/sql/tree/expression.go deleted file mode 100644 index 40bc42827..000000000 --- a/parse/sql/tree/expression.go +++ /dev/null @@ -1,843 +0,0 @@ -package tree - -import ( - "encoding/hex" - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -type Wrapped bool - -type ExpressionTextLiteral struct { - parseTypes.Node - Wrapped - Value string - TypeCast *types.DataType -} - -func (e *ExpressionTextLiteral) Accept(v AstVisitor) any { - return v.VisitExpressionTextLiteral(e) -} - -func (e *ExpressionTextLiteral) Walk(w AstListener) error { - return run( - w.EnterExpressionTextLiteral(e), - w.ExitExpressionTextLiteral(e), - ) -} - -func (e *ExpressionTextLiteral) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(fmt.Sprintf("'%s'", e.Value)) - return castSuffix(stmt.String(), e.TypeCast) -} - -func castSuffix(stmt string, typeCast *types.DataType) string { - if typeCast != nil { - stmt += "::" - - tp, err := typeCast.PGString() - if err != nil { - panic(err) - } - - stmt += tp - } - - return stmt -} - -type ExpressionNumericLiteral struct { - parseTypes.Node - - Wrapped - Value int64 - TypeCast *types.DataType -} - -func (e *ExpressionNumericLiteral) Accept(v AstVisitor) any { - return v.VisitExpressionNumericLiteral(e) -} - -func (e *ExpressionNumericLiteral) Walk(w AstListener) error { - return run( - w.EnterExpressionNumericLiteral(e), - w.ExitExpressionNumericLiteral(e), - ) -} - -func (e *ExpressionNumericLiteral) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(strconv.FormatInt(e.Value, 10)) - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionBooleanLiteral struct { - parseTypes.Node - - Wrapped - Value bool - TypeCast *types.DataType -} - -func (e *ExpressionBooleanLiteral) Accept(v AstVisitor) any { - return v.VisitExpressionBooleanLiteral(e) -} - -func (e *ExpressionBooleanLiteral) Walk(w AstListener) error { - return run( - w.EnterExpressionBooleanLiteral(e), - w.ExitExpressionBooleanLiteral(e), - ) -} - -func (e *ExpressionBooleanLiteral) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(strconv.FormatBool(e.Value)) - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionNullLiteral struct { - parseTypes.Node - - Wrapped - TypeCast *types.DataType -} - -func (e *ExpressionNullLiteral) Accept(v AstVisitor) any { - return v.VisitExpressionNullLiteral(e) -} - -func (e *ExpressionNullLiteral) Walk(w AstListener) error { - return run( - w.EnterExpressionNullLiteral(e), - w.ExitExpressionNullLiteral(e), - ) -} - -func (e *ExpressionNullLiteral) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString("NULL") - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionBlobLiteral struct { - parseTypes.Node - - Wrapped - Value []byte - TypeCast *types.DataType -} - -func (e *ExpressionBlobLiteral) Accept(v AstVisitor) any { - return v.VisitExpressionBlobLiteral(e) -} - -func (e *ExpressionBlobLiteral) Walk(w AstListener) error { - return run( - w.EnterExpressionBlobLiteral(e), - w.ExitExpressionBlobLiteral(e), - ) -} - -func (e *ExpressionBlobLiteral) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(fmt.Sprintf("'\\%s'", hex.EncodeToString(e.Value))) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionBindParameter struct { - parseTypes.Node - - Wrapped - Parameter string - TypeCast *types.DataType -} - -func (e *ExpressionBindParameter) Accept(v AstVisitor) any { - return v.VisitExpressionBindParameter(e) -} - -func (e *ExpressionBindParameter) Walk(w AstListener) error { - return run( - w.EnterExpressionBindParameter(e), - w.ExitExpressionBindParameter(e), - ) -} - -func (e *ExpressionBindParameter) ToSQL() string { - if e.Parameter == "" { - panic("ExpressionBindParameter: bind parameter cannot be empty") - } - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Parameter) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionColumn struct { - parseTypes.Node - - Wrapped - Table string - Column string - TypeCast *types.DataType -} - -func (e *ExpressionColumn) Accept(v AstVisitor) any { - return v.VisitExpressionColumn(e) -} - -func (e *ExpressionColumn) Walk(w AstListener) error { - return run( - w.EnterExpressionColumn(e), - w.ExitExpressionColumn(e), - ) -} - -func (e *ExpressionColumn) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - if e.Table != "" { - stmt.WriteIdent(e.Table) - stmt.Token.Period() - } - - if e.Column == "" { - panic("ExpressionColumn: column cannot be empty") - } - - stmt.WriteIdent(e.Column) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionUnary struct { - parseTypes.Node - - Wrapped - Operator UnaryOperator - Operand Expression - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped, -} - -func (e *ExpressionUnary) Accept(v AstVisitor) any { - return v.VisitExpressionUnary(e) -} - -func (e *ExpressionUnary) Walk(w AstListener) error { - return run( - w.EnterExpressionUnary(e), - w.ExitExpressionUnary(e), - ) -} - -func (e *ExpressionUnary) ToSQL() string { - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Operator.String()) - stmt.WriteString(e.Operand.ToSQL()) - - return castSuffix(stmt.String(), e.TypeCast) -} - -// checkTypeWrap checks if the type is nil and wrapped is false -func checkTypeWrap(typ *types.DataType, wrapped bool, node any) { - typeOf := reflect.TypeOf(node) - if typeOf.Kind() == reflect.Ptr { - typeOf = typeOf.Elem() - } - if typeOf.Kind() != reflect.Struct { - panic("checkTypeWrap: node must be a struct. this is a bug") - } - - if typ != nil && !wrapped { - panic(fmt.Sprintf("%s: expression with type cast must be wrapped in parentheses", typeOf.Name())) - } -} - -type ExpressionBinaryComparison struct { - parseTypes.Node - - Wrapped - Left Expression - Operator BinaryOperator - Right Expression - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped, -} - -func (e *ExpressionBinaryComparison) Accept(v AstVisitor) any { - return v.VisitExpressionBinaryComparison(e) -} - -func (e *ExpressionBinaryComparison) Walk(w AstListener) error { - return run( - w.EnterExpressionBinaryComparison(e), - walk(w, e.Left), - walk(w, e.Right), - w.ExitExpressionBinaryComparison(e), - ) -} - -func (e *ExpressionBinaryComparison) ToSQL() string { - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Left.ToSQL()) - stmt.WriteString(e.Operator.String()) - stmt.WriteString(e.Right.ToSQL()) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionFunction struct { - parseTypes.Node - - Wrapped - Function string - // ContextualParams are params passed in square brackets - ContextualParams []Expression - Inputs []Expression - Star bool // true if function is called with * - Distinct bool - - TypeCast *types.DataType -} - -func (e *ExpressionFunction) Accept(v AstVisitor) any { - return v.VisitExpressionFunction(e) -} - -func (e *ExpressionFunction) Walk(w AstListener) error { - return run( - w.EnterExpressionFunction(e), - walkMany(w, e.Inputs), - w.ExitExpressionFunction(e), - ) -} - -func (e *ExpressionFunction) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(strings.ToLower(e.Function)) - stmt.Token.Lparen() - - if e.Star { - stmt.Token.Asterisk() - } else { - if e.Distinct { - stmt.Token.Distinct() - } - - // the contextual params just get passed first - for i, param := range e.ContextualParams { - if i > 0 { - stmt.Token.Comma() - } - stmt.WriteString(param.ToSQL()) - } - - // then the input params - for i, param := range e.Inputs { - if i > 0 || len(e.ContextualParams) > 0 { - stmt.Token.Comma() - } - stmt.WriteString(param.ToSQL()) - } - } - - stmt.Token.Rparen() - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionList struct { - parseTypes.Node - - Wrapped - Expressions []Expression - - TypeCast *types.DataType -} - -func (e *ExpressionList) Accept(v AstVisitor) any { - return v.VisitExpressionList(e) -} - -func (e *ExpressionList) Walk(w AstListener) error { - return run( - w.EnterExpressionList(e), - walkMany(w, e.Expressions), - w.ExitExpressionList(e), - ) -} - -func (e *ExpressionList) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - if len(e.Expressions) == 0 { - panic("ExpressionExpressionList: expressions cannot be empty") - } - - stmt.WriteParenList(len(e.Expressions), func(i int) { - stmt.WriteString(e.Expressions[i].ToSQL()) - }) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionCollate struct { - parseTypes.Node - - Wrapped - Expression Expression - Collation CollationType - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionCollate) Accept(v AstVisitor) any { - return v.VisitExpressionCollate(e) -} - -func (e *ExpressionCollate) Walk(w AstListener) error { - return run( - w.EnterExpressionCollate(e), - walk(w, e.Expression), - w.ExitExpressionCollate(e), - ) -} - -func (e *ExpressionCollate) ToSQL() string { - if e.Expression == nil { - panic("ExpressionCollate: expression cannot be nil") - } - if e.Collation == "" { - panic("ExpressionCollate: collation name cannot be empty") - } - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Expression.ToSQL()) - stmt.Token.Collate() - stmt.WriteString(e.Collation.String()) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionStringCompare struct { - parseTypes.Node - - Wrapped - Left Expression - Operator StringOperator - Right Expression - Escape Expression // can only be used with LIKE or NOT LIKE - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionStringCompare) Accept(v AstVisitor) any { - return v.VisitExpressionStringCompare(e) -} - -func (e *ExpressionStringCompare) Walk(w AstListener) error { - return run( - w.EnterExpressionStringCompare(e), - walk(w, e.Left), - walk(w, e.Right), - walk(w, e.Escape), - w.ExitExpressionStringCompare(e), - ) -} - -func (e *ExpressionStringCompare) ToSQL() string { - if e.Left == nil { - panic("ExpressionStringCompare: left expression cannot be nil") - } - if e.Right == nil { - panic("ExpressionStringCompare: right expression cannot be nil") - } - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Left.ToSQL()) - stmt.WriteString(e.Operator.String()) - stmt.WriteString(e.Right.ToSQL()) - if e.Escape != nil { - if !e.Operator.Escapable() { - panic("ExpressionStringCompare: escape can only be used with LIKE or NOT LIKE") - } - - stmt.Token.Escape() - stmt.WriteString(e.Escape.ToSQL()) - } - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionIs struct { - parseTypes.Node - - Wrapped - Left Expression - Distinct bool - Not bool - Right Expression - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionIs) Accept(v AstVisitor) any { - return v.VisitExpressionIs(e) -} - -func (e *ExpressionIs) Walk(w AstListener) error { - return run( - w.EnterExpressionIs(e), - walk(w, e.Left), - walk(w, e.Right), - w.ExitExpressionIs(e), - ) -} - -func (e *ExpressionIs) ToSQL() string { - if e.Left == nil { - panic("ExpressionIs: left expression cannot be nil") - } - if e.Right == nil { - panic("ExpressionIs: right expression cannot be nil") - } - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Left.ToSQL()) - stmt.Token.Is() - if e.Not { - stmt.Token.Not() - } - if e.Distinct { - stmt.Token.Distinct().From() - } - stmt.WriteString(e.Right.ToSQL()) - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionBetween struct { - parseTypes.Node - - Wrapped - Expression Expression - NotBetween bool - Left Expression - Right Expression - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionBetween) Accept(v AstVisitor) any { - return v.VisitExpressionBetween(e) -} - -func (e *ExpressionBetween) Walk(w AstListener) error { - return run( - w.EnterExpressionBetween(e), - walk(w, e.Expression), - walk(w, e.Left), - walk(w, e.Right), - w.ExitExpressionBetween(e), - ) -} - -func (e *ExpressionBetween) ToSQL() string { - // TODO: those validation should be done in analyzer - if e.Expression == nil { - panic("ExpressionBetween: expression cannot be nil") - } - if e.Left == nil { - panic("ExpressionBetween: left expression cannot be nil") - } - if e.Right == nil { - panic("ExpressionBetween: right expression cannot be nil") - } - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.WriteString(e.Expression.ToSQL()) - if e.NotBetween { - stmt.Token.Not() - } - stmt.Token.Between() - stmt.WriteString(e.Left.ToSQL()) - stmt.Token.And() - stmt.WriteString(e.Right.ToSQL()) - - return castSuffix(stmt.String(), e.TypeCast) -} - -type ExpressionSelect struct { - parseTypes.Node - - Wrapped - IsNot bool - IsExists bool - Select *SelectCore - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionSelect) Accept(v AstVisitor) any { - return v.VisitExpressionSelect(e) -} - -func (e *ExpressionSelect) Walk(w AstListener) error { - return run( - w.EnterExpressionSelect(e), - walk(w, e.Select), - w.ExitExpressionSelect(e), - ) -} - -func (e *ExpressionSelect) ToSQL() string { - e.check() - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - if e.IsNot { - stmt.Token.Not() - } - if e.IsExists { - stmt.Token.Exists() - } - stmt.Token.Lparen() - - selectSql := e.Select.ToSQL() - - stmt.WriteString(selectSql) - stmt.Token.Rparen() - - return castSuffix(stmt.String(), e.TypeCast) -} - -func (e *ExpressionSelect) check() { - if e.Select == nil { - panic("ExpressionSelect: select cannot be nil") - } - - if e.IsNot { - if !e.IsExists { - panic("ExpressionSelect: NOT can only be used with EXISTS") - } - } - - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) -} - -type ExpressionCase struct { - parseTypes.Node - - Wrapped - CaseExpression Expression - WhenThenPairs [][2]Expression - ElseExpression Expression - - TypeCast *types.DataType - // NOTE: type cast does not apply to the whole case expression -} - -func (e *ExpressionCase) Accept(v AstVisitor) any { - return v.VisitExpressionCase(e) -} - -func (e *ExpressionCase) Walk(w AstListener) error { - return run( - w.EnterExpressionCase(e), - walk(w, e.CaseExpression), - func() error { - for _, whenThen := range e.WhenThenPairs { - err := walk(w, whenThen[0]) - if err != nil { - return err - } - err = walk(w, whenThen[1]) - if err != nil { - return err - } - } - return nil - }(), - walk(w, e.ElseExpression), - w.ExitExpressionCase(e), - ) -} - -func (e *ExpressionCase) ToSQL() string { - if len(e.WhenThenPairs) == 0 { - panic("ExpressionCase: must contain at least 1 when-then pair") - } - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - stmt.Token.Case() - if e.CaseExpression != nil { - stmt.WriteString(e.CaseExpression.ToSQL()) - } - - for _, whenThen := range e.WhenThenPairs { - stmt.Token.When() - stmt.WriteString(whenThen[0].ToSQL()) - stmt.Token.Then() - stmt.WriteString(whenThen[1].ToSQL()) - } - - if e.ElseExpression != nil { - stmt.Token.Else() - stmt.WriteString(e.ElseExpression.ToSQL()) - } - - stmt.Token.End() - return stmt.String() -} - -type ExpressionArithmetic struct { - parseTypes.Node - - Wrapped - Left Expression - Operator ArithmeticOperator - Right Expression - - TypeCast *types.DataType - // NOTE: type cast only makes sense when wrapped -} - -func (e *ExpressionArithmetic) Accept(v AstVisitor) any { - return v.VisitExpressionArithmetic(e) -} - -func (e *ExpressionArithmetic) Walk(w AstListener) error { - return run( - w.EnterExpressionArithmetic(e), - walk(w, e.Left), - walk(w, e.Right), - w.ExitExpressionArithmetic(e), - ) -} - -func (e *ExpressionArithmetic) ToSQL() string { - checkTypeWrap(e.TypeCast, bool(e.Wrapped), e) - - stmt := sqlwriter.NewWriter() - - if e.Wrapped { - stmt.WrapParen() - } - - // TODO: this should be removed once we handle * properly - // right now, * is treated as an ArithmeticOperator, but it should be its own type - // if * is passed, left and right are not defined - - stmt.WriteString(e.Left.ToSQL()) - stmt.WriteString(e.Operator.String()) - stmt.WriteString(e.Right.ToSQL()) - - return castSuffix(stmt.String(), e.TypeCast) -} diff --git a/parse/sql/tree/expression_test.go b/parse/sql/tree/expression_test.go deleted file mode 100644 index b04171332..000000000 --- a/parse/sql/tree/expression_test.go +++ /dev/null @@ -1,813 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestExpressionTextLiteral_ToSQL(t *testing.T) { - type fields tree.Expression - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "expression literal", - fields: &tree.ExpressionTextLiteral{ - Value: "foo", - }, - want: "'foo'", - }, - { - name: "expression literal with type cast", - fields: &tree.ExpressionTextLiteral{ - Value: "foo", - TypeCast: types.TextType, - }, - want: "'foo' ::TEXT", - // not variable. this should be the result string, no interpolation - }, - { - name: "expression literal with wrapped paren", - fields: &tree.ExpressionTextLiteral{ - Value: "foo", - Wrapped: true, - }, - want: "( 'foo' )", - }, - { - name: "expression literal with wrapped paren and type cast", - fields: &tree.ExpressionTextLiteral{ - Value: "foo", - Wrapped: true, - TypeCast: types.TextType, - }, - want: "( 'foo' ) ::TEXT", - }, - { - name: "expression literal with int", - fields: &tree.ExpressionNumericLiteral{ - Value: 1, - }, - want: "1", - }, - { - name: "expression literal with int and type cast", - fields: &tree.ExpressionNumericLiteral{ - Value: 1, - TypeCast: types.IntType, - }, - want: "1 ::INT8", - }, - { - name: "expression $ bind parameter", - fields: &tree.ExpressionBindParameter{ - Parameter: "$foo", - }, - want: "$foo", - }, - { - name: "expression $ bind parameter with type cast", - fields: &tree.ExpressionBindParameter{ - Parameter: "$foo", - TypeCast: types.TextType, - }, - want: "$foo ::TEXT", - }, - { - name: "expression @ bind parameter", - fields: &tree.ExpressionBindParameter{ - Parameter: "@foo", - }, - want: "@foo", - }, - { - name: "expression @ bind parameter with type cast", - fields: &tree.ExpressionBindParameter{ - Parameter: "@foo", - TypeCast: types.TextType, - }, - want: "@foo ::TEXT", - }, - { - name: "expression parameter with empty string", - fields: &tree.ExpressionBindParameter{ - Parameter: "", - }, - wantPanic: true, - }, - { - name: "expression column", - fields: &tree.ExpressionColumn{ - Column: "foo", - }, - want: `"foo"`, - }, - { - name: "expression column with type cast", - fields: &tree.ExpressionColumn{ - Column: "foo", - TypeCast: types.TextType, - }, - want: `"foo" ::TEXT`, - }, - { - name: "expression column with table", - fields: &tree.ExpressionColumn{ - Table: "bar", - Column: "foo", - }, - want: `"bar"."foo"`, - }, - { - name: "expression column with table and type cast", - fields: &tree.ExpressionColumn{ - Table: "bar", - Column: "foo", - TypeCast: types.TextType, - }, - want: `"bar"."foo" ::TEXT`, - }, - { - name: "expression column with only table", - fields: &tree.ExpressionColumn{ - Table: "bar", - }, - wantPanic: true, - }, - { - name: "expression unary operator", - fields: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionColumn{ - Column: "foo", - }, - }, - want: `NOT "foo"`, - }, - { - name: "expression unary operator with type cast", - fields: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionColumn{ - Column: "foo", - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `(NOT "foo") ::INT8`, - }, - { - name: "expression unary operator with type cast without wrapped", - fields: &tree.ExpressionUnary{ - Operator: tree.UnaryOperatorNot, - Operand: &tree.ExpressionColumn{ - Column: "foo", - }, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "expression binary comparison", - fields: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - want: `"foo" = 'bar'`, - }, - { - name: "expression binary comparison with type cast", - fields: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" = 'bar') ::INT8`, - }, - { - name: "expression binary comparison with type cast without wrapped", - fields: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "expression abs function", - fields: &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{ - &tree.ExpressionColumn{ - Column: "foo", - }, - }, - }, - want: "abs(\"foo\")", - }, - { - name: "expression abs function with type cast", - fields: &tree.ExpressionFunction{ - Function: "abs", - Inputs: []tree.Expression{ - &tree.ExpressionColumn{ - Column: "foo", - }, - }, - TypeCast: types.IntType, - }, - want: "abs(\"foo\") ::INT8", - }, - { - name: "expression list", - fields: &tree.ExpressionList{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{ - Column: "foo", - }, - &tree.ExpressionColumn{ - Column: "bar", - }, - }, - }, - want: "(\"foo\", \"bar\")", - }, - { - name: "expression list with element type cast", - fields: &tree.ExpressionList{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{ - Column: "foo", - TypeCast: types.TextType, - }, - &tree.ExpressionColumn{ - Column: "bar", - TypeCast: types.IntType, - }, - }, - }, - want: `("foo" ::TEXT, "bar" ::INT8)`, - }, - { - name: "expression list with type cast", - // NOTE Seems no point in having a type cast for a list?? as we can't have a list types? - fields: &tree.ExpressionList{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{ - Column: "foo", - }, - &tree.ExpressionColumn{ - Column: "bar", - }, - }, - TypeCast: types.TextType, - }, - want: "(\"foo\", \"bar\") ::TEXT", - }, - { - name: "collate", - fields: &tree.ExpressionCollate{ - Expression: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - Collation: tree.CollationTypeNoCase, - }, - want: `"foo" = 'bar' COLLATE NOCASE`, - }, - { - name: "collate with type cast", - fields: &tree.ExpressionCollate{ - Expression: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - Collation: tree.CollationTypeNoCase, - Wrapped: true, - TypeCast: types.IntType, - }, - want: `("foo" = 'bar' COLLATE NOCASE) ::INT8`, - }, - { - name: "collate with type cast without wrapped", - fields: &tree.ExpressionCollate{ - Expression: &tree.ExpressionBinaryComparison{}, - Collation: tree.CollationTypeNoCase, - TypeCast: types.TextType, - }, - wantPanic: true, - }, - { - name: "collate with no expression", - fields: &tree.ExpressionCollate{ - Collation: tree.CollationTypeNoCase, - }, - wantPanic: true, - }, - { - name: "collate with no collation", - fields: &tree.ExpressionCollate{ - Expression: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - }, - wantPanic: true, - }, - { - name: "string compare with escape", - fields: &tree.ExpressionStringCompare{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.StringOperatorNotLike, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Escape: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - want: `"foo" NOT LIKE 'bar' ESCAPE 'baz'`, - }, - { - name: "string compare with escape and type cast", - fields: &tree.ExpressionStringCompare{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.StringOperatorNotLike, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Escape: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" NOT LIKE 'bar' ESCAPE 'baz') ::INT8`, - }, - { - name: "string compare with escape and type cast without wrapped", - fields: &tree.ExpressionStringCompare{ - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "IsNull", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionNullLiteral{}, - }, - want: `"foo" IS NULL`, - }, - { - name: "IsNull with type cast", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionNullLiteral{}, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" IS NULL) ::INT8`, - }, - { - name: "IsNull with type cast without wrapped", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionNullLiteral{}, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "IsNull with no expression", - fields: &tree.ExpressionIs{}, - wantPanic: true, - }, - { - name: "Is Not Null", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionNullLiteral{}, - Not: true, - }, - want: `"foo" IS NOT NULL`, - }, - { - name: "Is Not Null with type cast", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionNullLiteral{}, - Not: true, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" IS NOT NULL) ::INT8`, - }, - { - name: "is not distinct from", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Distinct: true, - Not: true, - }, - want: `"foo" IS NOT DISTINCT FROM 'bar'`, - }, - { - name: "is not distinct from with type cast", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Distinct: true, - Not: true, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" IS NOT DISTINCT FROM 'bar') ::INT8`, - }, - { - name: "is not distinct from with type cast without wrapped", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Distinct: true, - Not: true, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "expr is expr", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - want: `"foo" IS 'bar'`, - }, - { - name: "distinct with no left", - fields: &tree.ExpressionIs{ - Right: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - wantPanic: true, - }, - { - name: "distinct with no right", - fields: &tree.ExpressionIs{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - }, - wantPanic: true, - }, - { - name: "valid between", - fields: &tree.ExpressionBetween{ - Expression: &tree.ExpressionColumn{ - Column: "foo", - }, - NotBetween: true, - Left: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - want: `"foo" NOT BETWEEN 'bar' AND 'baz'`, - }, - { - name: "valid between with type cast", - fields: &tree.ExpressionBetween{ - Expression: &tree.ExpressionColumn{ - Column: "foo", - }, - NotBetween: true, - Left: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" NOT BETWEEN 'bar' AND 'baz') ::INT8`, - }, - { - name: "valid between with type cast without wrapped", - fields: &tree.ExpressionBetween{ - Expression: &tree.ExpressionColumn{ - Column: "foo", - }, - NotBetween: true, - Left: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - { - name: "between with no expression", - fields: &tree.ExpressionBetween{ - Left: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - wantPanic: true, - }, - { - name: "between with no left", - fields: &tree.ExpressionBetween{ - Expression: &tree.ExpressionColumn{ - Column: "foo", - }, - Right: &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - wantPanic: true, - }, - { - name: "between with no right", - fields: &tree.ExpressionBetween{ - Expression: &tree.ExpressionColumn{ - Column: "foo", - }, - Left: &tree.ExpressionTextLiteral{ - Value: "bar", - }, - }, - wantPanic: true, - }, - { - name: "select subquery", - fields: &tree.ExpressionSelect{ - IsNot: true, - IsExists: true, - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - From: &tree.RelationTable{ - Name: "foo", - Alias: "f", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "f", - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - }, - }, - }, - want: `NOT EXISTS (SELECT * FROM "foo" AS "f" WHERE "f"."foo" = $a)`, - }, - { - name: "select subquery with type cast", - fields: &tree.ExpressionSelect{ - IsNot: true, - IsExists: true, - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - From: &tree.RelationTable{ - Name: "foo", - Alias: "f", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "f", - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - }, - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `(NOT EXISTS (SELECT * FROM "foo" AS "f" WHERE "f"."foo" = $a)) ::INT8`, - }, - { - name: "case expression", - fields: &tree.ExpressionCase{ - CaseExpression: &tree.ExpressionColumn{ - Column: "foo", - }, - WhenThenPairs: [][2]tree.Expression{ - { - &tree.ExpressionTextLiteral{ - Value: "bar", - }, - &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - }, - ElseExpression: &tree.ExpressionTextLiteral{ - Value: "qux", - }, - }, - want: `CASE "foo" WHEN 'bar' THEN 'baz' ELSE 'qux' END`, - }, - { - name: "case expression with no case expression", - fields: &tree.ExpressionCase{ - WhenThenPairs: [][2]tree.Expression{ - { - &tree.ExpressionTextLiteral{ - Value: "bar", - }, - &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - }, - ElseExpression: &tree.ExpressionTextLiteral{ - Value: "qux", - }, - }, - want: `CASE WHEN 'bar' THEN 'baz' ELSE 'qux' END`, - }, - { - name: "case expression with no when then pairs", - fields: &tree.ExpressionCase{ - CaseExpression: &tree.ExpressionColumn{ - Column: "foo", - }, - ElseExpression: &tree.ExpressionTextLiteral{ - Value: "qux", - }, - }, - wantPanic: true, - }, - { - name: "case expression with no else expression", - fields: &tree.ExpressionCase{ - CaseExpression: &tree.ExpressionColumn{ - Column: "foo", - }, - WhenThenPairs: [][2]tree.Expression{ - { - &tree.ExpressionTextLiteral{ - Value: "bar", - }, - &tree.ExpressionTextLiteral{ - Value: "baz", - }, - }, - }, - }, - want: `CASE "foo" WHEN 'bar' THEN 'baz' END`, - }, - { - name: "arithmetic expression", - fields: &tree.ExpressionArithmetic{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionNumericLiteral{ - Value: 1, - }, - }, - want: `"foo" + 1`, - }, - { - name: "arithmetic expression with type cast", - fields: &tree.ExpressionArithmetic{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionNumericLiteral{ - Value: 1, - }, - TypeCast: types.IntType, - Wrapped: true, - }, - want: `("foo" + 1) ::INT8`, - }, - { - name: "arithmetic expression with type cast without wrapped", - fields: &tree.ExpressionArithmetic{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ArithmeticOperatorAdd, - Right: &tree.ExpressionTextLiteral{ - Value: "1", - }, - TypeCast: types.IntType, - }, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("Expression.ToSQL() should have panicked") - } - }() - } - - got := tt.fields.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("Expression.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/expressions.md b/parse/sql/tree/expressions.md deleted file mode 100644 index e990f9b9d..000000000 --- a/parse/sql/tree/expressions.md +++ /dev/null @@ -1,318 +0,0 @@ -# Expressions - -Expressions are valuatable clauses that are comprised of literals, identifiers, comparisons, functions, subqueries, and other expressions. All expressions are interchangeable, however they will not all necessarily create valid statements. - -#### ExpressionLiteral - -An expression literal is used to define any concrete, static value. These are things like strings, integers, and floating point numbers. Floating point numbers will immediately be rounded when they are passed to the engine. - -```go -type ExpressionLiteral struct { - Value interface{} -} -``` - -_In SQL:_ - -```sql -INSERT INTO users (username, age) -VALUES ( - /*string literal:*/ 'satoshi', - /*integer literal:*/ 42 -); -``` - -#### ExpressionBindParameter - -An expression bind parameter is used to denote user input. User's can store statements containing bind parameters in their database engine, and later execute them, while passing in different values for the parameter. - -They can also be used as a method to protect against SQL injection, since the engine compiles statements before parameters are bound to the database. This means that, even in the case of users passing an otherwise valid SQL injection, the system will still treat it purely asn a string. - -In Kwil, all bind parameters that accept user inputs must begin with a "$". For global variables, such as a transaction caller's wallet address, bind parameters must begin with "@". - -```go -type ExpressionBindParameter struct { - Parameter string -} -``` - -_In SQL:_ - -```sql -UPDATE users -SET username = /*user bind parameter*/ $new_username, -age = /*user bind parameter*/ $new_age -WHERE wallet_address = /*global bind parameter*/ @caller -AND id = /*user bind parameter*/ $target_id; -``` - -_This statement allows a user to update a user record's username and age only if the value in the "wallet_address" column matches their address._ - -#### ExpressionColumn - -A column expression is used to specify a column that should be used in a query. It can also take a table name, which is necessary if you are using multiple tables (e.g. in a statement containing a join). - -```go -type ExpressionColumn struct { - Table string - Column string -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM followers -INNER JOIN users -## Expressions containing table.column: -ON users.id = followers.followed_id -WHERE followers.follower_id = $user_id; -``` - -#### ExpressionBinaryComparison - -A binary comparison expression is used to compare two expressions against each other. This is commonly used in WHERE predicates to specify desired result attributes. - -The expressions are compared using a binary operator (TODO: link to operators page). - -```go -type ExpressionBinaryComparison struct { - Left Expression - Operator BinaryOperator - Right Expression -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -## Binary comparison in a where clause: -WHERE age > 20 -``` - -#### ExpressionFunction - -A function is used to execute some pre-defined functionality on a value or set of values. A full list of Kwil's supported functions can be found here: TODO: link - -```go -type ExpressionFunction struct { - Function SQLFunction - Inputs []Expression -} -``` - -_In SQL:_ - -```sql -INSERT INTO users (username, age) -## Using an "abs" function to get the absolute value of an integer -VALUES ($new_username, abs($new_age)); -``` - -#### ExpressionList - -An expression list is simply a list of other expressions, wrapped in parenthesis and delimited by commas. - -```go -type ExpressionList struct { - Expressions []Expression -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -## A list of expression literals, within a binary comparison -WHERE username IN ('satoshi', 'hal_finney', 'roger_ver'); -``` - -#### ExpressionCollate - -A collation is used to specify the bitset that should be used when comparing values. Kwil has 3 predefined collation types, and currently does not support custom collations. The 3 supported are: - -- BINARY: Compares values based on their binary representation, which makes string comparisons case-sensitive and accent-sensitive. -- RTRIM: Compares strings while ignoring trailing whitespace. -- NOCASE: Compares strings case-insensitively. - -```go -type ExpressionCollate struct { - Expression Expression - Collation CollationType -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -WHERE username = 'sAtOshI' -## case-insensitive collation: -COLLATE NOCASE; -``` - -#### ExpressionStringCompare - -A string comparison expression is used to compare two strings against each other. It also has an escape clause, which is used to escape characters. The escape clause can only be used with LIKE and NOT LIKE string operators. - -For a full list of string operators, see the operators page TODO: link to operators. - -```go -type ExpressionStringCompare struct { - Left Expression - Operator StringOperator - Right Expression - Escape Expression // can only be used with LIKE or NOT LIKE -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -## LIKE comparison with ESCAPE clause -WHERE username LIKE '%\_finney' ESCAPE '\'; -``` - -#### ExpressionIsNull - -An IsNull expression is used to determine whether or not the result of some expression is null. - -```go -type ExpressionIsNull struct { - Expression Expression - IsNull bool -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM posts -## getting all posts that have a body -WHERE content NOT NULL -``` - -#### ExpressionDistinct - -A distinct expression is used to determine whether or not two expressions evaluate to distinct results from one another. - -```go -type ExpressionDistinct struct { - Left Expression - Right Expression - IsNot bool - Distinct bool -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -# Getting all users distinctly different from satoshi. -WHERE username IS DISTINCT FROM 'satoshi'; -``` - -#### ExpressionBetween - -A between expression is used to filter values that are between the results of two other expressions. - -```go -type ExpressionBetween struct { - Expression Expression - NotBetween bool - Left Expression - Right Expression -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM users -# filtering results of a column between two integer literals -WHERE age BETWEEN 18 AND 30; -``` - -#### ExpressionIn - -An In expression is used to specify values that are within some set of values. - -```go -type ExpressionIn struct { - Expression Expression - NotIn bool - InExpressions []Expression -} -``` - -_In SQL:_ - -```sql -SELECT * -FROM posts -# Getting posts from a set of authors -WHERE author_id IN ('satoshi', 'hal_finney', 'roger_ver'); -``` - -#### ExpressionSelect - -The select expression, also known as a subquery, allows users to specify results of a SELECT that should be used in a query. In most cases, this has to be a "scalar subquery"; that is, it can only return one column. This is not enforced at the statement validation level, but instead at the execution level. - -```go -type ExpressionSelect struct { - IsNot bool - IsExists bool - Select *SelectStmt -} -``` - -_In SQL:_ - -```sql -INSERT INTO posts (id, title, content, author_id) -# A scalar subquery used to get the user_id of the caller -VALUES ($id, $title, $content, ( - SELECT id - FROM users - WHERE wallet_address = @caller - ) -); -``` - -#### ExpressionCase - -A case expression is the logical equivalent of an IF... THEN... ELSE... statement, where conditions are checked until one is met. - -```go -type ExpressionCase struct { - CaseExpression Expression - WhenThenPairs [][2]Expression - ElseExpression Expression -} -``` - -_In SQL:_ - -```sql -SELECT username, -# If users have an age, we will identify the age classification - CASE age NOT NULL - WHEN age > 65 THEN 'Senior' - WHEN age > 35 THEN 'Middle-Age' - WHEN age > 18 THEN 'Young-Adult' - ELSE 'Minor' - END -AS age_classification -FROM users; -``` diff --git a/parse/sql/tree/group-by.go b/parse/sql/tree/group-by.go deleted file mode 100644 index 85cde271a..000000000 --- a/parse/sql/tree/group-by.go +++ /dev/null @@ -1,47 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type GroupBy struct { - types.Node - - Expressions []Expression - Having Expression -} - -func (g *GroupBy) Accept(v AstVisitor) any { - return v.VisitGroupBy(g) -} - -func (g *GroupBy) Walk(w AstListener) error { - return run( - w.EnterGroupBy(g), - walkMany(w, g.Expressions), - walk(w, g.Having), - w.ExitGroupBy(g), - ) -} - -func (g *GroupBy) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(g.Expressions) == 0 { - panic("no expressions provided to GroupBy") - } - - stmt.Token.Group().By() - - stmt.WriteList(len(g.Expressions), func(i int) { - stmt.WriteString(g.Expressions[i].ToSQL()) - }) - - if g.Having != nil { - stmt.Token.Having() - stmt.WriteString(g.Having.ToSQL()) - } - - return stmt.String() -} diff --git a/parse/sql/tree/group-by_test.go b/parse/sql/tree/group-by_test.go deleted file mode 100644 index 91b6375ad..000000000 --- a/parse/sql/tree/group-by_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestGroupBy_ToSQL(t *testing.T) { - type fields struct { - Expressions []tree.Expression - Having tree.Expression - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid group by", - fields: fields{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{Column: "foo"}, - }, - }, - want: ` GROUP BY "foo"`, - }, - { - name: "valid group by with having", - fields: fields{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{Column: "foo"}, - &tree.ExpressionColumn{Column: "bar"}, - }, - Having: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "foo"}, - Operator: tree.ComparisonOperatorGreaterThan, - Right: &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - }, - want: ` GROUP BY "foo", "bar" HAVING "foo" > $a`, - }, - { - name: "no expressions", - fields: fields{ - Expressions: []tree.Expression{}, - }, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - g := &tree.GroupBy{ - Expressions: tt.fields.Expressions, - Having: tt.fields.Having, - } - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("GroupBy.ToSQL() should have panicked") - } - }() - } - - got := g.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("GroupBy.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/indexed-column.go b/parse/sql/tree/indexed-column.go deleted file mode 100644 index 186d65f01..000000000 --- a/parse/sql/tree/indexed-column.go +++ /dev/null @@ -1,45 +0,0 @@ -package tree - -// * AFAIK this is a correct implementation of SQLITE's IndexedColumn, but it is not needed now - -/* -type IndexedColumn struct { - Column string - Expression Expression - Collation CollationType - OrderType OrderType -} - -func (i *IndexedColumn) ToSQL() string { - i.check() - - stmt := sqlwriter.NewWriter() - - if i.Expression == nil { - stmt.WriteIdent(i.Column) - } else { - stmt.WriteString(i.Expression.ToSQL()) - } - - if i.Collation != "" { - stmt.Token.Collate() - stmt.WriteString(i.Collation.String()) - } - - if i.OrderType != OrderTypeNone { - stmt.WriteString(i.OrderType.String()) - } - - return stmt.String() -} - -func (i *IndexedColumn) check() { - if i.Column == "" && i.Expression == nil { - panic("column and expression cannot both be empty") - } - - if i.Column != "" && i.Expression != nil { - panic("column and expression cannot both be set") - } -} -*/ diff --git a/parse/sql/tree/indexed-column_test.go b/parse/sql/tree/indexed-column_test.go deleted file mode 100644 index c81a2cbc5..000000000 --- a/parse/sql/tree/indexed-column_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package tree_test - -/* -func TestIndexedColumn_ToSQL(t *testing.T) { - type fields struct { - Column string - Expression tree.Expression - Collation tree.CollationType - OrderType tree.OrderType - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "column and expression cannot both be empty", - fields: fields{ - Column: "", - Expression: nil, - Collation: tree.CollationTypeBinary, - OrderType: tree.OrderTypeNone, - }, - wantPanic: true, - }, - { - name: "column and expression cannot both be set", - fields: fields{ - Column: "column", - Expression: &tree.ExpressionLiteral{"'expression'"}, - Collation: tree.CollationTypeBinary, - OrderType: tree.OrderTypeNone, - }, - wantPanic: true, - }, - { - name: "valid indexed-column with column", - fields: fields{ - Column: "col1", - Collation: tree.CollationTypeRTrim, - OrderType: tree.OrderTypeAsc, - }, - want: `"col1" COLLATE RTRIM ASC`, - }, - { - name: "valid indexed-column with expression", - fields: fields{ - Expression: &tree.ExpressionLiteral{"'expr'"}, - Collation: tree.CollationTypeRTrim, - OrderType: tree.OrderTypeAsc, - }, - want: "'expr' COLLATE RTRIM ASC", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - - defer func() { - if r := recover(); r != nil { - if !tt.wantPanic { - t.Errorf("IndexedColumn.ToSQL() panicked with %v", r) - } - } - }() - - i := &tree.IndexedColumn{ - Column: tt.fields.Column, - Expression: tt.fields.Expression, - Collation: tt.fields.Collation, - OrderType: tt.fields.OrderType, - } - got := i.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("IndexedColumn.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} -*/ diff --git a/parse/sql/tree/insert.go b/parse/sql/tree/insert.go deleted file mode 100644 index eb41697b8..000000000 --- a/parse/sql/tree/insert.go +++ /dev/null @@ -1,176 +0,0 @@ -package tree - -import ( - "fmt" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type InsertStmt struct { - types.Node - - CTE []*CTE - Core *InsertCore -} - -func (ins *InsertStmt) Accept(v AstVisitor) any { - return v.VisitInsertStmt(ins) -} - -func (ins *InsertStmt) Walk(w AstListener) error { - return run( - w.EnterInsertStmt(ins), - walkMany(w, ins.CTE), - walk(w, ins.Core), - w.ExitInsertStmt(ins), - ) -} - -func (ins *InsertStmt) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(ins.CTE) > 0 { - stmt.Token.With() - stmt.WriteList(len(ins.CTE), func(i int) { - stmt.WriteString(ins.CTE[i].ToSQL()) - }) - } - - stmt.WriteString(ins.Core.ToSQL()) - - stmt.Token.Semicolon() - - return stmt.String() -} - -func (ins *InsertStmt) statement() {} - -type InsertCore struct { - types.Node - - schema string - InsertType InsertType - Table string - TableAlias string - Columns []string - Values [][]Expression - Upsert *Upsert - ReturningClause *ReturningClause -} - -func (ins *InsertCore) Accept(v AstVisitor) any { - return v.VisitInsertCore(ins) -} - -func (ins *InsertCore) Walk(w AstListener) error { - return run( - w.EnterInsertCore(ins), - func() error { - for _, v := range ins.Values { - err := walkMany(w, v) - if err != nil { - return err - } - } - return nil - }(), - walk(w, ins.Upsert), - walk(w, ins.ReturningClause), - w.ExitInsertCore(ins), - ) -} - -// SetSchema sets the schema of the table. -// It should not be called by the parser, and is meant to be called -// by processes after parsing. -func (ins *InsertCore) SetSchema(schema string) { - ins.schema = schema -} - -type InsertType uint8 - -const ( - InsertTypeInsert InsertType = iota -) - -func (i InsertType) Valid() error { - switch i { - case InsertTypeInsert: - return nil - default: - return fmt.Errorf("invalid insert type: %d", i) - } -} - -func (i *InsertType) String() string { - switch *i { - case InsertTypeInsert: - return "INSERT" - default: - panic(fmt.Errorf("unknown InsertType: %d", *i)) - } -} - -func (ins *InsertCore) ToSQL() string { - ins.check() - - stmt := sqlwriter.NewWriter() - stmt.WriteString(ins.InsertType.String()) - stmt.Token.Into() - - if ins.schema != "" { - stmt.Token.Space() - stmt.WriteIdentNoSpace(ins.schema) - stmt.Token.Period() - stmt.WriteIdentNoSpace(ins.Table) - stmt.Token.Space() - } else { - stmt.WriteIdent(ins.Table) - } - - if ins.TableAlias != "" { - stmt.Token.As() - stmt.WriteIdent(ins.TableAlias) - } - if len(ins.Columns) > 0 { - stmt.WriteParenList(len(ins.Columns), func(i int) { - stmt.WriteIdent(ins.Columns[i]) - }) - } - - stmt.Token.Values() - for i := range ins.Values { - if i > 0 && i < len(ins.Values) { - stmt.Token.Comma() - } - - stmt.WriteParenList(len(ins.Values[i]), func(j int) { - stmt.WriteString(ins.Values[i][j].ToSQL()) - }) - } - - if ins.Upsert != nil { - stmt.WriteString(ins.Upsert.ToSQL()) - } - - if ins.ReturningClause != nil { - stmt.WriteString(ins.ReturningClause.ToSQL()) - } - - return stmt.String() -} - -func (ins *InsertCore) check() { - if ins.Table == "" { - panic("InsertStatement: table name is empty") - } - - if len(ins.Values) == 0 { - panic("InsertStatement: values is empty") - } - - if ins.Upsert != nil && ins.InsertType != InsertTypeInsert { - panic("InsertStatement: upsert is only allowed for INSERT") - } -} diff --git a/parse/sql/tree/insert_test.go b/parse/sql/tree/insert_test.go deleted file mode 100644 index cc93b251d..000000000 --- a/parse/sql/tree/insert_test.go +++ /dev/null @@ -1,241 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestInsert_ToSQL(t *testing.T) { - type fields struct { - CTE []*tree.CTE - InsertStmt *tree.InsertCore - Schema string - } - tests := []struct { - name string - fields fields - wantStr string - wantErr bool - }{ - { - name: "valid insert", - fields: fields{ - CTE: []*tree.CTE{ - mockCTE, - }, - InsertStmt: &tree.InsertCore{ - InsertType: tree.InsertTypeInsert, - Table: "foo", - Columns: []string{"bar", "baz"}, - Values: [][]tree.Expression{ - { - &tree.ExpressionTextLiteral{Value: "barVal"}, - &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - { - &tree.ExpressionTextLiteral{Value: "bazVal"}, - &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - }, - Upsert: &tree.Upsert{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"bar", "baz"}, - }, - Type: tree.UpsertTypeDoNothing, - }, - ReturningClause: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - }, - }, - wantStr: `WITH ` + mockCTE.ToSQL() + ` INSERT INTO "foo" ("bar", "baz") VALUES ('barVal', $a), ('bazVal', $b) ON CONFLICT ("bar", "baz") DO NOTHING RETURNING *;`, - }, - { - name: "insert to namespaced", - fields: fields{ - InsertStmt: &tree.InsertCore{ - InsertType: tree.InsertTypeInsert, - Table: "bar", - Columns: []string{"baz"}, - Values: [][]tree.Expression{ - { - &tree.ExpressionTextLiteral{Value: "bazVal"}, - }, - }, - }, - Schema: "public", - }, - wantStr: `INSERT INTO "public"."bar" ("baz") VALUES ('bazVal');`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ins := &tree.InsertStmt{ - CTE: tt.fields.CTE, - Core: tt.fields.InsertStmt, - } - - if tt.fields.Schema != "" { - ins.Core.SetSchema(tt.fields.Schema) - } - - gotStr, err := tree.SafeToSQL(ins) - if (err != nil) != tt.wantErr { - t.Errorf("InsertStmt.ToSQL() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !compareIgnoringWhitespace(gotStr, tt.wantStr) { - t.Errorf("InsertStmt.ToSQL() = %v, want %v", gotStr, tt.wantStr) - } - }) - } -} - -func TestInsertStatement_ToSql(t *testing.T) { - type fields struct { - InsertType tree.InsertType - Table string - TableAlias string - Columns []string - Values [][]tree.Expression - Upsert *tree.Upsert - ReturningClause *tree.ReturningClause - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid insert", - fields: fields{ - InsertType: tree.InsertTypeInsert, - Table: "foo", - TableAlias: "f", - Columns: []string{ - "barCol", - "bazCol", - }, - Values: [][]tree.Expression{ - { - &tree.ExpressionTextLiteral{Value: "barVal"}, - &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - { - &tree.ExpressionTextLiteral{Value: "bazVal"}, - &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - }, - Upsert: &tree.Upsert{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"barCol", "bazCol"}, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionTextLiteral{ - Value: "barVal", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - { - Columns: []string{"barCol"}, - Expression: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionTextLiteral{ - Value: "barVal", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - ReturningClause: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - }, - want: `INSERT INTO "foo" AS "f" ("barCol", "bazCol") VALUES ('barVal', $a), ('bazVal', $b) ON CONFLICT ("barCol", "bazCol") WHERE 'barVal' = $a DO UPDATE SET "barCol" = $a WHERE 'barVal' = $a RETURNING *`, - wantPanic: false, - }, - { - name: "insert without table", - fields: fields{ - InsertType: tree.InsertTypeInsert, - Columns: []string{ - "barCol", - "bazCol", - }, - Values: [][]tree.Expression{ - { - &tree.ExpressionTextLiteral{Value: "barVal"}, - &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - { - &tree.ExpressionTextLiteral{Value: "bazVal"}, - &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - }, - }, - wantPanic: true, - }, - { - name: "insert without values", - fields: fields{ - InsertType: tree.InsertTypeInsert, - Table: "foo", - Columns: []string{ - "barCol", - "bazCol", - }, - }, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("InsertStatement.ToSql() should have panicked") - } - }() - } - - i := &tree.InsertCore{ - InsertType: tt.fields.InsertType, - Table: tt.fields.Table, - TableAlias: tt.fields.TableAlias, - Columns: tt.fields.Columns, - Values: tt.fields.Values, - Upsert: tt.fields.Upsert, - ReturningClause: tt.fields.ReturningClause, - } - got := i.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("InsertStatement.ToSql() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/join.go b/parse/sql/tree/join.go deleted file mode 100644 index a71dcc8d2..000000000 --- a/parse/sql/tree/join.go +++ /dev/null @@ -1,164 +0,0 @@ -package tree - -import ( - "fmt" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// TODO: update this docs to reflect the current state of the code -/* -From the SQLite documentation: - If the join-operator is "CROSS JOIN", "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING clause, - then the result of the join is simply the cartesian product of the left and right-hand datasets. - If join-operator does have ON or USING clauses, those are handled according to the following bullet points: - - - If there is an ON clause then the ON expression is evaluated for each row of the cartesian product as a boolean expression. - Only rows for which the expression evaluates to true are included from the dataset. - - - If there is a USING clause then each of the column names specified must exist in the datasets to both the left - and right of the join-operator. For each pair of named columns, the expression "lhs.X = rhs.X" is evaluated for - each row of the cartesian product as a boolean expression. Only rows for which all such expressions evaluates to - true are included from the result set. When comparing values as a result of a USING clause, the normal rules for - handling affinities, collation sequences and NULL values in comparisons apply. The column from the dataset on - the left-hand side of the join-operator is considered to be on the left-hand side of the comparison operator (=) - for the purposes of collation sequence and affinity precedence. - - - For each pair of columns identified by a USING clause, the column from the right-hand dataset is omitted from the joined dataset. - This is the only difference between a USING clause and its equivalent ON constraint. - - - If the NATURAL keyword is in the join-operator then an implicit USING clause is added to the join-constraints. - The implicit USING clause contains each of the column names that appear in both the left and right-hand input datasets. - If the left and right-hand input datasets feature no common column names, then the NATURAL keyword has no effect on the - results of the join. A USING or ON clause may not be added to a join that specifies the NATURAL keyword. - - - If the join-operator is a "LEFT JOIN" or "LEFT OUTER JOIN", then after the ON or USING filtering clauses have been applied, - an extra row is added to the output for each row in the original left-hand input dataset that does not match any row in the - right-hand dataset. The added rows contain NULL values in the columns that would normally contain values copied from the right-hand input dataset. - - - If the join-operator is a "RIGHT JOIN" or "RIGHT OUTER JOIN", then after the ON or USING filtering clauses have been applied, - an extra row is added to the output for each row in the original right-hand input dataset that does not match any row in the - left-hand dataset. The added rows contain NULL values in the columns that would normally contain values copied from the left-hand input dataset. - - - A "FULL JOIN" or "FULL OUTER JOIN" is a combination of a "LEFT JOIN" and a "RIGHT JOIN". Extra rows of output are added - for each row in left dataset that matches no rows in the right, and for each row in the right dataset that matches no rows in the left. - Unmatched columns are filled in with NULL. - - When more than two tables are joined together as part of a FROM clause, the join operations are processed in order from left to right. - In other words, the FROM clause (A join-op-1 B join-op-2 C) is computed as ((A join-op-1 B) join-op-2 C). -*/ - -type JoinPredicate struct { - types.Node - - JoinOperator *JoinOperator - Table Relation - Constraint Expression -} - -func (j *JoinPredicate) Walk(w AstListener) error { - return run( - w.EnterJoinPredicate(j), - walk(w, j.JoinOperator), - walk(w, j.Table), - walk(w, j.Constraint), - w.ExitJoinPredicate(j), - ) -} - -func (j *JoinPredicate) ToSQL() string { - if j.Constraint == nil { - panic("join 'ON' cannot be nil") - } - if j.Constraint.joinable() != joinableStatusValid { - panic("invalid join constraint") - } - if j.JoinOperator == nil { - panic("join operator cannot be nil") - } - if j.Table == nil { - panic("join table cannot be nil") - } - - stmt := sqlwriter.NewWriter() - stmt.WriteString(j.JoinOperator.ToSQL()) - stmt.WriteString(j.Table.ToSQL()) - stmt.Token.On() - stmt.WriteString(j.Constraint.ToSQL()) - - return stmt.String() -} - -func (j *JoinPredicate) Accept(v AstVisitor) any { - return v.VisitJoinPredicate(j) -} - -type JoinOperator struct { - types.Node - - JoinType JoinType - Outer bool -} - -func (j *JoinOperator) Accept(v AstVisitor) any { - return v.VisitJoinOperator(j) -} - -func (j *JoinOperator) Walk(w AstListener) error { - return run( - w.EnterJoinOperator(j), - w.ExitJoinOperator(j), - ) -} - -type JoinType uint8 - -const ( - JoinTypeJoin JoinType = iota - JoinTypeInner - JoinTypeLeft - JoinTypeRight - JoinTypeFull -) - -func (j *JoinOperator) ToSQL() string { - stmt := sqlwriter.NewWriter() - - switch j.JoinType { - case JoinTypeJoin: - // do nothing - case JoinTypeInner: - stmt.Token.Inner() - case JoinTypeLeft: - stmt.Token.Left() - case JoinTypeRight: - stmt.Token.Right() - case JoinTypeFull: - stmt.Token.Full() - default: - panic("invalid join type: " + fmt.Sprint(j.JoinType)) - } - - if j.Outer { - if j.JoinType == JoinTypeInner || j.JoinType == JoinTypeJoin { - panic("outer join cannot be used with generic join or inner join") - } - stmt.Token.Outer() - } - - stmt.Token.Join() - return stmt.String() -} - -func (j *JoinOperator) Valid() error { - if j.JoinType < JoinTypeJoin || j.JoinType > JoinTypeFull { - return fmt.Errorf("invalid join type: %d", j.JoinType) - } - - if j.Outer && (j.JoinType == JoinTypeJoin || j.JoinType == JoinTypeInner) { - return fmt.Errorf("outer join cannot be used with generic join or inner join") - } - - return nil -} diff --git a/parse/sql/tree/limit.go b/parse/sql/tree/limit.go deleted file mode 100644 index dc1bc86c9..000000000 --- a/parse/sql/tree/limit.go +++ /dev/null @@ -1,46 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// Limit is a LIMIT clause. -// It takes an expression, and can optionally take either an offset or a second expression. -type Limit struct { - types.Node - - Expression Expression - Offset Expression -} - -func (l *Limit) Accept(v AstVisitor) any { - return v.VisitLimit(l) -} - -func (l *Limit) Walk(w AstListener) error { - return run( - w.EnterLimit(l), - walk(w, l.Expression), - walk(w, l.Offset), - w.ExitLimit(l), - ) -} - -// ToSQL marshals a LIMIT clause into a SQL string. -func (l *Limit) ToSQL() string { - stmt := sqlwriter.NewWriter() - if l.Expression == nil { - panic("no expression provided to Limit") - } - - stmt.Token.Limit() - stmt.WriteString(l.Expression.ToSQL()) - - if l.Offset != nil { - stmt.Token.Offset() - stmt.WriteString(l.Offset.ToSQL()) - } - - return stmt.String() -} diff --git a/parse/sql/tree/limit_test.go b/parse/sql/tree/limit_test.go deleted file mode 100644 index 0bedd761f..000000000 --- a/parse/sql/tree/limit_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestLimit_ToSQL(t *testing.T) { - type fields struct { - Expression tree.Expression - Offset tree.Expression - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid limit", - fields: fields{ - Expression: &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - want: ` LIMIT $a`, - }, - { - name: "valid limit with offset", - fields: fields{ - Expression: &tree.ExpressionBindParameter{Parameter: "$a"}, - Offset: &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - want: ` LIMIT $a OFFSET $b`, - }, - { - name: "no expression", - fields: fields{}, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - l := &tree.Limit{ - Expression: tt.fields.Expression, - Offset: tt.fields.Offset, - } - - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("Limit.ToSQL() should have panicked") - } - }() - } - - got := l.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("Limit.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/operators.go b/parse/sql/tree/operators.go deleted file mode 100644 index 93a2e9940..000000000 --- a/parse/sql/tree/operators.go +++ /dev/null @@ -1,131 +0,0 @@ -package tree - -import "fmt" - -type BinaryOperator interface { - binary() - String() string - Valid() error -} - -type ArithmeticOperator string - -const ( - ArithmeticOperatorAdd ArithmeticOperator = "+" - ArithmeticOperatorSubtract ArithmeticOperator = "-" - ArithmeticOperatorMultiply ArithmeticOperator = "*" - ArithmeticOperatorDivide ArithmeticOperator = "/" - ArithmeticOperatorModulus ArithmeticOperator = "%" -) - -func (a ArithmeticOperator) String() string { - return string(a) -} - -func (a ArithmeticOperator) Valid() error { - switch a { - case ArithmeticOperatorAdd, ArithmeticOperatorSubtract, ArithmeticOperatorMultiply, ArithmeticOperatorDivide, ArithmeticOperatorModulus: - return nil - default: - return fmt.Errorf("invalid arithmetic operator: %s", a) - } -} - -type ComparisonOperator string - -const ( - ComparisonOperatorEqual ComparisonOperator = "=" - ComparisonOperatorNotEqualDiamond ComparisonOperator = "<>" - ComparisonOperatorNotEqual ComparisonOperator = "!=" - ComparisonOperatorGreaterThan ComparisonOperator = ">" - ComparisonOperatorLessThan ComparisonOperator = "<" - ComparisonOperatorGreaterThanOrEqual ComparisonOperator = ">=" - ComparisonOperatorLessThanOrEqual ComparisonOperator = "<=" - ComparisonOperatorIn ComparisonOperator = "IN" - ComparisonOperatorNotIn ComparisonOperator = "NOT IN" -) - -func (c ComparisonOperator) binary() {} -func (c ComparisonOperator) String() string { - return string(c) -} - -func (c ComparisonOperator) Valid() error { - switch c { - case ComparisonOperatorEqual, ComparisonOperatorNotEqualDiamond, ComparisonOperatorNotEqual, ComparisonOperatorGreaterThan, ComparisonOperatorLessThan, ComparisonOperatorGreaterThanOrEqual, ComparisonOperatorLessThanOrEqual, ComparisonOperatorIn, ComparisonOperatorNotIn: - return nil - default: - return fmt.Errorf("invalid comparison operator: %s", c) - } -} - -type LogicalOperator string - -const ( - LogicalOperatorAnd LogicalOperator = "AND" - LogicalOperatorOr LogicalOperator = "OR" -) - -func (l LogicalOperator) binary() {} -func (l LogicalOperator) String() string { - return string(l) -} - -func (l LogicalOperator) Valid() error { - switch l { - case LogicalOperatorAnd, LogicalOperatorOr: - return nil - default: - return fmt.Errorf("invalid logical operator: %s", l) - } -} - -type StringOperator string - -const ( - StringOperatorLike StringOperator = "LIKE" - StringOperatorNotLike StringOperator = "NOT LIKE" -) - -func (s StringOperator) binary() {} -func (s StringOperator) String() string { - return string(s) -} -func (s StringOperator) Valid() error { - switch s { - case StringOperatorLike, StringOperatorNotLike: - return nil - default: - return fmt.Errorf("invalid string operator: %s", s) - } -} -func (s StringOperator) Escapable() bool { - switch s { - case StringOperatorLike, StringOperatorNotLike: - return true - default: - return false - } -} - -type UnaryOperator string - -const ( - UnaryOperatorPlus UnaryOperator = "+" - UnaryOperatorMinus UnaryOperator = "-" - UnaryOperatorNot UnaryOperator = "NOT" - //UnaryOperatorBitNot UnaryOperator = "~" -) - -func (u UnaryOperator) String() string { - return string(u) -} - -func (u UnaryOperator) Valid() error { - switch u { - case UnaryOperatorPlus, UnaryOperatorMinus, UnaryOperatorNot: - return nil - default: - return fmt.Errorf("invalid unary operator: %s", u) - } -} diff --git a/parse/sql/tree/order-by.go b/parse/sql/tree/order-by.go deleted file mode 100644 index a8259147f..000000000 --- a/parse/sql/tree/order-by.go +++ /dev/null @@ -1,132 +0,0 @@ -package tree - -import ( - "fmt" - "strings" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type OrderBy struct { - types.Node - - OrderingTerms []*OrderingTerm -} - -func (o *OrderBy) Accept(v AstVisitor) any { - return v.VisitOrderBy(o) -} - -func (o *OrderBy) Walk(w AstListener) error { - return run( - w.EnterOrderBy(o), - walkMany(w, o.OrderingTerms), - w.ExitOrderBy(o), - ) -} - -func (o *OrderBy) ToSQL() string { - stmt := sqlwriter.NewWriter() - - stmt.Token.Order().By() - - if len(o.OrderingTerms) == 0 { - panic("no ordering terms provided to OrderBy") - } - - stmt.WriteList(len(o.OrderingTerms), func(i int) { - stmt.WriteString(o.OrderingTerms[i].ToSQL()) - }) - - return stmt.String() -} - -type OrderingTerm struct { - types.Node - - Expression Expression - OrderType OrderType - NullOrdering NullOrderingType -} - -func (o *OrderingTerm) Accept(v AstVisitor) any { - return v.VisitOrderingTerm(o) -} - -func (o *OrderingTerm) Walk(w AstListener) error { - return run( - w.EnterOrderingTerm(o), - walk(w, o.Expression), - w.ExitOrderingTerm(o), - ) -} - -func (o *OrderingTerm) ToSQL() string { - stmt := sqlwriter.NewWriter() - - stmt.WriteString(o.Expression.ToSQL()) - - if o.OrderType != OrderTypeNone { - stmt.WriteString(o.OrderType.String()) - } - - if o.NullOrdering != NullOrderingTypeNone { - stmt.WriteString(o.NullOrdering.String()) - } - - return stmt.String() -} - -type NullOrderingType string - -const ( - NullOrderingTypeNone NullOrderingType = "" - NullOrderingTypeFirst NullOrderingType = "NULLS FIRST" - NullOrderingTypeLast NullOrderingType = "NULLS LAST" -) - -func (n NullOrderingType) String() string { - return string(n) -} - -func (n NullOrderingType) Valid() error { - if n != NullOrderingTypeFirst && n != NullOrderingTypeLast && n != NullOrderingTypeNone { - return fmt.Errorf("invalid null ordering type: %s", n) - } - - return nil -} - -type OrderType string - -const ( - OrderTypeNone OrderType = "" - OrderTypeAsc OrderType = "ASC" - OrderTypeDesc OrderType = "DESC" -) - -func (o OrderType) String() string { - o.check() - return string(o) -} - -func (o OrderType) check() { - - err := o.Valid() - if err != nil { - panic(err) - } -} - -func (o *OrderType) Valid() error { - upper := OrderType(strings.ToUpper(string(*o))) - - if upper != OrderTypeAsc && upper != OrderTypeDesc && upper != OrderTypeNone { - return fmt.Errorf("invalid order type: %s", o) - } - - *o = upper - - return nil -} diff --git a/parse/sql/tree/order-by_test.go b/parse/sql/tree/order-by_test.go deleted file mode 100644 index 5e30e3790..000000000 --- a/parse/sql/tree/order-by_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestOrderBy_ToSQL(t *testing.T) { - type fields struct { - OrderingTerms []*tree.OrderingTerm - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid order by with multiple terms", - fields: fields{ - OrderingTerms: []*tree.OrderingTerm{ - { - Expression: &tree.ExpressionColumn{Column: "foo"}, - }, - { - Expression: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "bar"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionCollate{ - Expression: &tree.ExpressionBindParameter{Parameter: "$a"}, - Collation: tree.CollationTypeNoCase, - }, - }, - OrderType: tree.OrderTypeDesc, - NullOrdering: tree.NullOrderingTypeFirst, - }, - }, - }, - want: ` ORDER BY "foo", "bar" = $a COLLATE NOCASE DESC NULLS FIRST`, - }, - { - name: "no ordering terms", - fields: fields{}, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - o := &tree.OrderBy{ - OrderingTerms: tt.fields.OrderingTerms, - } - - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("OrderBy.ToSQL() should have panicked") - } - }() - } - - got := o.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("OrderBy.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/qualified-table-name.go b/parse/sql/tree/qualified-table-name.go deleted file mode 100644 index b7e6992a0..000000000 --- a/parse/sql/tree/qualified-table-name.go +++ /dev/null @@ -1,63 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// QualifiedTableName is a table name that is qualified with a schema and can be aliased. -// It is used in UPDATE and DELETE statements to specify the target table. -type QualifiedTableName struct { - types.Node - - schema string - TableName string - TableAlias string -} - -func (q *QualifiedTableName) Accept(v AstVisitor) any { - return v.VisitQualifiedTableName(q) -} - -func (q *QualifiedTableName) Walk(w AstListener) error { - return run( - w.EnterQualifiedTableName(q), - w.ExitQualifiedTableName(q), - ) -} - -func (q *QualifiedTableName) ToSQL() string { - q.check() - - stmt := sqlwriter.NewWriter() - - if q.schema != "" { - stmt.Token.Space() - stmt.WriteIdentNoSpace(q.schema) - stmt.Token.Period() - stmt.WriteIdentNoSpace(q.TableName) - stmt.Token.Space() - } else { - stmt.WriteIdent(q.TableName) - } - - if q.TableAlias != "" { - stmt.Token.As() - stmt.WriteIdent(q.TableAlias) - } - - return stmt.String() -} - -func (q *QualifiedTableName) check() { - if q.TableName == "" { - panic("table name is empty") - } -} - -// SetSchema sets the schema of the table. -// It should not be called by the parser, and is meant to be called -// by processes after parsing. -func (q *QualifiedTableName) SetSchema(schema string) { - q.schema = schema -} diff --git a/parse/sql/tree/qualified-table-name_test.go b/parse/sql/tree/qualified-table-name_test.go deleted file mode 100644 index f4e274f68..000000000 --- a/parse/sql/tree/qualified-table-name_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestQualifiedTableName_ToSQL(t *testing.T) { - type fields struct { - TableName string - TableAlias string - Schema string // optional - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid table name", - fields: fields{ - TableName: "foo", - TableAlias: "f", - }, - want: `"foo" AS "f"`, - }, - { - name: "no table name", - fields: fields{ - TableAlias: "f", - }, - wantPanic: true, - }, - { - name: "schema", - fields: fields{ - TableName: "foo", - Schema: "baz", - }, - want: `"baz"."foo"`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("QualifiedTableName.ToSQL() should have panicked") - } - }() - } - - q := &tree.QualifiedTableName{ - TableName: tt.fields.TableName, - TableAlias: tt.fields.TableAlias, - } - - if tt.fields.Schema != "" { - q.SetSchema(tt.fields.Schema) - } - - got := q.ToSQL() - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("QualifiedTableName.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/relation.go b/parse/sql/tree/relation.go deleted file mode 100644 index b449d7ebd..000000000 --- a/parse/sql/tree/relation.go +++ /dev/null @@ -1,188 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// Relation is one of: -// - RelationTable -// - RelationSubquery -// - RelationJoin -type Relation interface { - AstNode - - relation() -} - -type RelationTable struct { - types.Node - - schema string - Name string - Alias string -} - -func (t *RelationTable) Accept(v AstVisitor) any { - return v.VisitRelationTable(t) -} - -func (t *RelationTable) Walk(w AstListener) error { - return run( - w.EnterRelationTable(t), - w.ExitRelationTable(t), - ) -} - -func (t *RelationTable) ToSQL() string { - if t.Name == "" { - panic("table name is empty") - } - - stmt := sqlwriter.NewWriter() - - if t.schema != "" { - stmt.Token.Space() - stmt.WriteIdentNoSpace(t.schema) - stmt.Token.Period() - stmt.WriteIdentNoSpace(t.Name) - stmt.Token.Space() - } else { - stmt.WriteIdentNoSpace(t.Name) - } - - if t.Alias != "" { - stmt.Token.As() - stmt.WriteIdentNoSpace(t.Alias) - - } - - return stmt.String() -} -func (t *RelationTable) relation() {} - -// SetSchema sets the schema of the table. -// It should not be called by the parser, and is meant to be called -// by processes after parsing. -func (t *RelationTable) SetSchema(schema string) { - t.schema = schema -} - -// RelationFunc is a relation that is a function call. -// This can be used it a user has a function that returns a table. -type RelationFunction struct { - types.Node - - Function *ExpressionFunction - Alias string -} - -func (t *RelationFunction) Accept(v AstVisitor) any { - return v.VisitRelationFunction(t) -} - -func (t *RelationFunction) Walk(w AstListener) error { - return run( - w.EnterRelationFunction(t), - walk(w, t.Function), - w.ExitRelationFunction(t), - ) -} - -func (t *RelationFunction) relation() {} - -func (t *RelationFunction) ToSQL() string { - if t.Function == nil { - panic("function is nil") - } - - stmt := sqlwriter.NewWriter() - - stmt.WriteString(t.Function.ToSQL()) - if t.Alias != "" { - stmt.Token.As() - stmt.WriteIdent(t.Alias) - - } - - return stmt.String() -} - -type RelationSubquery struct { - types.Node - - Select *SelectCore - Alias string -} - -func (t *RelationSubquery) Accept(v AstVisitor) any { - return v.VisitRelationSubquery(t) -} - -func (t *RelationSubquery) Walk(w AstListener) error { - return run( - w.EnterRelationSubquery(t), - walk(w, t.Select), - w.ExitRelationSubquery(t), - ) -} - -func (t *RelationSubquery) ToSQL() string { - if t.Select == nil { - panic("select is nil") - } - - stmt := sqlwriter.NewWriter() - - stmt.Token.Lparen() - - selectString := t.Select.ToSQL() - stmt.WriteString(selectString) - stmt.Token.Rparen() - - if t.Alias != "" { - stmt.Token.As() - stmt.WriteIdent(t.Alias) - - } - - return stmt.String() -} -func (t *RelationSubquery) relation() {} - -type RelationJoin struct { - types.Node - - Relation Relation - Joins []*JoinPredicate -} - -func (t *RelationJoin) Accept(v AstVisitor) any { - return v.VisitRelationJoin(t) -} - -func (t *RelationJoin) Walk(w AstListener) error { - return run( - w.EnterRelationJoin(t), - walk(w, t.Relation), - walkMany(w, t.Joins), - w.ExitRelationJoin(t), - ) -} - -func (t *RelationJoin) relation() {} - -func (t *RelationJoin) ToSQL() string { - if t.Relation == nil { - panic("join table or subquery cannot be nil") - } - - stmt := sqlwriter.NewWriter() - - stmt.WriteString(t.Relation.ToSQL()) - for _, join := range t.Joins { - stmt.WriteString(join.ToSQL()) - } - - return stmt.String() -} diff --git a/parse/sql/tree/relation_test.go b/parse/sql/tree/relation_test.go deleted file mode 100644 index b17b2b617..000000000 --- a/parse/sql/tree/relation_test.go +++ /dev/null @@ -1,251 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestRelation_ToSQL(t *testing.T) { - type fields struct { - Relation tree.Relation - Schema string // optional, only for RelationTable - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid table", - fields: fields{ - Relation: &tree.RelationTable{ - Name: "foo", - Alias: "f", - }, - }, - want: `"foo" AS "f"`, - }, - { - name: "no table name", - fields: fields{ - Relation: &tree.RelationTable{ - Alias: "f", - }, - }, - wantPanic: true, - }, - { - name: "subquery", - fields: fields{ - Relation: &tree.RelationSubquery{ - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - From: &tree.RelationTable{ - Name: "foo", - }, - }, - }, - }, - }, - }, - want: `(SELECT * FROM "foo")`, - }, - { - name: "join", - fields: fields{ - Relation: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "foo", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeLeft, - Outer: true, - }, - Table: &tree.RelationTable{ - Name: "bar", - }, - Constraint: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "foo"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionColumn{Column: "bar"}, - }, - }, - }, - }, - }, - want: `"foo" LEFT OUTER JOIN "bar" ON "foo" = "bar"`, - }, - { - name: "join clause with one join predicate", - fields: fields{ - Relation: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "table1", - Alias: "t1", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeInner, - }, - Table: &tree.RelationTable{ - Name: "table2", - Alias: "t2", - }, - Constraint: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "t1", - Column: "col1", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionColumn{ - Table: "t2", - Column: "col2", - }, - }, - }, - }, - }, - }, - want: `"table1" AS "t1" INNER JOIN "table2" AS "t2" ON "t1"."col1" = "t2"."col2"`, - }, - { - name: "join clause with greater than one join predicate", - fields: fields{ - Relation: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "table1", - Alias: "t1", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeInner, - }, - Table: &tree.RelationTable{ - Name: "table2", - Alias: "t2", - }, - Constraint: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "t1", - Column: "col1", - }, - Operator: tree.ComparisonOperatorGreaterThan, - Right: &tree.ExpressionColumn{ - Table: "t2", - Column: "col2", - }, - }, - }, - }, - }, - }, - wantPanic: true, - }, - { - name: "join clause with one side of the join operator not containing a column", - fields: fields{ - Relation: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "table1", - Alias: "t1", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeInner, - }, - Table: &tree.RelationTable{ - Name: "table2", - Alias: "t2", - }, - Constraint: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Table: "t1", - Column: "col1", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionTextLiteral{ - Value: "value", - }, - }, - }, - }, - }, - }, - wantPanic: true, - }, - { - name: "join clause with only 1 column as the condition", - fields: fields{ - Relation: &tree.RelationJoin{ - Relation: &tree.RelationTable{ - Name: "table1", - Alias: "t1", - }, - Joins: []*tree.JoinPredicate{ - { - JoinOperator: &tree.JoinOperator{ - JoinType: tree.JoinTypeInner, - }, - Table: &tree.RelationTable{ - Name: "table2", - Alias: "t2", - }, - Constraint: &tree.ExpressionColumn{ - Table: "t1", - Column: "col1", - }, - }, - }, - }, - }, - wantPanic: true, - }, - { - name: "schema namespace", - fields: fields{ - Relation: &tree.RelationTable{ - Name: "foo", - Alias: "f", - }, - Schema: "baz", - }, - want: `"baz"."foo" AS "f"`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("Relation.ToSQL() should have panicked") - } - }() - } - - tr := tt.fields.Relation - - if tt.fields.Schema != "" { - trt := tr.(*tree.RelationTable) - trt.SetSchema(tt.fields.Schema) - } - - got := tr.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("Relation.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/result-column.go b/parse/sql/tree/result-column.go deleted file mode 100644 index 97ab25dcd..000000000 --- a/parse/sql/tree/result-column.go +++ /dev/null @@ -1,83 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// ResultColumnStar represents a wildcard column, i.e. `*`. -type ResultColumnStar struct { - types.Node -} - -func (r *ResultColumnStar) Accept(v AstVisitor) any { - return v.VisitResultColumnStar(r) -} - -func (r *ResultColumnStar) resultColumn() {} -func (r *ResultColumnStar) ToSQL() string { - return "*" -} -func (r *ResultColumnStar) Walk(w AstListener) error { - return run( - w.EnterResultColumnStar(r), - w.ExitResultColumnStar(r), - ) -} - -// ResultColumnExpression represents a result column with an expression and an optional alias. -type ResultColumnExpression struct { - types.Node - - Expression Expression - Alias string -} - -func (r *ResultColumnExpression) Accept(v AstVisitor) any { - return v.VisitResultColumnExpression(r) -} - -func (r *ResultColumnExpression) resultColumn() {} -func (r *ResultColumnExpression) ToSQL() string { - stmt := sqlwriter.NewWriter() - stmt.WriteString(r.Expression.ToSQL()) - if r.Alias != "" { - stmt.Token.As() - stmt.WriteIdent(r.Alias) - } - return stmt.String() -} -func (r *ResultColumnExpression) Walk(w AstListener) error { - return run( - w.EnterResultColumnExpression(r), - walk(w, r.Expression), - w.ExitResultColumnExpression(r), - ) -} - -// ResultColumnTable represents a table name with a star, i.e. `table.*`. -// Or qualified star? -type ResultColumnTable struct { - types.Node - - TableName string -} - -func (r *ResultColumnTable) Accept(v AstVisitor) any { - return v.VisitResultColumnTable(r) -} - -func (r *ResultColumnTable) resultColumn() {} -func (r *ResultColumnTable) ToSQL() string { - stmt := sqlwriter.NewWriter() - stmt.WriteIdent(r.TableName) - stmt.Token.Period() - stmt.Token.Asterisk() - return stmt.String() -} -func (r *ResultColumnTable) Walk(w AstListener) error { - return run( - w.EnterResultColumnTable(r), - w.ExitResultColumnTable(r), - ) -} diff --git a/parse/sql/tree/result-column_test.go b/parse/sql/tree/result-column_test.go deleted file mode 100644 index c0daea0de..000000000 --- a/parse/sql/tree/result-column_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestResultColumnStar_ToSQL(t *testing.T) { - tests := []struct { - name string - r tree.ResultColumn - want string - }{ - { - name: "valid star", - r: &tree.ResultColumnStar{}, - want: "*", - }, - { - name: "expression with alias", - r: &tree.ResultColumnExpression{ - Expression: &tree.ExpressionColumn{Column: "foo"}, - Alias: "f", - }, - want: `"foo" AS "f"`, - }, - { - name: "expression without alias", - r: &tree.ResultColumnExpression{ - Expression: &tree.ExpressionColumn{Column: "foo"}, - }, - want: `"foo"`, - }, - { - name: "table", - r: &tree.ResultColumnTable{ - TableName: "foo", - }, - want: `"foo".*`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - r := tt.r - - got := r.ToSQL() - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("ResultColumnStar.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/returning-clause.go b/parse/sql/tree/returning-clause.go deleted file mode 100644 index ef342826b..000000000 --- a/parse/sql/tree/returning-clause.go +++ /dev/null @@ -1,77 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type ReturningClause struct { - types.Node - - Returned []*ReturningClauseColumn -} - -func (r *ReturningClause) Accept(v AstVisitor) any { - return v.VisitReturningClause(r) -} - -func (r *ReturningClause) Walk(w AstListener) error { - return run( - w.EnterReturningClause(r), - walkMany(w, r.Returned), - w.ExitReturningClause(r), - ) -} - -func (r *ReturningClause) ToSQL() string { - r.check() - - stmt := sqlwriter.NewWriter() - stmt.Token.Returning() - - stmt.WriteList(len(r.Returned), func(i int) { - if r.Returned[i].All { - stmt.Token.Asterisk() - } else { - stmt.WriteString(r.Returned[i].Expression.ToSQL()) - if r.Returned[i].Alias != "" { - stmt.Token.As() - stmt.WriteIdent(r.Returned[i].Alias) - } - } - }) - - return stmt.String() -} - -func (r *ReturningClause) check() { - if len(r.Returned) == 0 { - panic("no columns provided to ReturningClause") - } - - for _, col := range r.Returned { - if col.All && col.Expression != nil { - panic("all and expression cannot be set at the same time") - } - } -} - -type ReturningClauseColumn struct { - types.Node - - All bool - Expression Expression - Alias string -} - -func (r *ReturningClauseColumn) Accept(v AstVisitor) any { - return v.VisitReturningClauseColumn(r) -} - -func (r *ReturningClauseColumn) Walk(w AstListener) error { - return run( - w.EnterReturningClauseColumn(r), - walk(w, r.Expression), - w.ExitReturningClauseColumn(r), - ) -} diff --git a/parse/sql/tree/returning-clause_test.go b/parse/sql/tree/returning-clause_test.go deleted file mode 100644 index ba9daeb90..000000000 --- a/parse/sql/tree/returning-clause_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestReturningClause_ToSQL(t *testing.T) { - type fields struct { - Returned []*tree.ReturningClauseColumn - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid returning clause", - fields: fields{ - Returned: []*tree.ReturningClauseColumn{ - { - Expression: &tree.ExpressionColumn{Column: "foo"}, - Alias: "f", - }, - { - Expression: &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - }, - }, - want: ` RETURNING "foo" AS "f", $a`, - }, - { - name: "returns all", - fields: fields{ - Returned: []*tree.ReturningClauseColumn{ - { - All: true, - }, - }, - }, - want: ` RETURNING *`, - }, - { - name: "contains expression and all", - fields: fields{ - Returned: []*tree.ReturningClauseColumn{ - { - Expression: &tree.ExpressionColumn{Column: "foo"}, - Alias: "f", - All: true, - }, - }, - }, - wantPanic: true, - }, - { - name: "contains no columns", - fields: fields{}, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("ReturningClause.ToSQL() should have panicked") - } - }() - } - - r := &tree.ReturningClause{ - Returned: tt.fields.Returned, - } - - got := r.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("ReturningClause.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/select.go b/parse/sql/tree/select.go deleted file mode 100644 index 63e2c3a8e..000000000 --- a/parse/sql/tree/select.go +++ /dev/null @@ -1,224 +0,0 @@ -package tree - -import ( - "fmt" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type SelectStmt struct { - types.Node - - CTE []*CTE - Stmt *SelectCore -} - -func (s *SelectStmt) Accept(v AstVisitor) any { - return v.VisitSelectStmt(s) -} - -func (s *SelectStmt) Walk(w AstListener) error { - return run( - w.EnterSelectStmt(s), - walkMany(w, s.CTE), - walk(w, s.Stmt), - w.ExitSelectStmt(s), - ) -} - -func (s *SelectStmt) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(s.CTE) > 0 { - stmt.Token.With() - stmt.WriteList(len(s.CTE), func(i int) { - stmt.WriteString(s.CTE[i].ToSQL()) - }) - } - - stmt.WriteString(s.Stmt.ToSQL()) - - stmt.Token.Semicolon() - - return stmt.String() -} - -func (s *SelectStmt) statement() {} - -type SelectCore struct { - types.Node - - SimpleSelects []*SimpleSelect - OrderBy *OrderBy - Limit *Limit -} - -func (s *SelectCore) Accept(v AstVisitor) any { - return v.VisitSelectCore(s) -} - -func (s *SelectCore) Walk(w AstListener) error { - return run( - w.EnterSelectCore(s), - walkMany(w, s.SimpleSelects), - walk(w, s.OrderBy), - walk(w, s.Limit), - w.ExitSelectCore(s), - ) -} - -func (s *SelectCore) ToSQL() (res string) { - stmt := sqlwriter.NewWriter() - for _, core := range s.SimpleSelects { - stmt.WriteString(core.ToSQL()) - } - if s.OrderBy != nil { - stmt.WriteString(s.OrderBy.ToSQL()) - } - if s.Limit != nil { - stmt.WriteString(s.Limit.ToSQL()) - } - - return stmt.String() -} - -type SimpleSelect struct { - types.Node - - SelectType SelectType - Columns []ResultColumn - From Relation - Where Expression - GroupBy *GroupBy - Compound *CompoundOperator -} - -func (s *SimpleSelect) Accept(v AstVisitor) any { - return v.VisitSimpleSelect(s) -} - -func (s *SimpleSelect) Walk(w AstListener) error { - return run( - w.EnterSimpleSelect(s), - walkMany(w, s.Columns), - walk(w, s.From), - walk(w, s.Where), - walk(w, s.GroupBy), - walk(w, s.Compound), - w.ExitSimpleSelect(s), - ) -} - -func (s *SimpleSelect) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if s.Compound != nil { - stmt.WriteString(s.Compound.ToSQL()) - } - - stmt.Token.Select() - if s.SelectType == SelectTypeDistinct { - stmt.Token.Distinct() - } - - if len(s.Columns) == 0 { - stmt.Token.Asterisk() - } else { - for i, col := range s.Columns { - if i > 0 && i < len(s.Columns) { - stmt.Token.Comma() - } - stmt.WriteString(col.ToSQL()) - } - } - - if s.From != nil { - stmt.Token.From() - stmt.WriteString(s.From.ToSQL()) - } - if s.Where != nil { - stmt.Token.Where() - stmt.WriteString(s.Where.ToSQL()) - } - if s.GroupBy != nil { - stmt.WriteString(s.GroupBy.ToSQL()) - } - return stmt.String() -} - -type SelectType uint8 - -const ( - SelectTypeAll SelectType = iota - SelectTypeDistinct -) - -func (s SelectType) Valid() error { - switch s { - case SelectTypeAll, SelectTypeDistinct: - return nil - default: - return fmt.Errorf("invalid select type: %d", s) - } -} - -type CompoundOperatorType uint8 - -const ( - CompoundOperatorTypeUnion CompoundOperatorType = iota - CompoundOperatorTypeUnionAll - CompoundOperatorTypeIntersect - CompoundOperatorTypeExcept -) - -func (c CompoundOperatorType) Valid() error { - switch c { - case CompoundOperatorTypeUnion, CompoundOperatorTypeUnionAll, CompoundOperatorTypeIntersect, CompoundOperatorTypeExcept: - return nil - default: - return fmt.Errorf("invalid compound operator type: %d", c) - } -} - -func (c *CompoundOperatorType) ToSQL() string { - switch *c { - case CompoundOperatorTypeUnion: - return "UNION" - case CompoundOperatorTypeUnionAll: - return "UNION ALL" - case CompoundOperatorTypeIntersect: - return "INTERSECT" - case CompoundOperatorTypeExcept: - return "EXCEPT" - default: - panic(fmt.Errorf("unknown compound operator type %d", *c)) - } -} - -type CompoundOperator struct { - types.Node - - Operator CompoundOperatorType -} - -func (c *CompoundOperator) Accept(v AstVisitor) any { - return v.VisitCompoundOperator(c) -} - -func (c *CompoundOperator) AcceptVisitor(v AstVisitor) any { - return v.VisitCompoundOperator(c) -} - -func (c *CompoundOperator) Walk(w AstListener) error { - return run( - w.EnterCompoundOperator(c), - w.ExitCompoundOperator(c), - ) -} - -func (c *CompoundOperator) ToSQL() string { - stmt := sqlwriter.NewWriter() - stmt.WriteString(c.Operator.ToSQL()) - return stmt.String() -} diff --git a/parse/sql/tree/select_test.go b/parse/sql/tree/select_test.go deleted file mode 100644 index ffd95b04a..000000000 --- a/parse/sql/tree/select_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestSelect_ToSQL(t *testing.T) { - type fields struct { - CTE []*tree.CTE - SelectStmt *tree.SelectCore - } - tests := []struct { - name string - fields fields - wantStr string - wantErr bool - }{ - { - name: "valid select", - fields: fields{ - CTE: []*tree.CTE{ - mockCTE, - }, - SelectStmt: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{{ - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{Expression: &tree.ExpressionColumn{Column: "foo"}}, - &tree.ResultColumnExpression{Expression: &tree.ExpressionColumn{Column: "bar"}}, - }, - From: &tree.RelationTable{ - Name: "foo", - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "foo"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$a"}, - }, - GroupBy: &tree.GroupBy{ - Expressions: []tree.Expression{ - &tree.ExpressionColumn{Column: "foo"}, - &tree.ExpressionColumn{Column: "bar"}, - }, - Having: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{Column: "foo"}, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{Parameter: "$b"}, - }, - }, - }}, - OrderBy: &tree.OrderBy{ - OrderingTerms: []*tree.OrderingTerm{ - { - Expression: &tree.ExpressionCollate{ - Expression: &tree.ExpressionColumn{Column: "foo"}, - Collation: tree.CollationTypeNoCase, - }, - }, - }, - }, - Limit: &tree.Limit{ - Expression: &tree.ExpressionBindParameter{Parameter: "$c"}, - Offset: &tree.ExpressionBindParameter{Parameter: "$d"}, - }, - }, - }, - wantStr: `WITH ` + mockCTE.ToSQL() + ` SELECT "foo", "bar" FROM "foo" WHERE "foo" = $a GROUP BY "foo", "bar" HAVING "foo" = $b ORDER BY "foo" COLLATE NOCASE LIMIT $c OFFSET $d;`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := &tree.SelectStmt{ - CTE: tt.fields.CTE, - Stmt: tt.fields.SelectStmt, - } - gotStr, err := tree.SafeToSQL(s) - if (err != nil) != tt.wantErr { - t.Errorf("SelectStmt.ToSQL() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !compareIgnoringWhitespace(gotStr, tt.wantStr) { - t.Errorf("SelectStmt.ToSQL() = %v, want %v", gotStr, tt.wantStr) - } - }) - } -} diff --git a/parse/sql/tree/sql-writer/tokens.go b/parse/sql/tree/sql-writer/tokens.go deleted file mode 100644 index 3023c21db..000000000 --- a/parse/sql/tree/sql-writer/tokens.go +++ /dev/null @@ -1,384 +0,0 @@ -package sqlwriter - -import "strings" - -type sqliteSymbol string - -type tokenWriter struct { - stmt *strings.Builder -} - -func newTokenWriter(s *strings.Builder) *tokenWriter { - return &tokenWriter{ - stmt: s, - } -} - -func (t *tokenWriter) token(s sqliteSymbol) { - t.stmt.WriteString(" ") - t.stmt.WriteString(string(s)) - t.stmt.WriteString(" ") -} - -func (t *tokenWriter) Lparen() *tokenWriter { - t.token(lparen) - return t -} - -func (t *tokenWriter) Rparen() *tokenWriter { - t.token(rparen) - return t -} - -func (t *tokenWriter) Comma() *tokenWriter { - t.token(comma) - return t -} - -func (t *tokenWriter) Semicolon() *tokenWriter { - t.token(semicolon) - return t -} - -func (t *tokenWriter) Period() *tokenWriter { - t.token(period) - return t -} - -func (t *tokenWriter) Asterisk() *tokenWriter { - t.token(asterisk) - return t -} - -func (t *tokenWriter) Equals() *tokenWriter { - t.token(equals) - return t -} - -func (t *tokenWriter) Not() *tokenWriter { - t.token(not) - return t -} - -func (t *tokenWriter) And() *tokenWriter { - t.token(and) - return t -} - -func (t *tokenWriter) Or() *tokenWriter { - t.token(or) - return t -} - -func (t *tokenWriter) Is() *tokenWriter { - t.token(is) - return t -} - -func (t *tokenWriter) IsNot() *tokenWriter { - t.token(is_not) - return t -} - -func (t *tokenWriter) In() *tokenWriter { - t.token(in) - return t -} - -func (t *tokenWriter) Escape() *tokenWriter { - t.token(escape) - return t -} - -func (t *tokenWriter) Insert() *tokenWriter { - t.token(insert) - return t -} - -func (t *tokenWriter) Into() *tokenWriter { - t.token(into) - return t -} - -func (t *tokenWriter) Replace() *tokenWriter { - t.token(replace) - return t -} - -func (t *tokenWriter) Values() *tokenWriter { - t.token(values) - return t -} - -func (t *tokenWriter) Select() *tokenWriter { - t.token(selectToken) - return t -} - -func (t *tokenWriter) From() *tokenWriter { - t.token(from) - return t -} - -func (t *tokenWriter) Where() *tokenWriter { - t.token(where) - return t -} - -func (t *tokenWriter) Having() *tokenWriter { - t.token(having) - return t -} - -func (t *tokenWriter) Asc() *tokenWriter { - t.token(asc) - return t -} - -func (t *tokenWriter) Desc() *tokenWriter { - t.token(desc) - return t -} - -func (t *tokenWriter) Limit() *tokenWriter { - t.token(limit) - return t -} - -func (t *tokenWriter) Offset() *tokenWriter { - t.token(offset) - return t -} - -func (t *tokenWriter) All() *tokenWriter { - t.token(all) - return t -} - -func (t *tokenWriter) Distinct() *tokenWriter { - t.token(distinct) - return t -} - -func (t *tokenWriter) As() *tokenWriter { - t.token(as) - return t -} - -func (t *tokenWriter) Exists() *tokenWriter { - t.token(exists) - return t -} - -func (t *tokenWriter) Case() *tokenWriter { - t.token(case_) - return t -} - -func (t *tokenWriter) When() *tokenWriter { - t.token(when) - return t -} - -func (t *tokenWriter) Then() *tokenWriter { - t.token(then) - return t -} - -func (t *tokenWriter) Else() *tokenWriter { - t.token(else_) - return t -} - -func (t *tokenWriter) End() *tokenWriter { - t.token(end) - return t -} - -func (t *tokenWriter) Space() *tokenWriter { - t.token(space) - return t -} - -func (t *tokenWriter) On() *tokenWriter { - t.token(on) - return t -} - -func (t *tokenWriter) Conflict() *tokenWriter { - t.token(conflict) - return t -} - -func (t *tokenWriter) Do() *tokenWriter { - t.token(do) - return t -} - -func (t *tokenWriter) Nothing() *tokenWriter { - t.token(nothing) - return t -} - -func (t *tokenWriter) Update() *tokenWriter { - t.token(update) - return t -} - -func (t *tokenWriter) Set() *tokenWriter { - t.token(set) - return t -} - -func (t *tokenWriter) Collate() *tokenWriter { - t.token(collate) - return t -} - -func (t *tokenWriter) Returning() *tokenWriter { - t.token(returning) - return t -} - -func (t *tokenWriter) Order() *tokenWriter { - t.token(order) - return t -} - -func (t *tokenWriter) Group() *tokenWriter { - t.token(group) - return t -} - -func (t *tokenWriter) By() *tokenWriter { - t.token(by) - return t -} - -func (t *tokenWriter) Null() *tokenWriter { - t.token(null) - return t -} - -func (t *tokenWriter) Between() *tokenWriter { - t.token(between) - return t -} - -func (t *tokenWriter) Natural() *tokenWriter { - t.token(natural) - return t -} - -func (t *tokenWriter) Inner() *tokenWriter { - t.token(inner) - return t -} - -func (t *tokenWriter) Left() *tokenWriter { - t.token(left) - return t -} - -func (t *tokenWriter) Right() *tokenWriter { - t.token(right) - return t -} - -func (t *tokenWriter) Full() *tokenWriter { - t.token(full) - return t -} - -func (t *tokenWriter) Outer() *tokenWriter { - t.token(outer) - return t -} - -func (t *tokenWriter) Join() *tokenWriter { - t.token(join) - return t -} - -func (t *tokenWriter) Delete() *tokenWriter { - t.token(delete) - return t -} - -func (t *tokenWriter) Indexed() *tokenWriter { - t.token(indexed) - return t -} - -func (t *tokenWriter) With() *tokenWriter { - t.token(with) - return t -} - -func (t *tokenWriter) Raise() *tokenWriter { - t.token(raise) - return t -} - -const ( - lparen sqliteSymbol = "(" - rparen sqliteSymbol = ")" - comma sqliteSymbol = "," - semicolon sqliteSymbol = ";" - period sqliteSymbol = "." - asterisk sqliteSymbol = "*" - equals sqliteSymbol = "=" - not sqliteSymbol = "NOT" - and sqliteSymbol = "AND" - or sqliteSymbol = "OR" - is sqliteSymbol = "IS" - is_not sqliteSymbol = "IS NOT" - in sqliteSymbol = "IN" - escape sqliteSymbol = "ESCAPE" - insert sqliteSymbol = "INSERT" - into sqliteSymbol = "INTO" - replace sqliteSymbol = "REPLACE" - values sqliteSymbol = "VALUES" - selectToken sqliteSymbol = "SELECT" // select is a reserved word in Go - from sqliteSymbol = "FROM" - where sqliteSymbol = "WHERE" - having sqliteSymbol = "HAVING" - asc sqliteSymbol = "ASC" - desc sqliteSymbol = "DESC" - limit sqliteSymbol = "LIMIT" - offset sqliteSymbol = "OFFSET" - all sqliteSymbol = "ALL" - distinct sqliteSymbol = "DISTINCT" - as sqliteSymbol = "AS" - exists sqliteSymbol = "EXISTS" - case_ sqliteSymbol = "CASE" - when sqliteSymbol = "WHEN" - then sqliteSymbol = "THEN" - else_ sqliteSymbol = "ELSE" - end sqliteSymbol = "END" - space sqliteSymbol = " " - on sqliteSymbol = "ON" - conflict sqliteSymbol = "CONFLICT" - do sqliteSymbol = "DO" - nothing sqliteSymbol = "NOTHING" - update sqliteSymbol = "UPDATE" - set sqliteSymbol = "SET" - collate sqliteSymbol = "COLLATE" - returning sqliteSymbol = "RETURNING" - order sqliteSymbol = "ORDER" - group sqliteSymbol = "GROUP" - by sqliteSymbol = "BY" - null sqliteSymbol = "NULL" - between sqliteSymbol = "BETWEEN" - natural sqliteSymbol = "NATURAL" - inner sqliteSymbol = "INNER" - left sqliteSymbol = "LEFT" - right sqliteSymbol = "RIGHT" - full sqliteSymbol = "FULL" - outer sqliteSymbol = "OUTER" - join sqliteSymbol = "JOIN" - delete sqliteSymbol = "DELETE" - indexed sqliteSymbol = "INDEXED" - with sqliteSymbol = "WITH" - raise sqliteSymbol = "RAISE" -) diff --git a/parse/sql/tree/sql-writer/writer.go b/parse/sql/tree/sql-writer/writer.go deleted file mode 100644 index 6b68884a3..000000000 --- a/parse/sql/tree/sql-writer/writer.go +++ /dev/null @@ -1,89 +0,0 @@ -package sqlwriter - -import ( - "fmt" - "strings" -) - -var ( - // Options is a struct that can be used to configure the behavior of the sql writer. - // It is global, and should only be used for testing purposes. - Options = struct{ IdentWrapper string }{IdentWrapper: `"`} -) - -type SqlWriter struct { - stmt *strings.Builder - Token *tokenWriter - wrap bool -} - -func NewWriter() *SqlWriter { - builder := &strings.Builder{} - return &SqlWriter{ - stmt: builder, - Token: newTokenWriter(builder), - wrap: false, - } -} - -func (s *SqlWriter) WrapParen() *SqlWriter { - s.wrap = true - s.stmt.WriteString("(") // use this instead of token to prevent extra spaces - - return s -} - -func (s *SqlWriter) String() string { - if s.wrap { - s.stmt.WriteString(")") - } - - return s.stmt.String() -} - -func (s *SqlWriter) write(str string) { - s.stmt.WriteString(" ") - s.stmt.WriteString(str) - s.stmt.WriteString(" ") -} - -func (s *SqlWriter) WriteString(str string) { - s.write(str) -} - -func (s *SqlWriter) WriteIdent(str string) { - s.Token.Space() - s.stmt.WriteString(Options.IdentWrapper) - s.stmt.WriteString(str) - s.stmt.WriteString(Options.IdentWrapper) - s.Token.Space() -} - -func (s *SqlWriter) WriteIdentNoSpace(str string) { - s.stmt.WriteString(`"`) - s.stmt.WriteString(str) - s.stmt.WriteString(`"`) -} - -func (s *SqlWriter) WriteInt64(i int64) { - s.write(fmt.Sprint(i)) -} - -// WriteList writes a comma-separated list of strings, using the provided function to generate each string. -func (s *SqlWriter) WriteList(length int, fn func(i int)) { - for i := 0; i < length; i++ { - if i > 0 && i < length { - s.Token.Comma() - } - fn(i) - } -} - -// WriteParenList writes a comma-separated list of strings, using the provided function to generate each string. -// The list is wrapped in parentheses. -// The first argument is the length of the list. -func (s *SqlWriter) WriteParenList(length int, fn func(i int)) { - s.Token.Lparen() - s.WriteList(length, fn) - s.Token.Rparen() -} diff --git a/parse/sql/tree/sql-writer/writer_test.go b/parse/sql/tree/sql-writer/writer_test.go deleted file mode 100644 index 811f18ba3..000000000 --- a/parse/sql/tree/sql-writer/writer_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package sqlwriter_test - -import ( - "testing" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" -) - -// most of this gets tested by the tree package, so I am not too worried about coverage here - -func Test_Writer(t *testing.T) { - stmt := sqlwriter.NewWriter() - stmt.WriteString("TEST1") - stmt.WriteString("TEST2") - - if stmt.String() != " TEST1 TEST2 " { - t.Errorf("expected ' TEST1 TEST2 ', got %s", stmt.String()) - } - - stmt = sqlwriter.NewWriter().WrapParen() - stmt.Token.Lparen() - stmt.WriteInt64(1) - stmt.Token.Rparen() - str := stmt.String() - if str != "( ( 1 ) )" { - t.Errorf("expected '( ( 1 ) ), got %s", stmt.String()) - } - -} diff --git a/parse/sql/tree/update-set-clause.go b/parse/sql/tree/update-set-clause.go deleted file mode 100644 index 3970f0edc..000000000 --- a/parse/sql/tree/update-set-clause.go +++ /dev/null @@ -1,51 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -// UpdateSetClause is a clause that represents the SET clause in an UPDATE statement. -// This does NOT include the SET keyword. -// e.g. column1 = expression, column2 = expression, ... -type UpdateSetClause struct { - types.Node - - Columns []string - Expression Expression -} - -func (u *UpdateSetClause) Accept(v AstVisitor) any { - return v.VisitUpdateSetClause(u) -} - -func (u *UpdateSetClause) Walk(w AstListener) error { - return run( - w.EnterUpdateSetClause(u), - walk(w, u.Expression), - w.ExitUpdateSetClause(u), - ) -} - -func (u *UpdateSetClause) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(u.Columns) == 0 { - panic("no column names provided to UpdateSetClause") - } else if len(u.Columns) == 1 { - stmt.WriteIdent(u.Columns[0]) - } else { - stmt.WriteParenList(len(u.Columns), func(i int) { - stmt.WriteIdent(u.Columns[i]) - }) - } - - if u.Expression == nil { - panic("no expression provided to UpdateSetClause") - } - - stmt.Token.Equals() - stmt.WriteString(u.Expression.ToSQL()) - - return stmt.String() -} diff --git a/parse/sql/tree/update.go b/parse/sql/tree/update.go deleted file mode 100644 index 48f4d9ff3..000000000 --- a/parse/sql/tree/update.go +++ /dev/null @@ -1,108 +0,0 @@ -package tree - -import ( - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type UpdateStmt struct { - types.Node - - CTE []*CTE - Core *UpdateCore -} - -func (u *UpdateStmt) Accept(v AstVisitor) any { - return v.VisitUpdateStmt(u) -} - -func (u *UpdateStmt) Walk(w AstListener) error { - return run( - w.EnterUpdateStmt(u), - walkMany(w, u.CTE), - walk(w, u.Core), - w.ExitUpdateStmt(u), - ) -} - -func (u *UpdateStmt) ToSQL() string { - stmt := sqlwriter.NewWriter() - - if len(u.CTE) > 0 { - stmt.Token.With() - stmt.WriteList(len(u.CTE), func(i int) { - stmt.WriteString(u.CTE[i].ToSQL()) - }) - } - - stmt.WriteString(u.Core.ToSQL()) - - stmt.Token.Semicolon() - - return stmt.String() -} - -func (u *UpdateStmt) statement() {} - -type UpdateCore struct { - types.Node - - QualifiedTableName *QualifiedTableName - UpdateSetClause []*UpdateSetClause - From Relation - Where Expression - Returning *ReturningClause -} - -func (u *UpdateCore) Accept(v AstVisitor) any { - return v.VisitUpdateCore(u) -} - -func (u *UpdateCore) Walk(w AstListener) error { - return run( - w.EnterUpdateCore(u), - walk(w, u.QualifiedTableName), - walkMany(w, u.UpdateSetClause), - walk(w, u.From), - walk(w, u.Where), - walk(w, u.Returning), - w.ExitUpdateCore(u), - ) -} - -func (u *UpdateCore) ToSQL() string { - u.check() - - stmt := sqlwriter.NewWriter() - stmt.Token.Update() - stmt.WriteString(u.QualifiedTableName.ToSQL()) - stmt.Token.Set() - stmt.WriteList(len(u.UpdateSetClause), func(i int) { - stmt.WriteString(u.UpdateSetClause[i].ToSQL()) - }) - - if u.From != nil { - stmt.Token.From() - stmt.WriteString(u.From.ToSQL()) - } - - if u.Where != nil { - stmt.Token.Where() - stmt.WriteString(u.Where.ToSQL()) - } - - if u.Returning != nil { - stmt.WriteString(u.Returning.ToSQL()) - } - - return stmt.String() -} - -func (u *UpdateCore) check() { - if u.QualifiedTableName == nil { - panic("qualified table name is required") - } - if len(u.UpdateSetClause) == 0 { - panic("update set clause is required") - } -} diff --git a/parse/sql/tree/update_test.go b/parse/sql/tree/update_test.go deleted file mode 100644 index b4ec60166..000000000 --- a/parse/sql/tree/update_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestUpdate_ToSQL(t *testing.T) { - type fields struct { - CTE []*tree.CTE - Statement *tree.UpdateCore - } - tests := []struct { - name string - fields fields - wantStr string - wantErr bool - }{ - { - name: "valid update", - fields: fields{ - CTE: []*tree.CTE{ - mockCTE, - }, - Statement: &tree.UpdateCore{ - QualifiedTableName: &tree.QualifiedTableName{ - TableName: "foo", - TableAlias: "f", - }, - UpdateSetClause: []*tree.UpdateSetClause{ - { - Columns: []string{"bar", "baz"}, - Expression: &tree.ExpressionSelect{ - IsNot: true, - IsExists: true, - Select: &tree.SelectCore{ - SimpleSelects: []*tree.SimpleSelect{ - { - SelectType: tree.SelectTypeAll, - Columns: []tree.ResultColumn{ - &tree.ResultColumnExpression{Expression: &tree.ExpressionColumn{Column: "foo"}}, - &tree.ResultColumnExpression{Expression: &tree.ExpressionColumn{Column: "bar"}}, - }, - From: &tree.RelationTable{ - Name: "foo", - }, - }, - }, - }, - }, - }, - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "foo", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - Returning: &tree.ReturningClause{ - Returned: []*tree.ReturningClauseColumn{ - { - Expression: &tree.ExpressionColumn{Column: "foo"}, - Alias: "fu", - }, - }, - }, - }, - }, - wantStr: `WITH ` + mockCTE.ToSQL() + ` UPDATE "foo" AS "f" SET ("bar", "baz") = NOT EXISTS (SELECT "foo", "bar" FROM "foo") WHERE "foo" = $a RETURNING "foo" AS "fu";`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - u := &tree.UpdateStmt{ - CTE: tt.fields.CTE, - Core: tt.fields.Statement, - } - gotStr, err := tree.SafeToSQL(u) - if (err != nil) != tt.wantErr { - t.Errorf("UpdateStmt.ToSQL() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !compareIgnoringWhitespace(gotStr, tt.wantStr) { - t.Errorf("UpdateStmt.ToSQL() = %v, want %v", gotStr, tt.wantStr) - } - }) - } -} diff --git a/parse/sql/tree/upsert.go b/parse/sql/tree/upsert.go deleted file mode 100644 index 6b1dd68fb..000000000 --- a/parse/sql/tree/upsert.go +++ /dev/null @@ -1,75 +0,0 @@ -package tree - -import ( - "fmt" - - sqlwriter "github.com/kwilteam/kwil-db/parse/sql/tree/sql-writer" - "github.com/kwilteam/kwil-db/parse/types" -) - -type UpsertType uint8 - -const ( - UpsertTypeDoNothing UpsertType = iota - UpsertTypeDoUpdate -) - -func (u UpsertType) Valid() error { - switch u { - case UpsertTypeDoNothing, UpsertTypeDoUpdate: - return nil - default: - return fmt.Errorf("invalid upsert type: %d", u) - } -} - -type Upsert struct { - types.Node - - ConflictTarget *ConflictTarget - Type UpsertType - Updates []*UpdateSetClause - Where Expression -} - -func (u *Upsert) Accept(v AstVisitor) any { - return v.VisitUpsert(u) -} - -func (u *Upsert) Walk(w AstListener) error { - return run( - w.EnterUpsert(u), - walk(w, u.ConflictTarget), - walkMany(w, u.Updates), - walk(w, u.Where), - w.ExitUpsert(u), - ) -} - -func (u *Upsert) ToSQL() string { - stmt := sqlwriter.NewWriter() - - stmt.Token.On().Conflict() - - if u.ConflictTarget != nil { - stmt.WriteString(u.ConflictTarget.ToSQL()) - } - - switch u.Type { - case UpsertTypeDoNothing: - stmt.Token.Do().Nothing() - case UpsertTypeDoUpdate: - stmt.Token.Do().Update().Set() - - stmt.WriteList(len(u.Updates), func(i int) { - stmt.WriteString(u.Updates[i].ToSQL()) - }) - - if u.Where != nil { - stmt.Token.Where() - stmt.WriteString(u.Where.ToSQL()) - } - } - - return stmt.String() -} diff --git a/parse/sql/tree/upsert_test.go b/parse/sql/tree/upsert_test.go deleted file mode 100644 index 7414bd470..000000000 --- a/parse/sql/tree/upsert_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package tree_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/sql/tree" -) - -func TestUpsert_ToSQL(t *testing.T) { - type fields struct { - ConflictTarget *tree.ConflictTarget - Type tree.UpsertType - Updates []*tree.UpdateSetClause - Where tree.Expression - } - tests := []struct { - name string - fields fields - want string - wantPanic bool - }{ - { - name: "valid upsert", - fields: fields{ - ConflictTarget: &tree.ConflictTarget{ - IndexedColumns: []string{"barCol", "bazCol"}, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "barCol", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "$a", - }, - }, - }, - Type: tree.UpsertTypeDoUpdate, - Updates: []*tree.UpdateSetClause{ - { - Columns: []string{"barCol", "bazCol"}, - Expression: &tree.ExpressionBindParameter{ - Parameter: "$b", - }, - }, - }, - Where: &tree.ExpressionBinaryComparison{ - Left: &tree.ExpressionColumn{ - Column: "bazCol", - }, - Operator: tree.ComparisonOperatorEqual, - Right: &tree.ExpressionBindParameter{ - Parameter: "@caller", - }, - }, - }, - want: `ON CONFLICT ("barCol", "bazCol") WHERE "barCol" = $a DO UPDATE SET ("barCol", "bazCol") = $b WHERE "bazCol" = @caller`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantPanic { - defer func() { - if r := recover(); r == nil { - t.Errorf("Upsert.ToSQL() should have panicked") - } - }() - } - - u := &tree.Upsert{ - ConflictTarget: tt.fields.ConflictTarget, - Type: tt.fields.Type, - Updates: tt.fields.Updates, - Where: tt.fields.Where, - } - - got := u.ToSQL() - if tt.wantPanic { - return - } - - if !compareIgnoringWhitespace(got, tt.want) { - t.Errorf("Upsert.ToSQL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/parse/sql/tree/utils.go b/parse/sql/tree/utils.go deleted file mode 100644 index 90c27a093..000000000 --- a/parse/sql/tree/utils.go +++ /dev/null @@ -1,20 +0,0 @@ -package tree - -import ( - "fmt" -) - -func SafeToSQL(node AstNode) (str string, err error) { - defer func() { - if r := recover(); r != nil { - err2, ok := r.(error) - if !ok { - err2 = fmt.Errorf("%v", r) - } - - err = err2 - } - }() - - return node.ToSQL(), nil -} diff --git a/parse/sql/tree/utils_test.go b/parse/sql/tree/utils_test.go deleted file mode 100644 index 4aed81f9a..000000000 --- a/parse/sql/tree/utils_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package tree_test - -import ( - "strings" - "unicode" -) - -// this file contains some utils for testing this package specifically - -// removeWhitespace removes all whitespace characters from a string. -func removeWhitespace(s string) string { - return strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return -1 // skip this rune - } - return r - }, s) -} - -// compareIgnoringWhitespace compares two strings while ignoring whitespace characters. -func compareIgnoringWhitespace(a, b string) bool { - aWithoutWhitespace := removeWhitespace(a) - bWithoutWhitespace := removeWhitespace(b) - - return aWithoutWhitespace == bWithoutWhitespace -} diff --git a/parse/sql/tree/walker.go b/parse/sql/tree/walker.go deleted file mode 100644 index af71c1161..000000000 --- a/parse/sql/tree/walker.go +++ /dev/null @@ -1,48 +0,0 @@ -package tree - -import ( - "errors" - "reflect" -) - -func run(errs ...error) error { - return errors.Join(errs...) -} - -// AstWalker represents an AST node that can be walked. -type AstWalker interface { - // Walk walks through itself using AstListener. - Walk(AstListener) error -} - -func isNil(input interface{}) bool { - if input == nil { - return true - } - kind := reflect.ValueOf(input).Kind() - switch kind { - case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan: - return reflect.ValueOf(input).IsNil() - default: - return false - } -} - -func walk(v AstListener, a AstWalker) error { - if isNil(a) { - return nil - } - - return a.Walk(v) -} - -func walkMany[T AstWalker](v AstListener, as []T) error { - for _, a := range as { - err := walk(v, a) - if err != nil { - return err - } - } - - return nil -} diff --git a/parse/types.go b/parse/types.go new file mode 100644 index 000000000..f3f96433b --- /dev/null +++ b/parse/types.go @@ -0,0 +1,206 @@ +package parse + +import ( + "github.com/antlr4-go/antlr/v4" + "github.com/kwilteam/kwil-db/core/types" +) + +// Position is a Position in the parse tree. It represents a range of line and column +// values in Kuneiform source code. +type Position struct { + // Set is true if the position of the Position has been set. + // This is useful for testing parsers. + IsSet bool `json:"-"` + StartLine int `json:"start_line"` + StartCol int `json:"start_col"` + EndLine int `json:"end_line"` + EndCol int `json:"end_col"` +} + +// Set sets the position of the Position based on the given parser rule context. +func (n *Position) Set(r antlr.ParserRuleContext) { + n.IsSet = true + n.StartLine = r.GetStart().GetLine() + n.StartCol = r.GetStart().GetColumn() + n.EndLine = r.GetStop().GetLine() + n.EndCol = r.GetStop().GetColumn() +} + +// SetToken sets the position of the Position based on the given token. +func (n *Position) SetToken(t antlr.Token) { + n.IsSet = true + n.StartLine = t.GetLine() + n.StartCol = t.GetColumn() + n.EndLine = t.GetLine() + n.EndCol = t.GetColumn() +} + +// GetPosition returns the Position. +// It is useful if the Position is embedded in another struct. +func (n Position) GetPosition() *Position { + return &n +} + +// unaryNode creates a Position with the same start and end position. +func unaryNode(start, end int) *Position { + return &Position{ + StartLine: start, + StartCol: end, + EndLine: start, + EndCol: end, + } +} + +// MergeNodes merges two Positions into a single Position. +// It starts at the left Position and ends at the right Position. +func MergeNodes(left, right *Position) *Position { + return &Position{ + StartLine: left.StartLine, + StartCol: left.StartCol, + EndLine: right.EndLine, + EndCol: right.EndCol, + } +} + +// SchemaInfo contains information about a parsed schema +type SchemaInfo struct { + // Blocks maps declared block names to their Positions. + // Block names include: + // - tables + // - extensions + // - actions + // - procedures + // - foreign procedures + Blocks map[string]*Block `json:"blocks"` +} + +type Block struct { + Position + // AbsStart is the absolute start position of the block in the source code. + AbsStart int `json:"abs_start"` + // AbsEnd is the absolute end position of the block in the source code. + AbsEnd int `json:"abs_end"` +} + +// Relation represents a relation in a sql statement. +// It is meant to represent the shape of a relation, not the data. +type Relation struct { + Name string + // Attributes holds the attributes of the relation. + Attributes []*Attribute +} + +// ShapesMatch checks if the shapes of two relations match. +// It only checks types and order, and ignores the names of the attributes, +// as well as uniques and primary keys. +func (r *Relation) ShapesMatch(r2 *Relation) bool { + return ShapesMatch(r.Attributes, r2.Attributes) +} + +// FindAttribute finds an attribute by name. +// If it is not found, it returns nil and false +func (r *Relation) FindAttribute(name string) (*Attribute, bool) { + for _, a := range r.Attributes { + if a.Name == name { + return a, true + } + } + return nil, false +} + +// Copy returns a copy of the relation. +func (r *Relation) Copy() *Relation { + attrs := make([]*Attribute, len(r.Attributes)) + for i, a := range r.Attributes { + attrs[i] = &Attribute{ + Name: a.Name, + Type: a.Type.Copy(), + } + } + + return &Relation{ + Name: r.Name, + Attributes: attrs, + } +} + +// Attribute represents an attribute in a relation. +type Attribute struct { + Name string + Type *types.DataType +} + +// ShapesMatch checks if the shapes of two relations match. +// It only checks types and order, and ignores the names of the attributes, +// as well as uniques and primary keys. +func ShapesMatch(a1, a2 []*Attribute) bool { + if len(a1) != len(a2) { + return false + } + for i := range a1 { + if !a1[i].Type.EqualsStrict(a2[i].Type) { + return false + } + } + return true +} + +// Flatten flattens many relations into one unnamed relation. +// If there are column conflicts / ambiguities, it will return an error, +// and the name that caused the conflict. It will also discard any +// primary keys, and will unmark any unique columns. +func Flatten(rels ...*Relation) (res []*Attribute, col string, err error) { + var attrs []*Attribute + for _, r := range rels { + attrs = append(attrs, r.Attributes...) + } + + res, col, err = Coalesce(attrs...) + if err != nil { + return nil, col, err + } + + return res, "", nil +} + +// Coalesce coalesces sets of attributes. If there are ambiguities, it will +// return an error, and the name that caused the conflict. It will also discard +// any primary keys, and will unmark any unique columns. +func Coalesce(attrs ...*Attribute) (res []*Attribute, ambigousCol string, err error) { + colNames := make(map[string]struct{}) + + for _, a := range attrs { + // if unnamed, then we can just add and not worry about conflicts, + // since it cannot be referenced + if a.Name == "" { + res = append(res, &Attribute{ + Name: a.Name, + Type: a.Type.Copy(), + }) + + continue + } + + if _, ok := colNames[a.Name]; ok { + return nil, a.Name, ErrDuplicateResultColumnName + } + + colNames[a.Name] = struct{}{} + res = append(res, &Attribute{ + Name: a.Name, + Type: a.Type.Copy(), + }) + } + + return res, "", nil +} + +// findAttribute finds an attribute by name. +func findAttribute(attrs []*Attribute, name string) *Attribute { + for _, a := range attrs { + if a.Name == name { + return a + } + } + return nil +} diff --git a/parse/types/error_listener.go b/parse/types/error_listener.go deleted file mode 100644 index 9b73c664a..000000000 --- a/parse/types/error_listener.go +++ /dev/null @@ -1,189 +0,0 @@ -package types - -import ( - "fmt" - - "github.com/antlr4-go/antlr/v4" -) - -// BaseErrorListener is an interface for error listeners that are used by both Antlr -// and Kwil's native validation logic. -type BaseErrorListener interface { - // Err returns the error if there are any, otherwise it returns nil. - Err() error - // Errors returns the errors that have been collected. - Errors() []*ParseError - // Add adds errors from another error listener to this error listener. - Add(errs ...*ParseError) -} - -// AntlrErrorListener is an interface for error listeners required by functions that directly -// deal with Antlr parsers. -type AntlrErrorListener interface { - BaseErrorListener - antlr.ErrorListener - // TokenErr adds an error where the error comes from an antlr generated token. - TokenErr(t antlr.Token, errType ParseErrorType, err error) - // RuleErr adds an error where the position of an antlr generated rule is - // known. - RuleErr(ctx antlr.ParserRuleContext, errType ParseErrorType, err error) - // ChildFromToken creates a new error listener that is a child of the current error listener. - // It will have the same starting position as the token. - ChildFromToken(name string, t antlr.Token) *ErrorListener -} - -// NativeErrorListener is an interface for error listeners required by Kwil's native -// visitors, which perform validation such as type checking, semantic checking, etc. -type NativeErrorListener interface { - BaseErrorListener - // NodeErr adds an error where our native node type is identifiable. - NodeErr(node *Node, errType ParseErrorType, err error) - // Child creates a new error listener. It will not have any of the errors from the parent, - // and should simply be used for nested parsing. - Child(name string, startLine, startCol int) *ErrorListener -} - -// ErrorListener listens to errors emitted by Antlr, and also collects -// errors from Kwil's native validation logic. -type ErrorListener struct { - Errs []*ParseError - startLine int - startCol int - name string -} - -var _ AntlrErrorListener = &ErrorListener{} -var _ NativeErrorListener = &ErrorListener{} - -// ErrorListenerOptions allows for setting options on the ErrorListener. -type ErrorListenerOptions struct { - // ParentNode is the parent position of the error listener. - // For example, if the error listener is used in a sub-parser (e.g. the procedure parser), - // the parent position should be the starting position of the procedure. - ParentNode *Node -} - -// NewErrorListener creates a new error listener with the given options. -func NewErrorListener() *ErrorListener { - return &ErrorListener{ - Errs: make([]*ParseError, 0), - name: "kuneiform", - } -} - -// Err returns the error if there are any, otherwise it returns nil. -func (e *ErrorListener) Err() error { - if len(e.Errs) == 0 { - return nil - } - pe := ParseErrors(e.Errs) - return &pe -} - -// Errors returns the errors that have been collected. -func (e *ErrorListener) Errors() []*ParseError { - return e.Errs -} - -// Add adds errors from another error listener to this error listener. -func (e *ErrorListener) Add(errs ...*ParseError) { - e.Errs = append(e.Errs, errs...) -} - -// NodeErr adds an error that comes from a node. -func (e *ErrorListener) NodeErr(node *Node, errType ParseErrorType, err error) { - e.Errs = append(e.Errs, &ParseError{ - ParserName: e.name, - Type: errType, - Err: ErrMsg{err}, - Node: e.adjustNode(node), - }) -} - -// adjustNode adjusts the node based on the starting position of the error listener. -// It returns a copy of the node with the adjusted position. -func (e *ErrorListener) adjustNode(node *Node) *Node { - return &Node{ - IsSet: true, - StartLine: node.StartLine + e.startLine, - StartCol: node.StartCol + e.startCol, - EndLine: node.EndLine + e.startLine, - EndCol: node.EndCol + e.startCol, - } -} - -// TokenErr adds an error that comes from an Antlr token. -func (e *ErrorListener) TokenErr(t antlr.Token, errType ParseErrorType, err error) { - e.Errs = append(e.Errs, &ParseError{ - ParserName: e.name, - Type: errType, - Err: ErrMsg{err}, - Node: e.adjustNode(unaryNode(t.GetLine()-1, t.GetColumn())), - }) -} - -// RuleErr adds an error that comes from a Antlr parser rule. -func (e *ErrorListener) RuleErr(ctx antlr.ParserRuleContext, errType ParseErrorType, err error) { - node := &Node{} - node.Set(ctx) - e.Errs = append(e.Errs, &ParseError{ - ParserName: e.name, - Type: errType, - Err: ErrMsg{err}, - Node: e.adjustNode(node), - }) -} - -// Child creates a new error listener. It will not have any of the errors from the parent, -// and should simply be used for nested parsing. -func (e *ErrorListener) Child(name string, startLine, startCol int) *ErrorListener { - return &ErrorListener{ - name: name, - Errs: make([]*ParseError, 0), - startLine: e.startLine + startLine, - startCol: e.startCol + startCol, - } -} - -// ChildFromToken creates a new error listener that is a child of the current error listener. -// It will have the same starting position as the token. -// It is defined here because we have to account for antlr-go returning 1-indexed lines -// and 0-indexed columns, which is both confusing and non-standard for Antlr. We adjust -// everything to be 0-indexed, which while a-typical, is more convenient for tracking -// position in nested parsers. To abstract this aytpicality, we confine it all in this -// package. -func (e *ErrorListener) ChildFromToken(name string, t antlr.Token) *ErrorListener { - startline := t.GetLine() - 1 - startcol := t.GetColumn() - return e.Child(name, startline, startcol) -} - -// SyntaxError implements the Antlr error listener interface. -func (e *ErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, - msg string, ex antlr.RecognitionException) { - e.Errs = append(e.Errs, &ParseError{ - ParserName: e.name, - Type: ParseErrorTypeSyntax, - Err: ErrMsg{fmt.Errorf("%w: %s", ErrSyntaxError, msg)}, - Node: e.adjustNode(unaryNode(line, column)), - }) -} - -// We do not need to do anything in the below methods because they are simply Antlr's way of reporting. -// We may want to add warnings in the future, but for now, we will ignore them. -// https://stackoverflow.com/questions/71056312/antlr-how-to-avoid-reportattemptingfullcontext-and-reportambiguity - -// ReportAmbiguity implements the Antlr error listener interface. -func (e *ErrorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, - exact bool, ambigAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { -} - -// ReportAttemptingFullContext implements the Antlr error listener interface. -func (e *ErrorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, - stopIndex int, conflictingAlts *antlr.BitSet, configs *antlr.ATNConfigSet) { -} - -// ReportContextSensitivity implements the Antlr error listener interface. -func (e *ErrorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, - prediction int, configs *antlr.ATNConfigSet) { -} diff --git a/parse/types/errors.go b/parse/types/errors.go deleted file mode 100644 index bf02b2ef5..000000000 --- a/parse/types/errors.go +++ /dev/null @@ -1,42 +0,0 @@ -package types - -import ( - "errors" -) - -var ( - // ErrSyntaxError is returned when a syntax error is encountered. - ErrSyntaxError = errors.New("syntax error") - - ErrReadOnlyProcedureContainsDML = errors.New("read-only procedure contains DML statement") - ErrReadOnlyProcedureCallsMutative = errors.New("read-only procedure calls mutative procedure") - ErrUndeclaredVariable = errors.New("undeclared variable") - ErrVariableAlreadyDeclared = errors.New("variable already declared") - ErrUntypedVariable = errors.New("untyped variable") - ErrUnknownContextualVariable = errors.New("unknown contextual variable") - ErrUnknownFunctionOrProcedure = errors.New("unknown procedure/function") - ErrUnknownForeignProcedure = errors.New("unknown foreign procedure") - ErrUnknownField = errors.New("unknown field") - ErrArgCount = errors.New("argument count mismatch") - - // unknown reference errors - ErrForeignCallMissingField = errors.New("missing field in foreign call") - - // Type errors - ErrNotNumericType = errors.New("not a numeric type") - ErrReturnCount = errors.New("invalid number of return values") // used forr invalid number of returns - ErrAssignment = errors.New("assignment error") - ErrComparisonType = errors.New("comparison types do not match") - ErrArrayType = errors.New("incorrect type for array") - ErrArithmeticType = errors.New("arithmetic types do not match") - ErrParamType = errors.New("variable type does not match function parameter type") - - // procedure return errors - ErrReturnNextUsedInNonTableProc = errors.New("RETURN NEXT cannot be used in a procedure that does not return a table") - ErrReturnNextInvalidCount = errors.New("RETURN NEXT must return the same number of fields as the procedure return") - - // Loop errors - ErrInvalidIterable = errors.New("invalid iterable") - ErrBreakUsedOutsideOfLoop = errors.New("BREAK cannot be used outside of a loop") - ErrReturnNextUsedOutsideOfLoop = errors.New("RETURN NEXT cannot be used outside of a loop") -) diff --git a/parse/types/types.go b/parse/types/types.go deleted file mode 100644 index 994f02b7e..000000000 --- a/parse/types/types.go +++ /dev/null @@ -1,198 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/antlr4-go/antlr/v4" -) - -// ParseErrors is a collection of parse errors. -type ParseErrors []*ParseError - -var _ interface{ Unwrap() []error } = (*ParseErrors)(nil) - -// Unwrap allows errors.Is and error.As to identify wrapped errors. -func (p ParseErrors) Unwrap() []error { - errs := make([]error, len(p)) - for i := range p { - errs[i] = p[i] - } - return errs -} - -// Err returns all the errors as a single error. -func (p ParseErrors) Err() error { - if len(p) == 0 { - return nil - } - return &p -} - -// The zero value of a ParseErrors instance intentionally does not implement the -// error interface. The Err method will return nil if the length is zero. -var _ error = (*ParseErrors)(nil) - -// Error implements the error interface. -func (p *ParseErrors) Error() string { - errs := *p - switch len(errs) { - case 0: // use Err and this won't happen - return "" - case 1: - return errs[0].Error() - default: - var str strings.Builder - str.WriteString("detected multiple parse errors:") - for i, err := range errs { - str.WriteString(fmt.Sprintf("\n%d: %s", i, err.Error())) - } - return str.String() - } -} - -// Add adds errors to the collection. -func (p *ParseErrors) Add(errs ...*ParseError) { - *p = append(*p, errs...) -} - -// ParseError is an error that occurred during parsing. -type ParseError struct { - ParserName string `json:"parser_name,omitempty"` - Type ParseErrorType `json:"type"` - Err ErrMsg `json:"error"` - Node *Node `json:"node,omitempty"` -} - -// Unwrap() allows errors.Is and errors.As to find wrapped errors. -func (p ParseError) Unwrap() error { - return p.Err -} - -// Error satisfies the standard library error interface. -func (p *ParseError) Error() string { - // Add 1 to the line and column numbers to make them 1-indexed. - return fmt.Sprintf("(%s) %s error: start %d:%d end %d:%d: %s", p.ParserName, p.Type, - p.Node.StartLine+1, p.Node.StartCol+1, - p.Node.EndLine+1, p.Node.EndCol+1, p.Err) -} - -// ErrMsg is a type that can be used to create error messages. -// It marshals and unmarshals to and from a string. -type ErrMsg struct { - error -} - -// Error implements the error interface. -func (e ErrMsg) Error() string { - return e.error.Error() -} - -// Unwrap allows errors.Is and errors.As to find wrapped errors. -func (e ErrMsg) Unwrap() error { - return e.error -} - -// MarshalJSON marshals the error message to JSON. -func (e *ErrMsg) MarshalJSON() ([]byte, error) { - return json.Marshal(e.Error()) -} - -// UnmarshalJSON unmarshals the error message from JSON. -func (e *ErrMsg) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - - e.error = fmt.Errorf(s) - return nil -} - -// ParseErrorTypes are used to group errors into categories. -type ParseErrorType string - -const ( - ParseErrorTypeSyntax ParseErrorType = "syntax" - ParseErrorTypeType ParseErrorType = "type" - ParseErrorTypeSemantic ParseErrorType = "semantic" - ParseErrorTypeUnknown ParseErrorType = "unknown" -) - -// Node is a node in the parse tree. It represents a range of line and column -// values in Kuneiform source code. -type Node struct { - // Set is true if the position of the node has been set. - // This is useful for testing parsers. - IsSet bool `json:"-"` - StartLine int `json:"start_line"` - StartCol int `json:"start_col"` - EndLine int `json:"end_line"` - EndCol int `json:"end_col"` -} - -// Set sets the position of the node based on the given parser rule context. -func (n *Node) Set(r antlr.ParserRuleContext) { - n.IsSet = true - n.StartLine = r.GetStart().GetLine() - 1 - n.StartCol = r.GetStart().GetColumn() - n.EndLine = r.GetStop().GetLine() - 1 - n.EndCol = r.GetStop().GetColumn() -} - -// SetToken sets the position of the node based on the given token. -func (n *Node) SetToken(t antlr.Token) { - n.IsSet = true - n.StartLine = t.GetLine() - 1 - n.StartCol = t.GetColumn() - n.EndLine = t.GetLine() - 1 - n.EndCol = t.GetColumn() -} - -// GetNode returns the node. -// It is useful if the node is embedded in another struct. -func (n Node) GetNode() *Node { - return &n -} - -// unaryNode creates a node with the same start and end position. -func unaryNode(start, end int) *Node { - return &Node{ - StartLine: start, - StartCol: end, - EndLine: start, - EndCol: end, - } -} - -// MergeNodes merges two nodes into a single node. -// It starts at the left node and ends at the right node. -func MergeNodes(left, right *Node) *Node { - return &Node{ - StartLine: left.StartLine, - StartCol: left.StartCol, - EndLine: right.EndLine, - EndCol: right.EndCol, - } -} - -// SchemaInfo contains information about a parsed schema -type SchemaInfo struct { - // Blocks maps declared block names to their nodes. - // Block names include: - // - tables - // - extensions - // - actions - // - procedures - // - foreign procedures - Blocks map[string]*Block `json:"blocks"` -} - -type Block struct { - Node - // AbsStart is the absolute start position of the block in the source code. - AbsStart int `json:"abs_start"` - // AbsEnd is the absolute end position of the block in the source code. - AbsEnd int `json:"abs_end"` -} diff --git a/parse/util/procedure.go b/parse/util/procedure.go deleted file mode 100644 index f71327a53..000000000 --- a/parse/util/procedure.go +++ /dev/null @@ -1,84 +0,0 @@ -package util - -import ( - "fmt" - "strings" - - "github.com/kwilteam/kwil-db/core/types" - "github.com/kwilteam/kwil-db/parse/metadata" - parseTypes "github.com/kwilteam/kwil-db/parse/types" -) - -// FindProcOrForeign finds a procedure or foreign procedure by name. -// it returns the parameter types, and the return type. -func FindProcOrForeign(schema *types.Schema, name string) (parameters []*types.DataType, returns *types.ProcedureReturn, err error) { - if proc, ok := schema.FindProcedure(name); ok { - for _, p := range proc.Parameters { - parameters = append(parameters, p.Type) - } - - if proc.Returns != nil { - returns = proc.Returns - } - - return parameters, returns, nil - } - - if proc, ok := schema.FindForeignProcedure(name); ok { - parameters = append(parameters, proc.Parameters...) - - if proc.Returns != nil { - returns = proc.Returns - } - - return parameters, returns, nil - } - - return nil, nil, fmt.Errorf("%w: %s", parseTypes.ErrUnknownFunctionOrProcedure, name) -} - -// FormatProcedureName formats a procedure name for usage in postgres. This -// simply prepends the name with _fp_ -func FormatForeignProcedureName(name string) string { - return "_fp_" + name -} - -// FormatParameterName formats a parameter name for usage in postgres. This -// simply prepends the name with _param_, and removes the $ prefix. -func FormatParameterName(name string) string { - return "_param_" + name[1:] -} - -// UnformatParameterName removes the _param_ prefix from a parameter name. -// If it does not have the prefix, it will return the name as is. -func UnformatParameterName(name string) string { - name, cut := strings.CutPrefix(name, "_param_") - if cut { - return "$" + name - } - return name -} - -// FormatContextualVariableName formats a contextual variable name for usage in postgres. -// This uses the current_setting function to get the value of the variable. It also -// removes the @ prefix. If the type is not a text type, it will also type cast it. -// The type casting is necessary since current_setting returns all values as text. -func FormatContextualVariableName(name string, dataType *types.DataType) string { - str := fmt.Sprintf("current_setting('%s.%s')", metadata.PgSessionPrefix, name[1:]) - if dataType.Equals(types.TextType) { - return str - } - - switch dataType { - case types.BlobType: - return fmt.Sprintf("%s::bytea", str) - case types.IntType: - return fmt.Sprintf("%s::int8", str) - case types.BoolType: - return fmt.Sprintf("%s::bool", str) - case types.UUIDType: - return fmt.Sprintf("%s::uuid", str) - } - - panic("unallowed contextual variable type: " + dataType.String()) -} diff --git a/parse/util/util.go b/parse/util/util.go deleted file mode 100644 index c8bc98a67..000000000 --- a/parse/util/util.go +++ /dev/null @@ -1,24 +0,0 @@ -package util - -// ExtractSQLName remove surrounding lexical token(pair) of an identifier(name). -// Those tokens are: `"` and `[` `]` and "`". -// In sqlparser identifiers are used for: table name, table alias name, column name, -// column alias name, collation name, index name, function name. -func ExtractSQLName(name string) string { - // remove surrounding token pairs - if len(name) > 1 { - if name[0] == '"' && name[len(name)-1] == '"' { - name = name[1 : len(name)-1] - } - - if name[0] == '[' && name[len(name)-1] == ']' { - name = name[1 : len(name)-1] - } - - if name[0] == '`' && name[len(name)-1] == '`' { - name = name[1 : len(name)-1] - } - } - - return name -} diff --git a/parse/util/util_test.go b/parse/util/util_test.go deleted file mode 100644 index 5ed7bf6a6..000000000 --- a/parse/util/util_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package util_test - -import ( - "testing" - - "github.com/kwilteam/kwil-db/parse/util" - "github.com/stretchr/testify/assert" -) - -func TestExtractSQLName(t *testing.T) { - tests := []struct { - name string - args string - want string - }{ - {"empty", "", ""}, - {"asymmetric quotes with double quotes", `"a`, `"a`}, - {"asymmetric quotes with bracket quote", `[a`, `[a`}, - {"asymmetric quotes with back tick quote", "`a", "`a"}, - {"double quotes", `"a"`, `a`}, - {"bracket quotes", `[a]`, `a`}, - {"back tick quotes", "`a`", `a`}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, util.ExtractSQLName(tt.args), "ExtractSQLName(%v)", tt.args) - }) - } -} diff --git a/parse/wasm/wasm.go b/parse/wasm/wasm.go index 51f92c722..422295d66 100644 --- a/parse/wasm/wasm.go +++ b/parse/wasm/wasm.go @@ -12,18 +12,14 @@ import ( ) func parseAndMarshal(input string) (jsonStr string, err error) { - schema, err := parse.ParseKuneiform(input) + schema, err := parse.ParseAndValidate([]byte(input)) if err != nil { return "", err } - // convert all errors to be 1-indexed - for _, e := range schema.Errs { - e.Node.StartCol++ - e.Node.StartLine++ - e.Node.EndCol++ - e.Node.EndLine++ - } + // remove parsed action and procedure asts + schema.ParsedActions = nil + schema.ParsedProcedures = nil jsonBytes, err := json.Marshal(schema) if err != nil { diff --git a/test/acceptance/test-data/invalid_sql_syntax.kf b/test/acceptance/test-data/invalid_sql_syntax.kf index 72c326524..9bd93d6ec 100644 --- a/test/acceptance/test-data/invalid_sql_syntax.kf +++ b/test/acceptance/test-data/invalid_sql_syntax.kf @@ -8,6 +8,8 @@ table users { wallet text unique } +// invalid_sql is invalid because it returns ambigous columns, +// as it returns the same table twice. action invalid_sql() public { SELECT * FROM users AS u1 diff --git a/test/acceptance/test-data/invalid_sql_syntax_fixed.kf b/test/acceptance/test-data/invalid_sql_syntax_fixed.kf index 25aaa7e27..fb0a4b091 100644 --- a/test/acceptance/test-data/invalid_sql_syntax_fixed.kf +++ b/test/acceptance/test-data/invalid_sql_syntax_fixed.kf @@ -9,7 +9,7 @@ table users { } action invalid_sql() public { - SELECT * + SELECT u1.* FROM users AS u1 INNER JOIN users AS u2 ON u1.id = u2.id; } \ No newline at end of file diff --git a/test/acceptance/test-data/test_db.kf b/test/acceptance/test-data/test_db.kf index dc43d0638..e8be74ea6 100644 --- a/test/acceptance/test-data/test_db.kf +++ b/test/acceptance/test-data/test_db.kf @@ -36,7 +36,7 @@ action update_user($id, $username, $age) public { } action update_username($username) public { - UPDATE `users` + UPDATE users SET username = $username WHERE wallet = @caller; } @@ -132,15 +132,15 @@ action create_post_nested($id, $title, $content) public { @kgw(authn='true') action owner_only() public owner view { - select 'owner only'; + select 'owner only' as result; } @kgw(authn='true') action authn_only_action() public view { - select 'authn only action'; + select 'authn only action' as result; } @kgw(authn='true') action authn_only_procedure() public view { - select 'authn only procedure'; + select 'authn only procedure' as result; } diff --git a/test/acceptance/test-data/users.kf b/test/acceptance/test-data/users.kf index 4bf448397..30d9733f3 100644 --- a/test/acceptance/test-data/users.kf +++ b/test/acceptance/test-data/users.kf @@ -63,7 +63,9 @@ procedure get_user_by_owner($address text) public view returns (id uuid, age int // increment_post_count increments a user's post count, identified by the owner. // it returns the user id and the new post count procedure increment_post_count($address text) private returns (id uuid, post_count int) { - for $row in UPDATE users SET post_count = post_count+1 WHERE address = $address returning id, post_count { + UPDATE users SET post_count = post_count+1 WHERE address = $address; + + for $row in select id, post_count from users where address = $address { return $row.id, $row.post_count; } @@ -107,7 +109,7 @@ procedure get_recent_posts_by_size($username text, $size int, $limit int) public } $count int := 0; - for $row in get_recent_posts($username) { + for $row in select * from get_recent_posts($username) { if $count == $limit { break; } @@ -124,7 +126,7 @@ procedure get_recent_posts_by_size($username text, $size int, $limit int) public procedure reverse_latest_posts($username text, $limit int) public view returns (content text[]) { $content text[]; - for $post in get_recent_posts($username) { + for $post in select * from get_recent_posts($username) { $content := array_append($content, $post.content); } @@ -136,7 +138,7 @@ procedure reverse_latest_posts($username text, $limit int) public view returns ( procedure reverse_array($arr text[]) public view returns (reversed text[]) { $rev text[]; - for $i in 1:array_length($arr) { + for $i in 1..array_length($arr) { $rev := array_prepend($arr[$i], $rev); } diff --git a/test/go.mod b/test/go.mod index babf83538..82b7d40d6 100644 --- a/test/go.mod +++ b/test/go.mod @@ -59,6 +59,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.0 // indirect diff --git a/test/go.sum b/test/go.sum index 6f565e0aa..c0bf79c0f 100644 --- a/test/go.sum +++ b/test/go.sum @@ -117,6 +117,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= @@ -1040,6 +1042,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/test/integration/kwild_test.go b/test/integration/kwild_test.go index 84f906b9c..45221f94a 100644 --- a/test/integration/kwild_test.go +++ b/test/integration/kwild_test.go @@ -18,7 +18,7 @@ var dev = flag.Bool("dev", false, "run for development purpose (no tests)") var spamTest = flag.Bool("spam", false, "run the spam test that requires a special docker image to be built") -var drivers = flag.String("drivers", "jsonrpc,cli", "comma separated list of drivers to run") +var drivers = flag.String("drivers", "jsonrpc", "comma separated list of drivers to run") // NOTE: `-parallel` is a flag that is already used by `go test` var parallelMode = flag.Bool("parallel-mode", false, "run tests in parallel mode") diff --git a/test/integration/test-data/dummy.kf b/test/integration/test-data/dummy.kf index f427cab60..e3d6992aa 100644 --- a/test/integration/test-data/dummy.kf +++ b/test/integration/test-data/dummy.kf @@ -22,13 +22,13 @@ action create_user($id, $username, $age) public { } action update_user($id, $username, $age) public { - UPDATE [users] + UPDATE users SET id = $id, username = $username, age = $age WHERE wallet = @caller; } action update_username($username) public { - UPDATE `users` + UPDATE users SET username = $username WHERE wallet = @caller; } diff --git a/test/integration/test-data/invalid_sql_syntax_fixed.kf b/test/integration/test-data/invalid_sql_syntax_fixed.kf index 25aaa7e27..fb0a4b091 100644 --- a/test/integration/test-data/invalid_sql_syntax_fixed.kf +++ b/test/integration/test-data/invalid_sql_syntax_fixed.kf @@ -9,7 +9,7 @@ table users { } action invalid_sql() public { - SELECT * + SELECT u1.* FROM users AS u1 INNER JOIN users AS u2 ON u1.id = u2.id; } \ No newline at end of file diff --git a/test/integration/test-data/test_db.kf b/test/integration/test-data/test_db.kf index 10b3e5ce4..bd4b2237e 100644 --- a/test/integration/test-data/test_db.kf +++ b/test/integration/test-data/test_db.kf @@ -36,7 +36,7 @@ action update_user($id, $username, $age) public { } action update_username($username) public { - UPDATE `users` + UPDATE users SET username = $username WHERE wallet = @caller; } diff --git a/test/specifications/utils.go b/test/specifications/utils.go index d738ac313..ad52f7a03 100644 --- a/test/specifications/utils.go +++ b/test/specifications/utils.go @@ -10,7 +10,6 @@ import ( "github.com/kwilteam/kwil-db/core/types" "github.com/kwilteam/kwil-db/parse" - "github.com/kwilteam/kwil-db/parse/kuneiform" "github.com/kwilteam/kwil-db/test/driver" "github.com/stretchr/testify/require" ) @@ -32,7 +31,7 @@ func (l *FileDatabaseSchemaLoader) Load(t *testing.T, targetSchema *testSchema) t.Fatal("cannot open database schema file", err) } - parseResult, err := parse.ParseKuneiform(string(d)) + parseResult, err := parse.ParseAndValidate(d) if err != nil { t.Fatal("cannot parse database schema", err) } @@ -52,15 +51,15 @@ func (l *FileDatabaseSchemaLoader) LoadWithoutValidation(t *testing.T, targetSch t.Fatal("cannot open database schema file", err) } - db, _, _, err := kuneiform.Parse(string(d)) + db, err := parse.ParseSchema(d) if err != nil { t.Fatal("cannot parse database schema", err) } // ignore parser validation error - l.Modifier(db) + l.Modifier(db.Schema) - return db + return db.Schema } func ExpectTxSuccess(t *testing.T, spec TxQueryDsl, ctx context.Context, txHash []byte) { diff --git a/test/stress/scheme.go b/test/stress/scheme.go index f8d4e289b..8f5461672 100644 --- a/test/stress/scheme.go +++ b/test/stress/scheme.go @@ -24,7 +24,7 @@ const ( ) func loadTestSchema() (*types.Schema, error) { - res, err := parse.ParseKuneiform(testScheme) + res, err := parse.ParseAndValidate([]byte(testScheme)) if err != nil { return nil, err }