diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ce776b5..10763f36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,9 @@ jobs: ports: - 5432:5432 + env: + DB_CONNECTION_STRING: postgresql://postgres:postgres@localhost:5432/postgres + steps: - name: 🏗 Setup repository uses: actions/checkout@v3 @@ -38,6 +41,9 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Run test migrations + run: psql -f test-db/seed.sql postgresql://postgres:postgres@localhost:5432/postgres + - name: 📦 Build id: build run: cargo build diff --git a/.gitmodules b/.gitmodules index b344f3c0..a8ab9235 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,6 +2,6 @@ path = libpg_query url = https://github.com/pganalyze/libpg_query.git [submodule "crates/tree_sitter_sql/tree-sitter-sql"] - path = crates/tree_sitter_sql/tree-sitter-sql + path = lib/tree_sitter_sql/tree-sitter-sql url = https://github.com/DerekStride/tree-sitter-sql branch = gh-pages diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 00000000..5a10be2d --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,71 @@ +## Architecture + +This document describes the high-level architecture of postgres_lsp. If you want to familiarize yourself with the code base, you are just in the right place! + +> Since the project still evolves rapidly, this document may not be up-to-date. If you find any inconsistency, please let us know by creating an issue. + +### Bird's Eye View + +On the highest level, the postgres language server is a thing which accepts input source code, cuts it into individual sql statements and parses and analyses each. In addition, it connects to a postgres database and stores an im-memory schema cache with all required type information such as tables, columns and functions. The result of the parsing is used alongside the schema cache to answer queries about a statement. + +The client can submit a delta of input data (typically, a change to a single file), and the server will update the affected statements and their analysis accordingly. The underlying engine makes sure that we only re-parse and re-analyse what is necessary. + +### Entry Points + +The main entry point is as of now the `pg_lsp` crate, especially the `main.rs` function. It spawns the language server and starts listening for incoming messages. The server is implemented in the `server` module. + +There might be an additional entry point for a CLI tool in the future. + +### Code Map + +This section talks briefly about various important directories and data structures. + +#### `lib/` + +Independent libraries that are used by the project but are not specific for postgres. + +#### `crates/pg_lsp` + +The main entry point of the language server. It contains the server implementation and the main loop. + +#### `crates/pg_workspace` + +> This crate will grow significantly in near future. The current implementation just contains the base data structures and stores the diagnostic results from various features. + +The main API for consumers of the IDE. It stores the internal state of the workspace, such as the schema cache and the parsed statements and their analysis. + +#### `crates/pg_lexer` + +Simple lexer that tokenizes the input source code. Enhances the output of the `pg_query` tokenizer with the missing whitespace tokens. + +#### `crates/pg_statement_splitter` + +Implements the statement splitter, which cuts the input source code into individual statements. + +#### `crates/pg_base_db` + +Implements the base data structures and defines how documents and statements are stored and updated efficiently. + +#### `crates/pg_schema_cache` + +We store an in-memory representation of the database schema to efficiently resolve types. + +#### `crates/pg_query_ext` + +Simple wrapper crate for `pg_query` to expose types and a function to get the root node for an SQL statement. It also host any "extensions" to the `pg_query` crate that are not yet contributed upstream. Once all extensions are contributed upstream, this crate will be removed. + +#### `crates/pg_query_proto_parser` + +We use procedural macros a lot to generate repetitive code from the protobuf definition provided by `libg_query`. The `pg_query_proto_parser` crate is used to parse the proto file into a more usable data structure. + +#### `crates/pg_syntax` + +Implements the CST parser and AST enhancer. The CST parser is what is described in [this blog post](https://supabase.com/blog/postgres-language-server-implementing-parser). The AST enhancer takes in the CST and enriches the AST returned by `pg_query` with a range for each node. + +#### `crates/pg_type_resolver` + +Utility crate used by the feature crates listed below to resolve the source types to the actual types in the schema cache. + +#### `crates/pg_commands`, `crates/pg_completions`, `crates/pg_hover`, `crates/pg_inlay_hints`, `crates/pg_lint`, `crates/pg_typecheck` + +These crates implement the various features of the language server. They are all independent of each other and always operate on the schema cache and a single statement and its parse results. They are intentionally implemented in separate creates and without any language server flavour to make them reusable eg in a later cli. diff --git a/Cargo.lock b/Cargo.lock index 1049295f..0044279e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" @@ -47,9 +38,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "async-channel" @@ -64,13 +55,12 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.0.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy 0.5.2", "futures-core", "pin-project-lite", ] @@ -95,7 +85,7 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.2.0", + "async-channel 2.3.1", "async-executor", "async-io 2.3.1", "async-lock 3.3.0", @@ -120,7 +110,7 @@ dependencies = [ "polling 2.8.0", "rustix 0.37.27", "slab", - "socket2 0.4.10", + "socket2", "waker-fn", ] @@ -195,17 +185,6 @@ version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "atoi" version = "2.0.0" @@ -231,49 +210,12 @@ dependencies = [ "rand", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "auto_impl" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.21.7" @@ -305,7 +247,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.48", + "syn 2.0.71", "which", ] @@ -339,7 +281,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.2.0", + "async-channel 2.3.1", "async-lock 3.3.0", "async-task", "fastrand 2.0.1", @@ -411,20 +353,11 @@ dependencies = [ "cc", ] -[[package]] -name = "codegen" -version = "0.0.0" -dependencies = [ - "pg_query_proto_parser", - "proc-macro2", - "quote", -] - [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -489,6 +422,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.11" @@ -537,7 +479,7 @@ checksum = "0da6c38bede0ecec78757fe92451c463ac9e6d37961c2cbce6a20be917951baf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] @@ -606,19 +548,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -686,9 +615,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ "event-listener 5.0.0", "pin-project-lite", @@ -757,20 +686,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.30" @@ -843,17 +758,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "futures-sink" version = "0.3.30" @@ -872,10 +776,8 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "futures-channel", "futures-core", "futures-io", - "futures-macro", "futures-sink", "futures-task", "memchr", @@ -914,12 +816,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "glob" version = "0.3.1" @@ -972,15 +868,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.5" @@ -1020,18 +907,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "idna" version = "0.5.0" @@ -1090,7 +965,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.5", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -1185,6 +1060,13 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "line_index" +version = "0.0.0" +dependencies = [ + "text-size", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -1215,18 +1097,30 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "value-bag", ] +[[package]] +name = "lsp-server" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248f65b78f6db5d8e1b1604b4098a28b43d21a8eb1deeca22b1c421b276c7095" +dependencies = [ + "crossbeam-channel", + "log", + "serde", + "serde_json", +] + [[package]] name = "lsp-types" -version = "0.94.1" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" +checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984" dependencies = [ "bitflags 1.3.2", "serde", @@ -1266,17 +1160,6 @@ dependencies = [ "adler", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "multimap" version = "0.8.3" @@ -1363,19 +1246,10 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.5", + "hermit-abi", "libc", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" @@ -1411,22 +1285,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "parser" -version = "0.0.0" -dependencies = [ - "codegen", - "cstree", - "env_logger", - "insta", - "log", - "petgraph", - "pg_query", - "pg_query_proto_parser", - "regex", - "serde_json", -] - [[package]] name = "paste" version = "1.0.14" @@ -1464,6 +1322,133 @@ dependencies = [ "indexmap 2.2.2", ] +[[package]] +name = "pg_base_db" +version = "0.0.0" +dependencies = [ + "line_index", + "pg_statement_splitter", + "text-size", +] + +[[package]] +name = "pg_commands" +version = "0.0.0" +dependencies = [ + "anyhow", + "async-std", + "sqlx", + "text-size", +] + +[[package]] +name = "pg_completions" +version = "0.0.0" +dependencies = [ + "async-std", + "pg_schema_cache", + "sqlx", + "text-size", + "tree-sitter", + "tree_sitter_sql", +] + +[[package]] +name = "pg_diagnostics" +version = "0.0.0" +dependencies = [ + "text-size", +] + +[[package]] +name = "pg_hover" +version = "0.0.0" +dependencies = [ + "pg_query_ext", + "pg_schema_cache", + "pg_syntax", + "text-size", + "tree-sitter", + "tree_sitter_sql", +] + +[[package]] +name = "pg_inlay_hints" +version = "0.0.0" +dependencies = [ + "async-std", + "pg_query_ext", + "pg_schema_cache", + "pg_syntax", + "pg_type_resolver", + "sqlx", + "text-size", + "tree-sitter", + "tree_sitter_sql", +] + +[[package]] +name = "pg_lexer" +version = "0.0.0" +dependencies = [ + "cstree", + "insta", + "pg_lexer_codegen", + "pg_query", + "regex", + "text-size", +] + +[[package]] +name = "pg_lexer_codegen" +version = "0.0.0" +dependencies = [ + "pg_query_proto_parser", + "proc-macro2", + "quote", +] + +[[package]] +name = "pg_lint" +version = "0.0.0" +dependencies = [ + "lazy_static", + "pg_base_db", + "pg_query_ext", + "pg_syntax", + "serde", + "serde_json", + "serde_plain", + "text-size", +] + +[[package]] +name = "pg_lsp" +version = "0.0.0" +dependencies = [ + "anyhow", + "async-channel 2.3.1", + "async-std", + "crossbeam-channel", + "dashmap", + "line_index", + "lsp-server", + "lsp-types", + "pg_base_db", + "pg_commands", + "pg_completions", + "pg_diagnostics", + "pg_hover", + "pg_inlay_hints", + "pg_schema_cache", + "pg_workspace", + "serde", + "serde_json", + "sqlx", + "text-size", + "threadpool", +] + [[package]] name = "pg_query" version = "0.8.2" @@ -1480,6 +1465,25 @@ dependencies = [ "thiserror", ] +[[package]] +name = "pg_query_ext" +version = "0.0.0" +dependencies = [ + "petgraph", + "pg_lexer", + "pg_query", + "pg_query_ext_codegen", +] + +[[package]] +name = "pg_query_ext_codegen" +version = "0.0.0" +dependencies = [ + "pg_query_proto_parser", + "proc-macro2", + "quote", +] + [[package]] name = "pg_query_proto_parser" version = "0.0.0" @@ -1490,23 +1494,76 @@ dependencies = [ ] [[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +name = "pg_schema_cache" +version = "0.0.0" dependencies = [ - "pin-project-internal", + "async-std", + "serde", + "serde_json", + "sqlx", ] [[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +name = "pg_statement_splitter" +version = "0.0.0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", + "pg_lexer", + "pg_query", + "text-size", +] + +[[package]] +name = "pg_syntax" +version = "0.0.0" +dependencies = [ + "cstree", + "insta", + "petgraph", + "pg_lexer", + "pg_query", + "pg_query_ext", + "text-size", +] + +[[package]] +name = "pg_type_resolver" +version = "0.0.0" +dependencies = [ + "pg_query_ext", + "pg_schema_cache", +] + +[[package]] +name = "pg_typecheck" +version = "0.0.0" +dependencies = [ + "async-std", + "pg_base_db", + "pg_query_ext", + "pg_schema_cache", + "pg_syntax", + "sqlx", + "text-size", +] + +[[package]] +name = "pg_workspace" +version = "0.0.0" +dependencies = [ + "async-std", + "dashmap", + "pg_base_db", + "pg_diagnostics", + "pg_hover", + "pg_lint", + "pg_query_ext", + "pg_schema_cache", + "pg_syntax", + "pg_typecheck", + "sqlx", + "text-size", + "tree-sitter", + "tree_sitter_sql", ] [[package]] @@ -1589,21 +1646,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "postgres_lsp" -version = "0.0.0" -dependencies = [ - "dashmap", - "env_logger", - "log", - "parser", - "ropey", - "serde", - "serde_json", - "tokio", - "tower-lsp", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -1623,14 +1665,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1817,16 +1859,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "ropey" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5" -dependencies = [ - "smallvec", - "str_indices", -] - [[package]] name = "rsa" version = "0.9.6" @@ -1847,12 +1879,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -1922,14 +1948,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "schema_cache" -version = "0.0.0" -dependencies = [ - "async-std", - "sqlx", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1963,20 +1981,29 @@ checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_plain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + [[package]] name = "serde_repr" version = "0.1.18" @@ -1985,7 +2012,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] @@ -2016,15 +2043,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "signature" version = "2.2.0" @@ -2066,16 +2084,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "spin" version = "0.5.2" @@ -2324,12 +2332,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "str_indices" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" - [[package]] name = "stringprep" version = "0.1.4" @@ -2360,9 +2362,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -2381,15 +2383,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "text-size" version = "1.1.1" @@ -2413,7 +2406,16 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", ] [[package]] @@ -2450,110 +2452,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.5.5", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-lsp" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b38fb0e6ce037835174256518aace3ca621c4f96383c56bb846cfc11b341910" -dependencies = [ - "async-trait", - "auto_impl", - "bytes", - "dashmap", - "futures", - "httparse", - "lsp-types", - "memchr", - "serde", - "serde_json", - "tokio", - "tokio-util", - "tower", - "tower-lsp-macros", - "tracing", -] - -[[package]] -name = "tower-lsp-macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34723c06344244474fdde365b76aebef8050bf6be61a935b91ee9ff7c4e91157" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.40" @@ -2574,7 +2472,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] @@ -2727,7 +2625,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", "wasm-bindgen-shared", ] @@ -2761,7 +2659,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2822,15 +2720,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3044,7 +2933,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.71", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6e6fb923..5f37a1a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "crates/*", + "lib/*", "xtask/" ] resolver = "2" @@ -9,13 +10,36 @@ resolver = "2" rust-version = "1.71" [workspace.dependencies] -tree_sitter_sql = { path = "./crates/tree_sitter_sql", version = "0.0.0" } -schema_cache = { path = "./crates/schema_cache", version = "0.0.0" } -parser = { path = "./crates/parser", version = "0.0.0" } -codegen = { path = "./crates/codegen", version = "0.0.0" } -sourcegen = { path = "./crates/sourcegen", version = "0.0.0" } +# supporting crates unrelated to postgres +line_index = { path = "./lib/line_index", version = "0.0.0" } +tree_sitter_sql = { path = "./lib/tree_sitter_sql", version = "0.0.0" } +tree-sitter = "0.20.10" + +# postgres specific crates +pg_lexer = { path = "./crates/pg_lexer", version = "0.0.0" } +pg_diagnostics = { path = "./crates/pg_diagnostics", version = "0.0.0" } +pg_lexer_codegen = { path = "./crates/pg_lexer_codegen", version = "0.0.0" } +pg_statement_splitter = { path = "./crates/pg_statement_splitter", version = "0.0.0" } +pg_query_ext = { path = "./crates/pg_query_ext", version = "0.0.0" } +pg_query_ext_codegen = { path = "./crates/pg_query_ext_codegen", version = "0.0.0" } +pg_syntax = { path = "./crates/pg_syntax", version = "0.0.0" } +pg_schema_cache = { path = "./crates/pg_schema_cache", version = "0.0.0" } +pg_commands = { path = "./crates/pg_commands", version = "0.0.0" } +pg_completions = { path = "./crates/pg_completions", version = "0.0.0" } +pg_base_db = { path = "./crates/pg_base_db", version = "0.0.0" } pg_query_proto_parser = { path = "./crates/pg_query_proto_parser", version = "0.0.0" } -triomphe = { version = "0.1.8", default-features = false, features = ["std"] } +pg_typecheck = { path = "./crates/pg_typecheck", version = "0.0.0" } +pg_type_resolver = { path = "./crates/pg_type_resolver", version = "0.0.0" } +pg_hover = { path = "./crates/pg_hover", version = "0.0.0" } +pg_inlay_hints = { path = "./crates/pg_inlay_hints", version = "0.0.0" } +pg_lint = { path = "./crates/pg_lint", version = "0.0.0" } +pg_workspace = { path = "./crates/pg_workspace", version = "0.0.0" } +pg_lsp = { path = "./crates/lsp", version = "0.0.0" } + +# parser = { path = "./crates/parser", version = "0.0.0" } +# sql_parser = { path = "./crates/sql_parser", version = "0.0.0" } +# sql_parser_codegen = { path = "./crates/sql_parser_codegen", version = "0.0.0" } + [profile.dev.package] insta.opt-level = 3 diff --git a/README.md b/README.md index 34c65b0a..879fe9d5 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,25 @@ A Language Server for Postgres. Not SQL with flavors, just Postgres. -## Status - -🚧 This is in active development and is only ready for collaborators. The majority of work is still ahead, but we've verified that the approach works. We're making this public so that we can develop it in the open with input from the community. +> [!WARNING] +> This is in active development and is only ready for collaborators. But we are getting there! You can find the current roadmap and opportunities to contribute in https://github.com/supabase-community/postgres_lsp/issues/136. ## Features The [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) is an open protocol between code editors and servers to provide code intelligence tools such as code completion and syntax highlighting. This project implements such a language server for Postgres, significantly enhancing the developer experience within your favorite editor by adding: -- Semantic Highlighting +- Lint +- Hover +- Typechecking - Syntax Error Diagnostics -- Show SQL comments on hover +- Inlay Hints - Auto-Completion - Code actions such as `Execute the statement under the cursor`, or `Execute the current file` -- Configurable Code Formatting +- Formatter - ... and many more +We plan to support all of the above for SQL and PL/pgSQL function bodies too! + ## Motivation Despite the rising popularity of Postgres, support for the PL/pgSQL in IDEs and editors is limited. While there are some _generic_ SQL Language Servers[^1] offering the Postgres syntax as a "flavor" within the parser, they usually fall short due to the ever-evolving and complex syntax of PostgreSQL. There are a few proprietary IDEs[^2] that work well, but the features are only available within the respective IDE. @@ -28,39 +31,14 @@ This Language Server is designed to support Postgres, and only Postgres. The ser Once the parser is stable, and a robust and scalable data model is implemented, the language server will not only provide basic features such as semantic highlighting, code completion and syntax error diagnostics, but also serve as the user interface for all the great tooling of the Postgres ecosystem. -## Roadmap - -This is a proof of concept for building both a concrete syntax tree and an abstract syntax tree from a potentially malformed PostgreSQL source code. The `postgres_lsp` crate was created to prove that it works end-to-end, and is just a very basic language server with semantic highlighting and error diagnostics. Before further feature development, we have to complete a bit of groundwork: - -1. _Finish the parser_ - - ✅ The core parser algorithm is implemented. Check out [this blog post](https://supabase.com/blog/postgres-language-server-implementing-parser) for details. - - 🚧 But we need help from the community to finalize it: https://github.com/supabase/postgres_lsp/issues/51. -2. _Implement a robust and scalable data model_ - - RFC posted here https://github.com/supabase/postgres_lsp/discussions/107 -3. _Setup the language server properly_ - - This is still in a research phase - - Once again `rust-analyzer` will serve as a role model, and we will most likely implement the same queueing and cancellation approach -4. _Implement basic language server features_ - - Semantic Highlighting - - Syntax Error Diagnostics - - Show SQL comments on hover - - Auto-Completion - - Code Actions, such as `Execute the statement under the cursor`, or `Execute the current file` - - ... anything you can think of really -5. _Integrate all the existing open source tooling_ - - Show migration file lint errors from [squawk](https://github.com/sbdchd/squawk) - - Show plpsql lint errors from [plpgsql_check](https://github.com/okbob/plpgsql_check) -6. _Build missing pieces_ - - An optionated code formatter (think prettier for PostgreSQL) -7. _(Maybe) Support advanced features with declarative schema management_ - - Jump to definition - - ... anything you can think of really - ## Installation > [!WARNING] > This is not ready for production use. Only install this if you want to help with development. +> [!NOTE] +> Interested in setting up a release process and client extensions for Neovim and VS Code? Please check out https://github.com/supabase-community/postgres_lsp/issues/136! + ### Neovim Add the postgres_lsp executable to your path, and add the following to your config to use it. @@ -81,7 +59,7 @@ lsp.configure("postgres_lsp", {force_setup = true}) ### Building from source -You'll need *nightly* Cargo, Node, and npm installed. +You'll need _nightly_ Cargo, Node, and npm installed. Install the `libpg_query` submodule by running: @@ -101,28 +79,25 @@ If you're not using VS Code, you can install the server by running: cargo xtask install --server ``` - The server binary will be installed in `.cargo/bin`. Make sure that `.cargo/bin` is in `$PATH`. ### Github CodeSpaces + Currently, Windows does not support `libpg_query`. You can setup your development environment on [CodeSpaces](https://github.com/features/codespaces). After your codespace boots up, run the following command in the shell to install Rust: + ```shell curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh ``` + Proceed with the rest of the installation as usual. ## Contributors - [psteinroe](https://github.com/psteinroe) (Maintainer) -## Acknowledgments - -- [rust-analyzer](https://github.com/rust-lang/rust-analyzer) for implementing such a robust, well documented, and feature-rich language server. Great place to learn from. -- [squawk](https://github.com/sbdchd/squawk) and [pganalyze](https://pganalyze.com) for inspiring the use of libpg_query. - ## Footnotes [^1]: Generic SQL Solutions: [sql-language-server](https://github.com/joe-re/sql-language-server), [pgFormatter](https://github.com/darold/pgFormatter/tree/master), [sql-parser-cst](https://github.com/nene/sql-parser-cst) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs deleted file mode 100644 index a5fce229..00000000 --- a/crates/codegen/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -mod get_location; -mod get_node_properties; -mod get_nodes; -mod parser; -mod syntax_kind; - -use parser::parser_mod; - -#[proc_macro] -pub fn parser_codegen(item: proc_macro::TokenStream) -> proc_macro::TokenStream { - parser_mod(item.into()).into() -} diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml deleted file mode 100644 index 92edf274..00000000 --- a/crates/parser/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "parser" -version = "0.0.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -petgraph = "0.6.4" -cstree = { version = "0.12.0", features = ["derive"] } -pg_query = "0.8" -serde_json = "1.0" -regex = "1.9.1" -env_logger = { version = "0.9.1" } -log = { version = "0.4.20" } - -codegen.workspace = true -pg_query_proto_parser.workspace = true - -[dev-dependencies] -insta = "1.31.0" - -[lib] -doctest = false - -[features] -lazy_cell = [] diff --git a/crates/parser/src/ast_node.rs b/crates/parser/src/ast_node.rs deleted file mode 100644 index 56524ccd..00000000 --- a/crates/parser/src/ast_node.rs +++ /dev/null @@ -1,10 +0,0 @@ -use cstree::text::TextRange; -use pg_query::NodeEnum; - -// TODO: implement serde for node: https://serde.rs/remote-derive.html - -#[derive(Debug)] -pub struct RawStmt { - pub stmt: NodeEnum, - pub range: TextRange, -} diff --git a/crates/parser/src/codegen.rs b/crates/parser/src/codegen.rs deleted file mode 100644 index 43469980..00000000 --- a/crates/parser/src/codegen.rs +++ /dev/null @@ -1,402 +0,0 @@ -use codegen::parser_codegen; - -parser_codegen!(); - -#[cfg(test)] -mod tests { - use log::debug; - - use crate::codegen::{get_nodes, SyntaxKind, TokenProperty}; - - fn init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - #[test] - fn test_get_nodes() { - init(); - - let input = "with c as (insert into contact (id) values ('id')) select * from c;"; - - let pg_query_root = match pg_query::parse(input) { - Ok(parsed) => Some( - parsed - .protobuf - .nodes() - .iter() - .find(|n| n.1 == 1) - .unwrap() - .0 - .to_enum(), - ), - Err(_) => None, - }; - - let node_graph = get_nodes(&pg_query_root.unwrap(), 0); - assert_eq!(node_graph.node_count(), 13); - } - - fn test_get_node_properties(input: &str, kind: SyntaxKind, expected: Vec) { - init(); - - let pg_query_root = match pg_query::parse(input) { - Ok(parsed) => Some( - parsed - .protobuf - .nodes() - .iter() - .find(|n| n.1 == 1) - .unwrap() - .0 - .to_enum(), - ), - Err(_) => None, - }; - - debug!("pg_query_root: {:#?}", pg_query_root); - - let node_graph = get_nodes(&pg_query_root.unwrap(), 0); - - debug!("node graph: {:#?}", node_graph); - - let node_index = node_graph - .node_indices() - .find(|n| node_graph[*n].kind == kind) - .unwrap(); - - debug!("selected node: {:#?}", node_graph[node_index]); - - // note: even though we test for strict equality of the two vectors the order - // of the properties does not have to match the order of the tokens in the string - assert_eq!(node_graph[node_index].properties, expected); - assert_eq!(node_graph[node_index].properties.len(), expected.len()); - } - - #[test] - fn test_simple_select() { - test_get_node_properties( - "select 1;", - SyntaxKind::SelectStmt, - vec![TokenProperty::from(SyntaxKind::Select)], - ) - } - - #[test] - fn test_select_with_from() { - test_get_node_properties( - "select 1 from contact;", - SyntaxKind::SelectStmt, - vec![ - TokenProperty::from(SyntaxKind::Select), - TokenProperty::from(SyntaxKind::From), - ], - ) - } - - #[test] - fn test_select_with_where() { - test_get_node_properties( - "select 1 from contact where id = 1;", - SyntaxKind::SelectStmt, - vec![ - TokenProperty::from(SyntaxKind::Select), - TokenProperty::from(SyntaxKind::From), - TokenProperty::from(SyntaxKind::Where), - ], - ) - } - - #[test] - fn test_select_with_order_by() { - test_get_node_properties( - "SELECT a, b, c FROM table1 ORDER BY c;", - SyntaxKind::SortBy, - vec![ - TokenProperty::from(SyntaxKind::Order), - TokenProperty::from(SyntaxKind::By), - ], - ) - } - - #[test] - fn test_create_domain() { - test_get_node_properties( - "create domain us_postal_code as text check (value is not null);", - SyntaxKind::CreateDomainStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::DomainP), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from("us_postal_code".to_string()), - ], - ) - } - - #[test] - fn test_create_schema() { - test_get_node_properties( - "create schema if not exists test authorization joe;", - SyntaxKind::CreateSchemaStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Schema), - TokenProperty::from(SyntaxKind::IfP), - TokenProperty::from(SyntaxKind::Not), - TokenProperty::from(SyntaxKind::Exists), - TokenProperty::from(SyntaxKind::Authorization), - TokenProperty::from("test".to_string()), - ], - ) - } - - #[test] - fn test_create_view() { - test_get_node_properties( - "create or replace temporary view comedies as select * from films;", - SyntaxKind::ViewStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::View), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from(SyntaxKind::Or), - TokenProperty::from(SyntaxKind::Replace), - TokenProperty::from(SyntaxKind::Temporary), - ], - ) - } - - #[test] - fn test_create_enum() { - test_get_node_properties( - "create type status as enum ('open', 'closed');", - SyntaxKind::CreateEnumStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::TypeP), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from(SyntaxKind::EnumP), - TokenProperty::from("status".to_string()), - TokenProperty::from("open".to_string()), - TokenProperty::from("closed".to_string()), - ], - ) - } - - #[test] - fn test_create_cast() { - test_get_node_properties( - "create cast (bigint as int4) with inout as assignment;", - SyntaxKind::CreateCastStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Cast), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from(SyntaxKind::With), - TokenProperty::from(SyntaxKind::Inout), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from(SyntaxKind::Assignment), - ], - ) - } - - #[test] - fn test_create_range() { - test_get_node_properties( - "create type type1 as range (subtype = int4);", - SyntaxKind::CreateRangeStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::TypeP), - TokenProperty::from(SyntaxKind::As), - TokenProperty::from(SyntaxKind::Range), - TokenProperty::from("type1".to_string()), - ], - ) - } - - #[test] - fn test_create_function() { - test_get_node_properties( - r#"create function getfoo(int) - returns setof users - language sql - as $$select * from "users" where users.id = $1;$$; - "#, - SyntaxKind::CreateFunctionStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Function), - TokenProperty::from(SyntaxKind::Returns), - TokenProperty::from(SyntaxKind::Setof), - TokenProperty::from("getfoo".to_string()), - ], - ) - } - - #[test] - fn test_create_index() { - test_get_node_properties( - "create unique index title_idx on films (title);", - SyntaxKind::IndexStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Unique), - TokenProperty::from(SyntaxKind::Index), - TokenProperty::from(SyntaxKind::On), - TokenProperty::from(SyntaxKind::Using), - TokenProperty::from("title_idx".to_string()), - TokenProperty::from("btree".to_string()), - ], - ) - } - - #[test] - fn test_create_procedure() { - test_get_node_properties( - "create procedure insert_data(a integer) - language sql - as $$insert into tbl values (a);$$;", - SyntaxKind::CreateFunctionStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Procedure), - TokenProperty::from("insert_data".to_string()), - ], - ) - } - - #[test] - fn test_create_tablespace() { - test_get_node_properties( - "create tablespace x owner a location 'b' with (seq_page_cost=3);", - SyntaxKind::CreateTableSpaceStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Tablespace), - TokenProperty::from(SyntaxKind::Location), - TokenProperty::from(SyntaxKind::Owner), - TokenProperty::from(SyntaxKind::With), - TokenProperty::from("x".to_string()), - TokenProperty::from("b".to_string()), - ], - ) - } - - #[test] - fn test_create_type() { - test_get_node_properties( - "create type type1", - SyntaxKind::DefineStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::TypeP), - TokenProperty::from("type1".to_string()), - ], - ) - } - - #[test] - fn test_create_composite_type() { - test_get_node_properties( - "create type type1 as (attr1 int4, attr2 bool);", - SyntaxKind::CompositeTypeStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::TypeP), - TokenProperty::from(SyntaxKind::As), - ], - ) - } - - #[test] - fn test_create_database() { - test_get_node_properties( - "create database x owner abc connection limit 5;", - SyntaxKind::CreatedbStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Database), - TokenProperty::from("x".to_string()), - ], - ) - } - - #[test] - fn test_create_extension() { - test_get_node_properties( - r#"create extension if not exists x cascade version "1.2" schema a;"#, - SyntaxKind::CreateExtensionStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Extension), - TokenProperty::from(SyntaxKind::IfP), - TokenProperty::from(SyntaxKind::Not), - TokenProperty::from(SyntaxKind::Exists), - TokenProperty::from("x".to_string()), - ], - ) - } - - #[test] - fn test_create_conversion() { - test_get_node_properties( - "CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;", - SyntaxKind::CreateConversionStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Default), - TokenProperty::from(SyntaxKind::ConversionP), - TokenProperty::from(SyntaxKind::For), - TokenProperty::from(SyntaxKind::To), - TokenProperty::from(SyntaxKind::From), - TokenProperty::from("utf8".to_string()), - TokenProperty::from("latin1".to_string()), - TokenProperty::from("myconv".to_string()), - TokenProperty::from("myfunc".to_string()), - ], - ) - } - - #[test] - fn test_create_transform() { - test_get_node_properties( - "CREATE OR REPLACE TRANSFORM FOR hstore LANGUAGE plpython3u ( - FROM SQL WITH FUNCTION hstore_to_plpython(internal), - TO SQL WITH FUNCTION plpython_to_hstore(internal) - );", - SyntaxKind::CreateTransformStmt, - vec![ - TokenProperty::from(SyntaxKind::Create), - TokenProperty::from(SyntaxKind::Or), - TokenProperty::from(SyntaxKind::Replace), - TokenProperty::from(SyntaxKind::Transform), - TokenProperty::from(SyntaxKind::For), - TokenProperty::from(SyntaxKind::Language), - TokenProperty::from(SyntaxKind::From), - TokenProperty::from(SyntaxKind::SqlP), - TokenProperty::from(SyntaxKind::With), - TokenProperty::from(SyntaxKind::Function), - TokenProperty::from(SyntaxKind::To), - TokenProperty::from(SyntaxKind::SqlP), - TokenProperty::from(SyntaxKind::With), - TokenProperty::from(SyntaxKind::Function), - TokenProperty::from("plpython3u".to_string()), - ], - ) - } - - #[test] - fn test_truncate() { - test_get_node_properties( - "TRUNCATE TABLE users CONTINUE IDENTITY RESTRICT", - SyntaxKind::TruncateStmt, - vec![ - TokenProperty::from(SyntaxKind::Truncate), - TokenProperty::from(SyntaxKind::Table), - TokenProperty::from(SyntaxKind::ContinueP), - TokenProperty::from(SyntaxKind::IdentityP), - TokenProperty::from(SyntaxKind::Restrict), - ], - ) - } -} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs deleted file mode 100644 index 846c84fc..00000000 --- a/crates/parser/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! The Postgres parser. -//! -//! This crate provides a parser for the Postgres SQL dialect. -//! It is based in the pg_query.rs crate, which is a wrapper around the PostgreSQL query parser. -//! The main `Parser` struct parses a source file and individual statements. -//! The `Parse` result struct contains the resulting concrete syntax tree, syntax errors, and the abtract syntax tree, which is a list of pg_query statements and their positions. -//! -//! The idea is to offload the heavy lifting to the same parser that the PostgreSQL server uses, -//! and just fill in the gaps to be able to build both cst and ast from a source file that -//! potentially contains erroneous statements. -//! -//! The main drawbacks of the PostgreSQL query parser mitigated by this parser are: -//! - it only parsed a full source text, and if there is any syntax error in a file, it will not parse anything and return an error. -//! - it does not parse whitespaces and newlines, and it only returns ast nodes. The concrete syntax tree has to be reverse-engineered. -//! -//! To see how these drawbacks are mitigated, see the `statement_parser.rs` and the `source_parser.rs` module. - -#![feature(lazy_cell, is_sorted)] - -mod ast_node; -mod codegen; -mod lexer; -mod parse; -mod parser; -mod sibling_token; -mod syntax_error; -mod syntax_node; - -use lexer::lex; -use parse::source::source; - -pub use crate::codegen::SyntaxKind; -pub use crate::parser::{Parse, Parser}; -pub use crate::syntax_node::{SyntaxElement, SyntaxNode, SyntaxToken}; - -// TODO: I think we should add some kind of `EntryPoint` enum and make the api more flexible -// maybe have an intermediate struct that takes &str inputs, lexes the input and then calls the parser -pub fn parse_source(text: &str) -> Parse { - let mut p = Parser::new(lex(text)); - source(&mut p); - p.finish() -} diff --git a/crates/parser/src/parse/mod.rs b/crates/parser/src/parse/mod.rs deleted file mode 100644 index c664fd83..00000000 --- a/crates/parser/src/parse/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod libpg_query_node; -pub mod source; -pub mod statement; -pub mod statement_start; diff --git a/crates/parser/src/parse/source.rs b/crates/parser/src/parse/source.rs deleted file mode 100644 index 2743433e..00000000 --- a/crates/parser/src/parse/source.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::codegen::SyntaxKind; -use crate::Parser; - -use super::statement::statement; -use super::statement_start::is_at_stmt_start; - -pub fn source(parser: &mut Parser) { - parser.start_node(SyntaxKind::SourceFile); - - while !parser.eof() { - match is_at_stmt_start(parser) { - Some(stmt) => { - statement(parser, stmt); - } - None => { - parser.advance(); - } - } - } - - parser.finish_node(); -} diff --git a/crates/parser/src/parse/statement.rs b/crates/parser/src/parse/statement.rs deleted file mode 100644 index e1a7c5ff..00000000 --- a/crates/parser/src/parse/statement.rs +++ /dev/null @@ -1,151 +0,0 @@ -use std::ops::Range; - -use cstree::text::{TextRange, TextSize}; - -use super::statement_start::{is_at_stmt_start, TokenStatement, STATEMENT_START_TOKEN_MAPS}; -use crate::codegen::SyntaxKind; -use crate::parse::libpg_query_node::libpg_query_node; -use crate::Parser; - -pub fn statement(parser: &mut Parser, kind: SyntaxKind) { - let token_range = collect_statement_token_range(parser, kind); - let tokens = parser.tokens.get(token_range.clone()).unwrap().to_vec(); - match pg_query::parse( - tokens - .iter() - .map(|t| t.text.clone()) - .collect::() - .as_str(), - ) { - Ok(result) => { - let root = result - .protobuf - .nodes() - .iter() - .find(|n| n.1 == 1) - .unwrap() - .0 - .to_enum(); - - // FIXME: if have no idea why the subtraction is needed - let start = if parser.tokens[token_range.start].span.start() == TextSize::from(0) { - TextSize::from(0) - } else { - parser.tokens[token_range.start].span.start() - TextSize::from(1) - }; - let end = if token_range.end == parser.tokens.len() { - parser.tokens[token_range.end - 1].span.end() - TextSize::from(1) - } else { - parser.tokens[token_range.end - 1].span.end() - }; - let text_range = TextRange::new( - TextSize::from(u32::try_from(start).unwrap()), - TextSize::from(u32::try_from(end).unwrap()), - ); - - parser.stmt(root.clone(), text_range); - libpg_query_node(parser, root, &token_range); - } - Err(err) => { - parser.error( - err.to_string(), - TextRange::new( - TextSize::from(u32::try_from(token_range.start).unwrap()), - TextSize::from(u32::try_from(token_range.end).unwrap()), - ), - ); - while parser.pos < token_range.end { - parser.advance(); - } - } - }; - - assert_eq!(parser.pos, token_range.end); -} - -fn collect_statement_token_range(parser: &mut Parser, kind: SyntaxKind) -> Range { - parser.open_buffer(); - - // advance with all start tokens of statement - advance_over_start_tokens(parser, kind); - - let mut is_sub_stmt = 0; - let mut is_sub_trx = 0; - let mut ignore_next_non_whitespace = false; - while !parser.at(SyntaxKind::Ascii59) && !parser.eof() { - match parser.nth(0, false).kind { - SyntaxKind::All => { - // ALL is never a statement start, but needs to be skipped when combining queries - // (e.g. UNION ALL) - parser.advance(); - } - SyntaxKind::BeginP => { - // BEGIN, consume until END - is_sub_trx += 1; - parser.advance(); - } - SyntaxKind::EndP => { - is_sub_trx -= 1; - parser.advance(); - } - // opening brackets "(", consume until closing bracket ")" - SyntaxKind::Ascii40 => { - is_sub_stmt += 1; - parser.advance(); - } - SyntaxKind::Ascii41 => { - is_sub_stmt -= 1; - parser.advance(); - } - SyntaxKind::As | SyntaxKind::Union | SyntaxKind::Intersect | SyntaxKind::Except => { - // ignore the next non-whitespace token - ignore_next_non_whitespace = true; - parser.advance(); - } - _ => { - // if another stmt FIRST is encountered, break - // ignore if parsing sub stmt - if ignore_next_non_whitespace == false - && is_sub_stmt == 0 - && is_sub_trx == 0 - && is_at_stmt_start(parser).is_some() - { - break; - } else { - if ignore_next_non_whitespace == true && !parser.at_whitespace() { - ignore_next_non_whitespace = false; - } - parser.advance(); - } - } - } - } - - parser.expect(SyntaxKind::Ascii59); - - // close buffer, get tokens and reset pos - parser.close_buffer() -} - -/// advance with all start tokens of statement -fn advance_over_start_tokens(parser: &mut Parser, kind: SyntaxKind) { - for i in 0..STATEMENT_START_TOKEN_MAPS.len() { - parser.eat_whitespace(); - let token = parser.nth(0, false); - if let Some(result) = STATEMENT_START_TOKEN_MAPS[i].get(&token.kind) { - let is_in_results = result - .iter() - .find(|x| match x { - TokenStatement::EoS(y) | TokenStatement::Any(y) => y == &kind, - }) - .is_some(); - if i == 0 && !is_in_results { - panic!("Expected statement start"); - } else if is_in_results { - parser.expect(token.kind); - } else { - break; - } - } - } -} diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs deleted file mode 100644 index 611ba827..00000000 --- a/crates/parser/src/parser.rs +++ /dev/null @@ -1,412 +0,0 @@ -use cstree::build::Checkpoint; -use cstree::syntax::ResolvedNode; -use cstree::text::TextSize; -use cstree::{build::GreenNodeBuilder, text::TextRange}; -use log::debug; -use pg_query::NodeEnum; -use std::cmp::min; -use std::ops::Range; - -use crate::ast_node::RawStmt; -use crate::codegen::SyntaxKind; -use crate::lexer::{Token, TokenType}; -use crate::syntax_error::SyntaxError; -use crate::syntax_node::SyntaxNode; - -pub static WHITESPACE_TOKENS: &[SyntaxKind] = &[ - SyntaxKind::Whitespace, - SyntaxKind::Tab, - SyntaxKind::Newline, - SyntaxKind::SqlComment, -]; - -/// Main parser that exposes the `cstree` api, and collects errors and statements -#[derive(Debug)] -pub struct Parser { - /// The cst builder - inner: GreenNodeBuilder<'static, 'static, SyntaxKind>, - /// The syntax errors accumulated during parsing - errors: Vec, - /// The pg_query statements representing the abstract syntax tree - stmts: Vec, - /// The tokens to parse - pub tokens: Vec, - /// The current position in the token stream - pub pos: usize, - /// index from which whitespace tokens are buffered - pub whitespace_token_buffer: Option, - /// index from which tokens are buffered - token_buffer: Option, - - pub depth: usize, - - eof_token: Token, -} - -/// Result of Building -#[derive(Debug)] -pub struct Parse { - /// The concrete syntax tree - pub cst: ResolvedNode, - /// The syntax errors accumulated during parsing - pub errors: Vec, - /// The pg_query statements representing the abtract syntax tree - pub stmts: Vec, -} - -impl Parser { - pub fn new(tokens: Vec) -> Self { - Self { - eof_token: Token::eof(usize::from(tokens.last().unwrap().span.end())), - inner: GreenNodeBuilder::new(), - errors: Vec::new(), - stmts: Vec::new(), - tokens, - pos: 0, - whitespace_token_buffer: None, - token_buffer: None, - depth: 0, - } - } - - /// start a new node of `SyntaxKind` - pub fn start_node(&mut self, kind: SyntaxKind) { - debug!("start_node: {:?}", kind); - self.flush_token_buffer(); - self.inner.start_node(kind); - self.depth += 1; - } - /// finish current node - pub fn finish_node(&mut self) { - debug!("finish_node"); - self.inner.finish_node(); - self.depth -= 1; - } - - /// collects an SyntaxError with an `error` message at `range` - pub fn error(&mut self, error: String, range: TextRange) { - self.errors.push(SyntaxError::new(error, range)); - } - - /// collects an SyntaxError with an `error` message at `offset` - pub fn error_at_offset(&mut self, error: String, offset: TextSize) { - self.errors.push(SyntaxError::new_at_offset(error, offset)); - } - - /// collects an SyntaxError with an `error` message at `pos` - pub fn error_at_pos(&mut self, error: String, pos: usize) { - self.errors.push(SyntaxError::new_at_offset( - error, - self.tokens - .get(min(self.tokens.len() - 1, pos)) - .unwrap() - .span - .start(), - )); - } - - /// collects a pg_query `stmt` at `range` - pub fn stmt(&mut self, stmt: NodeEnum, range: TextRange) { - self.stmts.push(RawStmt { stmt, range }); - } - - /// finish cstree and return `Parse` - pub fn finish(self) -> Parse { - let (tree, cache) = self.inner.finish(); - Parse { - cst: SyntaxNode::new_root_with_resolver(tree, cache.unwrap().into_interner().unwrap()), - stmts: self.stmts, - errors: self.errors, - } - } - - /// Prepare for maybe wrapping the next node with a surrounding node. - /// - /// The way wrapping works is that you first get a checkpoint, then you add nodes and tokens as - /// normal, and then you *maybe* call [`start_node_at`](Parser::start_node_at). - pub fn checkpoint(self) -> Checkpoint { - self.inner.checkpoint() - } - - /// Wrap the previous branch marked by [`checkpoint`](Parser::checkpoint) in a new - /// branch and make it current. - pub fn start_node_at(&mut self, checkpoint: Checkpoint, kind: SyntaxKind) { - self.flush_token_buffer(); - self.inner.start_node_at(checkpoint, kind); - } - - /// Opens a buffer for tokens. While the buffer is active, tokens are not applied to the tree. - pub fn open_buffer(&mut self) { - self.token_buffer = Some(self.pos); - } - - /// Closes the current token buffer, resets the position to the start of the buffer and returns the range of buffered tokens. - pub fn close_buffer(&mut self) -> Range { - let token_buffer = self.token_buffer.unwrap(); - let token_range = token_buffer..self.whitespace_token_buffer.unwrap_or(self.pos); - self.token_buffer = None; - self.pos = token_buffer; - token_range - } - - /// applies token and advances - pub fn advance(&mut self) { - assert!(!self.eof()); - if self.nth(0, false).kind == SyntaxKind::Whitespace { - if self.whitespace_token_buffer.is_none() { - self.whitespace_token_buffer = Some(self.pos); - } - } else { - self.flush_token_buffer(); - if self.token_buffer.is_none() { - let token = self.tokens.get(self.pos).unwrap(); - self.inner.token(token.kind, &token.text); - } - } - self.pos += 1; - } - - /// flush token buffer and applies all tokens - pub fn flush_token_buffer(&mut self) { - if self.whitespace_token_buffer.is_none() { - return; - } - while self.whitespace_token_buffer.unwrap() < self.pos { - let token = self - .tokens - .get(self.whitespace_token_buffer.unwrap()) - .unwrap(); - if self.token_buffer.is_none() { - self.inner.token(token.kind, &token.text); - } - self.whitespace_token_buffer = Some(self.whitespace_token_buffer.unwrap() + 1); - } - self.whitespace_token_buffer = None; - } - - pub fn eat(&mut self, kind: SyntaxKind) -> bool { - if self.at(kind) { - self.advance(); - true - } else { - false - } - } - - pub fn at_whitespace(&self) -> bool { - self.nth(0, false).kind == SyntaxKind::Whitespace - } - - pub fn eat_whitespace(&mut self) { - while self.nth(0, false).token_type == TokenType::Whitespace { - self.advance(); - } - } - - pub fn eof(&self) -> bool { - self.pos == self.tokens.len() - } - - /// lookahead method. - /// - /// if `ignore_whitespace` is true, it will skip all whitespace tokens - pub fn nth(&self, lookahead: usize, ignore_whitespace: bool) -> &Token { - if ignore_whitespace { - let mut idx = 0; - let mut non_whitespace_token_ctr = 0; - loop { - match self.tokens.get(self.pos + idx) { - Some(token) => { - if !WHITESPACE_TOKENS.contains(&token.kind) { - if non_whitespace_token_ctr == lookahead { - return token; - } - non_whitespace_token_ctr += 1; - } - idx += 1; - } - None => { - return &self.eof_token; - } - } - } - } else { - match self.tokens.get(self.pos + lookahead) { - Some(token) => token, - None => &self.eof_token, - } - } - } - - /// checks if the current token is any of `kinds` - pub fn at_any(&self, kinds: &[SyntaxKind]) -> bool { - kinds.iter().any(|&it| self.at(it)) - } - - /// checks if the current token is of `kind` - pub fn at(&self, kind: SyntaxKind) -> bool { - self.nth(0, false).kind == kind - } - - /// like at, but for multiple consecutive tokens - pub fn at_all(&self, kinds: &[SyntaxKind]) -> bool { - kinds - .iter() - .enumerate() - .all(|(idx, &it)| self.nth(idx, false).kind == it) - } - - /// like at_any, but for multiple consecutive tokens - pub fn at_any_all(&self, kinds: &Vec<&[SyntaxKind]>) -> bool { - kinds.iter().any(|&it| self.at_all(it)) - } - - pub fn expect(&mut self, kind: SyntaxKind) { - if self.eat(kind) { - return; - } - if self.whitespace_token_buffer.is_some() { - self.error_at_pos( - format!( - "Expected {:#?}, found {:#?}", - kind, - self.tokens[self.whitespace_token_buffer.unwrap()].kind - ), - self.whitespace_token_buffer.unwrap(), - ); - } else { - self.error_at_pos( - format!("Expected {:#?}, found {:#?}", kind, self.nth(0, false)), - self.pos + 1, - ); - } - } -} - -#[cfg(test)] -mod tests { - use std::{sync::mpsc, thread, time::Duration}; - - use crate::{lexer::lex, parse::source::source}; - - use super::*; - - fn init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - #[test] - fn test_parser_another() { - init(); - - let input = "SELECT 1 from contact c - JOIN pg_class c ON nc.oid = c.relnamespace - left join ( - select - table_id, - jsonb_agg(_pk.*) as primary_keys - from ( - select 1 - from - pg_class c, - pg_attribute a - where - i.indrelid = c.oid - and c.relnamespace = n.oid - ) as _pk - group by table_id - ) as pk - on pk.table_id = c.oid;"; - - let mut p = Parser::new(lex(input)); - source(&mut p); - let result = p.finish(); - - dbg!(&result.cst); - println!("{:#?}", result.errors); - } - - #[test] - fn test_parser_very_simple() { - init(); - - panic_after(Duration::from_millis(100), || { - let input = "select * from public.contact where x = 1;"; - - let mut p = Parser::new(lex(input)); - source(&mut p); - let result = p.finish(); - - dbg!(&result.cst); - println!("{:#?}", result.errors); - }) - } - - #[test] - fn test_nested_substatements() { - init(); - - let input = "select is ((select true), true);\nselect isnt ((select false), true);"; - - let mut p = Parser::new(lex(input)); - source(&mut p); - let result = p.finish(); - - dbg!(&result.cst); - assert_eq!(result.stmts.len(), 2); - println!("{:#?}", result.errors); - } - - #[test] - fn test_nested_trx() { - init(); - - let input = "CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;"; - - let mut p = Parser::new(lex(input)); - source(&mut p); - let result = p.finish(); - - dbg!(&result.cst); - assert_eq!(result.stmts.len(), 2); - println!("{:#?}", result.errors); - } - - #[test] - fn test_parser_simple() { - init(); - - let input = "alter table x rename to y \n\n alter table x alter column z set default 1"; - - let mut p = Parser::new(lex(input)); - source(&mut p); - let result = p.finish(); - - dbg!(&result.cst); - assert_eq!(result.stmts.len(), 2); - result.stmts.iter().for_each(|x| { - dbg!(&x.range); - dbg!(&x.stmt); - }); - println!("{:#?}", result.errors); - } - - fn panic_after(d: Duration, f: F) -> T - where - T: Send + 'static, - F: FnOnce() -> T, - F: Send + 'static, - { - let (done_tx, done_rx) = mpsc::channel(); - let handle = thread::spawn(move || { - let val = f(); - done_tx.send(()).expect("Unable to send completion signal"); - val - }); - - match done_rx.recv_timeout(d) { - Ok(_) => handle.join().expect("Thread panicked"), - Err(_) => panic!("Thread took too long"), - } - } -} diff --git a/crates/parser/src/sibling_token.rs b/crates/parser/src/sibling_token.rs deleted file mode 100644 index 9a5ec09a..00000000 --- a/crates/parser/src/sibling_token.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::codegen::SyntaxKind; - -const SIBLINGS: [(SyntaxKind, SyntaxKind); 2] = [ - (SyntaxKind::Ascii40, SyntaxKind::Ascii41), - (SyntaxKind::Ascii91, SyntaxKind::Ascii93), -]; - -impl SyntaxKind { - pub fn is_closing_sibling(&self) -> bool { - SIBLINGS.iter().any(|(_, close)| close == self) - } - - pub fn is_opening_sibling(&self) -> bool { - SIBLINGS.iter().any(|(open, _)| open == self) - } - - pub fn get_closing_sibling(&self) -> SyntaxKind { - SIBLINGS - .iter() - .find_map(|(open, close)| if open == self { Some(*close) } else { None }) - .unwrap() - } - - pub fn get_opening_sibling(&self) -> SyntaxKind { - SIBLINGS - .iter() - .find_map(|(open, close)| if close == self { Some(*open) } else { None }) - .unwrap() - } -} - -#[cfg(test)] -mod tests { - use std::assert_eq; - - use super::*; - - #[test] - fn test_siblings() { - assert_eq!(SyntaxKind::Ascii40.is_opening_sibling(), true); - assert_eq!( - SyntaxKind::Ascii40.get_closing_sibling(), - SyntaxKind::Ascii41 - ); - } - - #[test] - #[should_panic] - fn test_mismatched_siblings() { - SyntaxKind::Ascii41.get_closing_sibling(); - } -} diff --git a/crates/parser/src/syntax_node.rs b/crates/parser/src/syntax_node.rs deleted file mode 100644 index abf84ed4..00000000 --- a/crates/parser/src/syntax_node.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! This module defines Concrete Syntax Tree (CST), used by postgres_lsp. -//! -//! The CST includes comments and whitespace, provides a single node type, -//! `SyntaxNode`, and a basic traversal API (parent, children, siblings). -//! -//! The *real* implementation is in the (language-agnostic) `cstree` crate, this -//! module just wraps its API. - -use crate::codegen::SyntaxKind; - -pub type SyntaxNode = cstree::syntax::SyntaxNode; -pub type SyntaxToken = cstree::syntax::SyntaxToken; -pub type SyntaxElement = cstree::syntax::SyntaxElement; diff --git a/crates/parser/tests/common/mod.rs b/crates/parser/tests/common/mod.rs deleted file mode 100644 index af191dab..00000000 --- a/crates/parser/tests/common/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn setup() { - let _ = env_logger::builder().is_test(true).try_init(); -} diff --git a/crates/parser/tests/data/source_file/valid/0001.sql b/crates/parser/tests/data/source_file/valid/0001.sql deleted file mode 100644 index 82cc0bf0..00000000 --- a/crates/parser/tests/data/source_file/valid/0001.sql +++ /dev/null @@ -1,11 +0,0 @@ -BEGIN; -UPDATE accounts SET balance = balance - 100.00 - WHERE name = 'Alice'; -SAVEPOINT my_savepoint; -UPDATE accounts SET balance = balance + 100.00 - WHERE name = 'Bob'; --- oops ... forget that and use Wally's account -ROLLBACK TO my_savepoint; -UPDATE accounts SET balance = balance + 100.00 - WHERE name = 'Wally'; -COMMIT; diff --git a/crates/parser/tests/snapshots/statements/valid/0001@1.snap b/crates/parser/tests/snapshots/statements/valid/0001@1.snap deleted file mode 100644 index dea5ba4c..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0001@1.snap +++ /dev/null @@ -1,330 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT city, count(*) FILTER (WHERE temp_lo < 45), max(temp_lo)\n FROM weather\n GROUP BY city;" ---- -Parse { - cst: SourceFile@0..99 - SelectStmt@0..99 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..11 - ColumnRef@7..11 - Ident@7..11 "city" - Ascii44@11..12 "," - Whitespace@12..13 " " - ResTarget@13..48 - FuncCall@13..48 - Ident@13..18 "count" - Ascii40@18..19 "(" - Ascii42@19..20 "*" - Ascii41@20..21 ")" - Whitespace@21..22 " " - Filter@22..28 "FILTER" - Whitespace@28..29 " " - Ascii40@29..30 "(" - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..48 - ColumnRef@36..43 - Ident@36..43 "temp_lo" - Whitespace@43..44 " " - Ascii60@44..45 "<" - Whitespace@45..46 " " - AConst@46..48 - Iconst@46..48 "45" - Ascii41@48..49 ")" - Ascii44@49..50 "," - Whitespace@50..51 " " - ResTarget@51..62 - FuncCall@51..62 - Ident@51..54 "max" - Ascii40@54..55 "(" - ColumnRef@55..62 - Ident@55..62 "temp_lo" - Ascii41@62..63 ")" - Newline@63..64 "\n" - Whitespace@64..68 " " - From@68..72 "FROM" - Whitespace@72..73 " " - RangeVar@73..80 - Ident@73..80 "weather" - Newline@80..81 "\n" - Whitespace@81..85 " " - GroupP@85..90 "GROUP" - Whitespace@90..91 " " - By@91..93 "BY" - Whitespace@93..94 " " - ColumnRef@94..98 - Ident@94..98 "city" - Ascii59@98..99 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "<", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 46, - val: Some( - Ival( - Integer { - ival: 45, - }, - ), - ), - }, - ), - ), - }, - ), - location: 44, - }, - ), - ), - }, - ), - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 13, - }, - ), - ), - }, - ), - location: 13, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "max", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 55, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 51, - }, - ), - ), - }, - ), - location: 51, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 73, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 94, - }, - ), - ), - }, - ], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..98, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0002@1.snap b/crates/parser/tests/snapshots/statements/valid/0002@1.snap deleted file mode 100644 index c28cc912..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0002@1.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "COPY weather FROM '/home/user/weather.txt';" ---- -Parse { - cst: SourceFile@0..43 - CopyStmt@0..43 - Copy@0..4 "COPY" - Whitespace@4..5 " " - RangeVar@5..12 - Ident@5..12 "weather" - Whitespace@12..13 " " - From@13..17 "FROM" - Whitespace@17..18 " " - Sconst@18..42 "'/home/user/weather.txt'" - Ascii59@42..43 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CopyStmt( - CopyStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 5, - }, - ), - query: None, - attlist: [], - is_from: true, - is_program: false, - filename: "/home/user/weather.txt", - options: [], - where_clause: None, - }, - ), - range: 0..42, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0003@1.snap b/crates/parser/tests/snapshots/statements/valid/0003@1.snap deleted file mode 100644 index 069c3c9d..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0003@1.snap +++ /dev/null @@ -1,453 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE weather (\n city varchar(80) references cities(name),\n temp_lo int,\n temp_hi int,\n prcp real,\n date date\n);" ---- -Parse { - cst: SourceFile@0..173 - CreateStmt@0..173 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..20 - Ident@13..20 "weather" - Whitespace@20..21 " " - Ascii40@21..22 "(" - Newline@22..23 "\n" - Whitespace@23..31 " " - ColumnDef@31..75 - Ident@31..35 "city" - Whitespace@35..41 " " - TypeName@41..51 - Varchar@41..48 "varchar" - Ascii40@48..49 "(" - AConst@49..51 - Iconst@49..51 "80" - Ascii41@51..52 ")" - Whitespace@52..53 " " - Constraint@53..75 - References@53..63 "references" - Whitespace@63..64 " " - RangeVar@64..70 - Ident@64..70 "cities" - Ascii40@70..71 "(" - NameP@71..75 "name" - Ascii41@75..76 ")" - Ascii44@76..77 "," - Newline@77..78 "\n" - Whitespace@78..86 " " - ColumnDef@86..99 - Ident@86..93 "temp_lo" - Whitespace@93..96 " " - TypeName@96..99 - IntP@96..99 "int" - Ascii44@99..100 "," - Newline@100..101 "\n" - Whitespace@101..109 " " - ColumnDef@109..122 - Ident@109..116 "temp_hi" - Whitespace@116..119 " " - TypeName@119..122 - IntP@119..122 "int" - Ascii44@122..123 "," - Newline@123..124 "\n" - Whitespace@124..132 " " - ColumnDef@132..146 - Ident@132..136 "prcp" - Whitespace@136..142 " " - TypeName@142..146 - Real@142..146 "real" - Ascii44@146..147 "," - Newline@147..148 "\n" - Whitespace@148..156 " " - ColumnDef@156..170 - Ident@156..160 "date" - Whitespace@160..166 " " - TypeName@166..170 - Ident@166..170 "date" - Newline@170..171 "\n" - Ascii41@171..172 ")" - Ascii59@172..173 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "city", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "varchar", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 49, - val: Some( - Ival( - Integer { - ival: 80, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 41, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrForeign, - conname: "", - deferrable: false, - initdeferred: false, - location: 53, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "p", - alias: None, - location: 64, - }, - ), - fk_attrs: [], - pk_attrs: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - fk_matchtype: "s", - fk_upd_action: "a", - fk_del_action: "a", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "temp_lo", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 96, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 86, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "temp_hi", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 119, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 109, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "prcp", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "float4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 142, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 132, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "date", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "date", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 166, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 156, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..172, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0004@1.snap b/crates/parser/tests/snapshots/statements/valid/0004@1.snap deleted file mode 100644 index 367d0727..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0004@1.snap +++ /dev/null @@ -1,253 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE VIEW myview AS\n SELECT name, location\n FROM weather, cities\n WHERE city = name;" ---- -Parse { - cst: SourceFile@0..99 - Create@0..6 "CREATE" - Whitespace@6..7 " " - View@7..11 "VIEW" - Whitespace@11..12 " " - Ident@12..18 "myview" - Whitespace@18..19 " " - As@19..21 "AS" - Newline@21..22 "\n" - SelectStmt@22..99 - Select@22..28 "SELECT" - Whitespace@28..29 " " - ResTarget@29..33 - ColumnRef@29..33 - NameP@29..33 "name" - Ascii44@33..34 "," - Whitespace@34..35 " " - ResTarget@35..43 - ColumnRef@35..43 - Location@35..43 "location" - Newline@43..44 "\n" - Whitespace@44..52 " " - From@52..56 "FROM" - Whitespace@56..57 " " - RangeVar@57..64 - Ident@57..64 "weather" - Ascii44@64..65 "," - Whitespace@65..66 " " - RangeVar@66..72 - Ident@66..72 "cities" - Newline@72..73 "\n" - Whitespace@73..81 " " - Where@81..86 "WHERE" - Whitespace@86..87 " " - AExpr@87..98 - ColumnRef@87..91 - Ident@87..91 "city" - Whitespace@91..92 " " - Ascii61@92..93 "=" - Whitespace@93..94 " " - ColumnRef@94..98 - NameP@94..98 "name" - Ascii59@98..99 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 22..22, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..8, - ), - ], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "location", - }, - ), - ), - }, - ], - location: 13, - }, - ), - ), - }, - ), - location: 13, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 35, - }, - ), - ), - }, - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "p", - alias: None, - location: 44, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 65, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - location: 72, - }, - ), - ), - }, - ), - location: 70, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 25..102, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0005@1.snap b/crates/parser/tests/snapshots/statements/valid/0005@1.snap deleted file mode 100644 index 0dbcffa6..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0005@1.snap +++ /dev/null @@ -1,115 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "DELETE FROM weather WHERE city = 'Hayward';" ---- -Parse { - cst: SourceFile@0..43 - DeleteStmt@0..43 - DeleteP@0..6 "DELETE" - Whitespace@6..7 " " - From@7..11 "FROM" - Whitespace@11..12 " " - RangeVar@12..19 - Ident@12..19 "weather" - Whitespace@19..20 " " - Where@20..25 "WHERE" - Whitespace@25..26 " " - AExpr@26..42 - ColumnRef@26..30 - Ident@26..30 "city" - Whitespace@30..31 " " - Ascii61@31..32 "=" - Whitespace@32..33 " " - AConst@33..42 - Sconst@33..42 "'Hayward'" - Ascii59@42..43 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DeleteStmt( - DeleteStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - using_clause: [], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 33, - val: Some( - Sval( - String { - sval: "Hayward", - }, - ), - ), - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - ), - returning_list: [], - with_clause: None, - }, - ), - range: 0..42, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0006@1.snap b/crates/parser/tests/snapshots/statements/valid/0006@1.snap deleted file mode 100644 index 9d2cd1d9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0006@1.snap +++ /dev/null @@ -1,16 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: DROP TABLE tablename; ---- -Parse { - cst: SourceFile@0..21 - Drop@0..4 "DROP" - Whitespace@4..5 " " - Table@5..10 "TABLE" - Whitespace@10..11 " " - Ident@11..20 "tablename" - Ascii59@20..21 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0007@1.snap b/crates/parser/tests/snapshots/statements/valid/0007@1.snap deleted file mode 100644 index 9e4f02c7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0007@1.snap +++ /dev/null @@ -1,237 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE cities (\n name text,\n population real,\n elevation int -- (in ft)\n);" ---- -Parse { - cst: SourceFile@0..94 - CreateStmt@0..94 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..19 - Ident@13..19 "cities" - Whitespace@19..20 " " - Ascii40@20..21 "(" - Newline@21..22 "\n" - Whitespace@22..24 " " - ColumnDef@24..39 - NameP@24..28 "name" - Whitespace@28..35 " " - TypeName@35..39 - TextP@35..39 "text" - Ascii44@39..40 "," - Newline@40..41 "\n" - Whitespace@41..43 " " - ColumnDef@43..58 - Ident@43..53 "population" - Whitespace@53..54 " " - TypeName@54..58 - Real@54..58 "real" - Ascii44@58..59 "," - Newline@59..60 "\n" - Whitespace@60..62 " " - ColumnDef@62..76 - Ident@62..71 "elevation" - Whitespace@71..73 " " - TypeName@73..76 - IntP@73..76 "int" - Whitespace@76..81 " " - SqlComment@81..91 "-- (in ft)" - Newline@91..92 "\n" - Ascii41@92..93 ")" - Ascii59@93..94 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 35, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 24, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "population", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "float4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 54, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "elevation", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 73, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 62, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..93, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0008@1.snap b/crates/parser/tests/snapshots/statements/valid/0008@1.snap deleted file mode 100644 index 467edb3b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0008@1.snap +++ /dev/null @@ -1,239 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO weather (date, city, temp_hi, temp_lo)\n VALUES ('1994-11-29', 'Hayward', 54, 37);" ---- -Parse { - cst: SourceFile@0..96 - InsertStmt@0..96 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..19 - Ident@12..19 "weather" - Whitespace@19..20 " " - Ascii40@20..21 "(" - ResTarget@21..25 - Ident@21..25 "date" - Ascii44@25..26 "," - Whitespace@26..27 " " - ResTarget@27..31 - Ident@27..31 "city" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..40 - Ident@33..40 "temp_hi" - Ascii44@40..41 "," - Whitespace@41..42 " " - ResTarget@42..49 - Ident@42..49 "temp_lo" - Ascii41@49..50 ")" - Newline@50..51 "\n" - Whitespace@51..55 " " - SelectStmt@55..94 - Values@55..61 "VALUES" - Whitespace@61..62 " " - Ascii40@62..63 "(" - List@63..94 - AConst@63..75 - Sconst@63..75 "'1994-11-29'" - Ascii44@75..76 "," - Whitespace@76..77 " " - AConst@77..86 - Sconst@77..86 "'Hayward'" - Ascii44@86..87 "," - Whitespace@87..88 " " - AConst@88..90 - Iconst@88..90 "54" - Ascii44@90..91 "," - Whitespace@91..92 " " - AConst@92..94 - Iconst@92..94 "37" - Ascii41@94..95 ")" - Ascii59@95..96 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "date", - indirection: [], - val: None, - location: 21, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "city", - indirection: [], - val: None, - location: 27, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "temp_hi", - indirection: [], - val: None, - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "temp_lo", - indirection: [], - val: None, - location: 42, - }, - ), - ), - }, - ], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 63, - val: Some( - Sval( - String { - sval: "1994-11-29", - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 77, - val: Some( - Sval( - String { - sval: "Hayward", - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 88, - val: Some( - Ival( - Integer { - ival: 54, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 92, - val: Some( - Ival( - Integer { - ival: 37, - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..95, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0009@1.snap b/crates/parser/tests/snapshots/statements/valid/0009@1.snap deleted file mode 100644 index 656c4734..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0009@1.snap +++ /dev/null @@ -1,642 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,\n w2.city, w2.temp_lo AS low, w2.temp_hi AS high\n FROM weather w1 JOIN weather w2\n ON w1.temp_lo < w2.temp_lo AND w1.temp_hi > w2.temp_hi;" ---- -Parse { - cst: SourceFile@0..208 - SelectStmt@0..208 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - ColumnRef@7..14 - Ident@7..9 "w1" - Ascii46@9..10 "." - Ident@10..14 "city" - Ascii44@14..15 "," - Whitespace@15..16 " " - ResTarget@16..33 - ColumnRef@16..26 - Ident@16..18 "w1" - Ascii46@18..19 "." - Ident@19..26 "temp_lo" - Whitespace@26..27 " " - As@27..29 "AS" - Whitespace@29..30 " " - Ident@30..33 "low" - Ascii44@33..34 "," - Whitespace@34..35 " " - ResTarget@35..53 - ColumnRef@35..45 - Ident@35..37 "w1" - Ascii46@37..38 "." - Ident@38..45 "temp_hi" - Whitespace@45..46 " " - As@46..48 "AS" - Whitespace@48..49 " " - Ident@49..53 "high" - Ascii44@53..54 "," - Newline@54..55 "\n" - Whitespace@55..62 " " - ResTarget@62..69 - ColumnRef@62..69 - Ident@62..64 "w2" - Ascii46@64..65 "." - Ident@65..69 "city" - Ascii44@69..70 "," - Whitespace@70..71 " " - ResTarget@71..88 - ColumnRef@71..81 - Ident@71..73 "w2" - Ascii46@73..74 "." - Ident@74..81 "temp_lo" - Whitespace@81..82 " " - As@82..84 "AS" - Whitespace@84..85 " " - Ident@85..88 "low" - Ascii44@88..89 "," - Whitespace@89..90 " " - ResTarget@90..108 - ColumnRef@90..100 - Ident@90..92 "w2" - Ascii46@92..93 "." - Ident@93..100 "temp_hi" - Whitespace@100..101 " " - As@101..103 "AS" - Whitespace@103..104 " " - Ident@104..108 "high" - Newline@108..109 "\n" - Whitespace@109..113 " " - From@113..117 "FROM" - Whitespace@117..118 " " - JoinExpr@118..207 - RangeVar@118..128 - Ident@118..125 "weather" - Whitespace@125..126 " " - Alias@126..128 - Ident@126..128 "w1" - Whitespace@128..129 " " - Join@129..133 "JOIN" - Whitespace@133..134 " " - RangeVar@134..144 - Ident@134..141 "weather" - Whitespace@141..142 " " - Alias@142..144 - Ident@142..144 "w2" - Newline@144..145 "\n" - Whitespace@145..153 " " - On@153..155 "ON" - Whitespace@155..156 " " - BoolExpr@156..207 - AExpr@156..179 - ColumnRef@156..166 - Ident@156..158 "w1" - Ascii46@158..159 "." - Ident@159..166 "temp_lo" - Whitespace@166..167 " " - Ascii60@167..168 "<" - Whitespace@168..169 " " - ColumnRef@169..179 - Ident@169..171 "w2" - Ascii46@171..172 "." - Ident@172..179 "temp_lo" - Whitespace@179..180 " " - And@180..183 "AND" - Whitespace@183..184 " " - AExpr@184..207 - ColumnRef@184..194 - Ident@184..186 "w1" - Ascii46@186..187 "." - Ident@187..194 "temp_hi" - Whitespace@194..195 " " - Ascii62@195..196 ">" - Whitespace@196..197 " " - ColumnRef@197..207 - Ident@197..199 "w2" - Ascii46@199..200 "." - Ident@200..207 "temp_hi" - Ascii59@207..208 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "low", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 16, - }, - ), - ), - }, - ), - location: 16, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "high", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_hi", - }, - ), - ), - }, - ], - location: 35, - }, - ), - ), - }, - ), - location: 35, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 62, - }, - ), - ), - }, - ), - location: 62, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "low", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 71, - }, - ), - ), - }, - ), - location: 71, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "high", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_hi", - }, - ), - ), - }, - ], - location: 90, - }, - ), - ), - }, - ), - location: 90, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - JoinExpr( - JoinExpr { - jointype: JoinInner, - is_natural: false, - larg: Some( - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: Some( - Alias { - aliasname: "w1", - colnames: [], - }, - ), - location: 118, - }, - ), - ), - }, - ), - rarg: Some( - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: Some( - Alias { - aliasname: "w2", - colnames: [], - }, - ), - location: 134, - }, - ), - ), - }, - ), - using_clause: [], - join_using_alias: None, - quals: Some( - Node { - node: Some( - BoolExpr( - BoolExpr { - xpr: None, - boolop: AndExpr, - args: [ - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "<", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 156, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_lo", - }, - ), - ), - }, - ], - location: 169, - }, - ), - ), - }, - ), - location: 167, - }, - ), - ), - }, - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_hi", - }, - ), - ), - }, - ], - location: 184, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "w2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "temp_hi", - }, - ), - ), - }, - ], - location: 197, - }, - ), - ), - }, - ), - location: 195, - }, - ), - ), - }, - ], - location: 180, - }, - ), - ), - }, - ), - alias: None, - rtindex: 0, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..207, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0010@1.snap b/crates/parser/tests/snapshots/statements/valid/0010@1.snap deleted file mode 100644 index 576ce70e..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0010@1.snap +++ /dev/null @@ -1,193 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');" ---- -Parse { - cst: SourceFile@0..73 - InsertStmt@0..73 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..19 - Ident@12..19 "weather" - Whitespace@19..20 " " - SelectStmt@20..71 - Values@20..26 "VALUES" - Whitespace@26..27 " " - Ascii40@27..28 "(" - List@28..71 - AConst@28..43 - Sconst@28..43 "'San Francisco'" - Ascii44@43..44 "," - Whitespace@44..45 " " - AConst@45..47 - Iconst@45..47 "46" - Ascii44@47..48 "," - Whitespace@48..49 " " - AConst@49..51 - Iconst@49..51 "50" - Ascii44@51..52 "," - Whitespace@52..53 " " - AConst@53..57 - Fconst@53..57 "0.25" - Ascii44@57..58 "," - Whitespace@58..59 " " - AConst@59..71 - Sconst@59..71 "'1994-11-27'" - Ascii41@71..72 ")" - Ascii59@72..73 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 28, - val: Some( - Sval( - String { - sval: "San Francisco", - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 45, - val: Some( - Ival( - Integer { - ival: 46, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 49, - val: Some( - Ival( - Integer { - ival: 50, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 53, - val: Some( - Fval( - Float { - fval: "0.25", - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 59, - val: Some( - Sval( - String { - sval: "1994-11-27", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..72, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0011@1.snap b/crates/parser/tests/snapshots/statements/valid/0011@1.snap deleted file mode 100644 index 1359b5c4..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0011@1.snap +++ /dev/null @@ -1,151 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT DISTINCT city\n FROM weather\n ORDER BY city;" ---- -Parse { - cst: SourceFile@0..56 - SelectStmt@0..56 - Select@0..6 "SELECT" - Whitespace@6..7 " " - Distinct@7..15 "DISTINCT" - Whitespace@15..16 " " - ResTarget@16..20 - ColumnRef@16..20 - Ident@16..20 "city" - Newline@20..21 "\n" - Whitespace@21..25 " " - From@25..29 "FROM" - Whitespace@29..30 " " - RangeVar@30..37 - Ident@30..37 "weather" - Newline@37..38 "\n" - Whitespace@38..42 " " - SortBy@42..55 - Order@42..47 "ORDER" - Whitespace@47..48 " " - By@48..50 "BY" - Whitespace@50..51 " " - ColumnRef@51..55 - Ident@51..55 "city" - Ascii59@55..56 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [ - Node { - node: None, - }, - ], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 16, - }, - ), - ), - }, - ), - location: 16, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "weather", - inh: true, - relpersistence: "p", - alias: None, - location: 30, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "city", - }, - ), - ), - }, - ], - location: 51, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..55, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0012@1.snap b/crates/parser/tests/snapshots/statements/valid/0012@1.snap deleted file mode 100644 index 8f5f6a76..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0012@1.snap +++ /dev/null @@ -1,179 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE measurement_y2008m01 PARTITION OF measurement\n FOR VALUES FROM ('2008-01-01') TO ('2008-02-01')\n WITH (parallel_workers = 4)\n TABLESPACE fasttablespace;" ---- -Parse { - cst: SourceFile@0..174 - CreateStmt@0..174 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..33 - Ident@13..33 "measurement_y2008m01" - Whitespace@33..34 " " - Partition@34..43 "PARTITION" - Whitespace@43..44 " " - Of@44..46 "OF" - Whitespace@46..47 " " - RangeVar@47..58 - Ident@47..58 "measurement" - Newline@58..59 "\n" - Whitespace@59..63 " " - For@63..66 "FOR" - Whitespace@66..67 " " - Values@67..73 "VALUES" - Whitespace@73..74 " " - PartitionBoundSpec@74..110 - From@74..78 "FROM" - Whitespace@78..79 " " - Ascii40@79..80 "(" - AConst@80..92 - Sconst@80..92 "'2008-01-01'" - Ascii41@92..93 ")" - Whitespace@93..94 " " - To@94..96 "TO" - Whitespace@96..97 " " - Ascii40@97..98 "(" - AConst@98..110 - Sconst@98..110 "'2008-02-01'" - Ascii41@110..111 ")" - Newline@111..112 "\n" - Whitespace@112..116 " " - With@116..120 "WITH" - Whitespace@120..121 " " - Ascii40@121..122 "(" - DefElem@122..142 - Ident@122..138 "parallel_workers" - Whitespace@138..139 " " - Ascii61@139..140 "=" - Whitespace@140..141 " " - Iconst@141..142 "4" - Ascii41@142..143 ")" - Newline@143..144 "\n" - Whitespace@144..148 " " - Tablespace@148..158 "TABLESPACE" - Whitespace@158..159 " " - Ident@159..173 "fasttablespace" - Ascii59@173..174 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "measurement_y2008m01", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [], - inh_relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "measurement", - inh: true, - relpersistence: "p", - alias: None, - location: 47, - }, - ), - ), - }, - ], - partbound: Some( - PartitionBoundSpec { - strategy: "r", - is_default: false, - modulus: 0, - remainder: 0, - listdatums: [], - lowerdatums: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 80, - val: Some( - Sval( - String { - sval: "2008-01-01", - }, - ), - ), - }, - ), - ), - }, - ], - upperdatums: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 98, - val: Some( - Sval( - String { - sval: "2008-02-01", - }, - ), - ), - }, - ), - ), - }, - ], - location: 74, - }, - ), - partspec: None, - of_typename: None, - constraints: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "parallel_workers", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 4, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 122, - }, - ), - ), - }, - ], - oncommit: OncommitNoop, - tablespacename: "fasttablespace", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..173, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0013@1.snap b/crates/parser/tests/snapshots/statements/valid/0013@1.snap deleted file mode 100644 index 70fedfab..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0013@1.snap +++ /dev/null @@ -1,59 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "UPDATE weather\n SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2\n WHERE date > '1994-11-28';" ---- -Parse { - cst: SourceFile@0..95 - Update@0..6 "UPDATE" - Whitespace@6..7 " " - Ident@7..14 "weather" - Newline@14..15 "\n" - Set@15..18 "SET" - Whitespace@18..19 " " - Ident@19..26 "temp_hi" - Whitespace@26..27 " " - Ascii61@27..28 "=" - Whitespace@28..29 " " - Ident@29..36 "temp_hi" - Whitespace@36..37 " " - Ascii45@37..38 "-" - Whitespace@38..39 " " - Iconst@39..40 "2" - Ascii44@40..41 "," - Whitespace@41..43 " " - Ident@43..50 "temp_lo" - Whitespace@50..51 " " - Ascii61@51..52 "=" - Whitespace@52..53 " " - Ident@53..60 "temp_lo" - Whitespace@60..61 " " - Ascii45@61..62 "-" - Whitespace@62..63 " " - Iconst@63..64 "2" - Newline@64..65 "\n" - Whitespace@65..69 " " - Where@69..74 "WHERE" - Whitespace@74..75 " " - Ident@75..79 "date" - Whitespace@79..80 " " - Ascii62@80..81 ">" - Whitespace@81..82 " " - Sconst@82..94 "'1994-11-28'" - Ascii59@94..95 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 15..15, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..4, - ), - SyntaxError( - "Invalid statement: syntax error at or near \"-\"", - 5..37, - ), - ], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0014@1.snap b/crates/parser/tests/snapshots/statements/valid/0014@1.snap deleted file mode 100644 index 799b8df8..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0014@1.snap +++ /dev/null @@ -1,339 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT sum(salary) OVER w, avg(salary) OVER w\n FROM empsalary\n WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);" ---- -Parse { - cst: SourceFile@0..121 - SelectStmt@0..121 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..25 - FuncCall@7..25 - Ident@7..10 "sum" - Ascii40@10..11 "(" - ColumnRef@11..17 - Ident@11..17 "salary" - Ascii41@17..18 ")" - Whitespace@18..19 " " - Over@19..23 "OVER" - Whitespace@23..24 " " - WindowDef@24..25 - Ident@24..25 "w" - Ascii44@25..26 "," - Whitespace@26..27 " " - ResTarget@27..45 - FuncCall@27..45 - Ident@27..30 "avg" - Ascii40@30..31 "(" - ColumnRef@31..37 - Ident@31..37 "salary" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Over@39..43 "OVER" - Whitespace@43..44 " " - WindowDef@44..45 - Ident@44..45 "w" - Newline@45..46 "\n" - Whitespace@46..48 " " - From@48..52 "FROM" - Whitespace@52..53 " " - RangeVar@53..62 - Ident@53..62 "empsalary" - Newline@62..63 "\n" - Whitespace@63..65 " " - WindowDef@65..119 - Window@65..71 "WINDOW" - Whitespace@71..72 " " - Ident@72..73 "w" - Whitespace@73..74 " " - As@74..76 "AS" - Whitespace@76..77 " " - Ascii40@77..78 "(" - Partition@78..87 "PARTITION" - Whitespace@87..88 " " - By@88..90 "BY" - Whitespace@90..91 " " - ColumnRef@91..98 - Ident@91..98 "depname" - Whitespace@98..99 " " - SortBy@99..119 - Order@99..104 "ORDER" - Whitespace@104..105 " " - By@105..107 "BY" - Whitespace@107..108 " " - ColumnRef@108..114 - Ident@108..114 "salary" - Whitespace@114..115 " " - Desc@115..119 "DESC" - Ascii41@119..120 ")" - Ascii59@120..121 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "sum", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "salary", - }, - ), - ), - }, - ], - location: 11, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: Some( - WindowDef { - name: "w", - refname: "", - partition_clause: [], - order_clause: [], - frame_options: 1058, - start_offset: None, - end_offset: None, - location: 24, - }, - ), - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "avg", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "salary", - }, - ), - ), - }, - ], - location: 31, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: Some( - WindowDef { - name: "w", - refname: "", - partition_clause: [], - order_clause: [], - frame_options: 1058, - start_offset: None, - end_offset: None, - location: 44, - }, - ), - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 27, - }, - ), - ), - }, - ), - location: 27, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "empsalary", - inh: true, - relpersistence: "p", - alias: None, - location: 53, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [ - Node { - node: Some( - WindowDef( - WindowDef { - name: "w", - refname: "", - partition_clause: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "depname", - }, - ), - ), - }, - ], - location: 91, - }, - ), - ), - }, - ], - order_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "salary", - }, - ), - ), - }, - ], - location: 108, - }, - ), - ), - }, - ), - sortby_dir: SortbyDesc, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - frame_options: 1058, - start_offset: None, - end_offset: None, - location: 77, - }, - ), - ), - }, - ], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..120, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0015@1.snap b/crates/parser/tests/snapshots/statements/valid/0015@1.snap deleted file mode 100644 index 5a425327..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0015@1.snap +++ /dev/null @@ -1,359 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT\n count(*) AS unfiltered,\n count(*) FILTER (WHERE i < 5) AS filtered\nFROM generate_series(1,10) AS s(i);" ---- -Parse { - cst: SourceFile@0..116 - SelectStmt@0..116 - Select@0..6 "SELECT" - Newline@6..7 "\n" - Whitespace@7..11 " " - ResTarget@11..33 - FuncCall@11..18 - Ident@11..16 "count" - Ascii40@16..17 "(" - Ascii42@17..18 "*" - Ascii41@18..19 ")" - Whitespace@19..20 " " - As@20..22 "AS" - Whitespace@22..23 " " - Ident@23..33 "unfiltered" - Ascii44@33..34 "," - Newline@34..35 "\n" - Whitespace@35..39 " " - ResTarget@39..80 - FuncCall@39..67 - Ident@39..44 "count" - Ascii40@44..45 "(" - Ascii42@45..46 "*" - Ascii41@46..47 ")" - Whitespace@47..48 " " - Filter@48..54 "FILTER" - Whitespace@54..55 " " - Ascii40@55..56 "(" - Where@56..61 "WHERE" - Whitespace@61..62 " " - AExpr@62..67 - ColumnRef@62..63 - Ident@62..63 "i" - Whitespace@63..64 " " - Ascii60@64..65 "<" - Whitespace@65..66 " " - AConst@66..67 - Iconst@66..67 "5" - Ascii41@67..68 ")" - Whitespace@68..69 " " - As@69..71 "AS" - Whitespace@71..72 " " - Ident@72..80 "filtered" - Newline@80..81 "\n" - From@81..85 "FROM" - Whitespace@85..86 " " - RangeFunction@86..114 - List@86..106 - FuncCall@86..106 - Ident@86..101 "generate_series" - Ascii40@101..102 "(" - AConst@102..103 - Iconst@102..103 "1" - Ascii44@103..104 "," - AConst@104..106 - Iconst@104..106 "10" - Ascii41@106..107 ")" - Whitespace@107..108 " " - Alias@108..114 - As@108..110 "AS" - Whitespace@110..111 " " - Ident@111..112 "s" - Ascii40@112..113 "(" - Ident@113..114 "i" - Ascii41@114..115 ")" - Ascii59@115..116 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "unfiltered", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 11, - }, - ), - ), - }, - ), - location: 11, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "filtered", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "<", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "i", - }, - ), - ), - }, - ], - location: 62, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 66, - val: Some( - Ival( - Integer { - ival: 5, - }, - ), - ), - }, - ), - ), - }, - ), - location: 64, - }, - ), - ), - }, - ), - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 39, - }, - ), - ), - }, - ), - location: 39, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeFunction( - RangeFunction { - lateral: false, - ordinality: false, - is_rowsfrom: false, - functions: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "generate_series", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 102, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 104, - val: Some( - Ival( - Integer { - ival: 10, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 86, - }, - ), - ), - }, - Node { - node: None, - }, - ], - }, - ), - ), - }, - ], - alias: Some( - Alias { - aliasname: "s", - colnames: [ - Node { - node: Some( - String( - String { - sval: "i", - }, - ), - ), - }, - ], - }, - ), - coldeflist: [], - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..115, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0016@1.snap b/crates/parser/tests/snapshots/statements/valid/0016@1.snap deleted file mode 100644 index 4f706145..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0016@1.snap +++ /dev/null @@ -1,200 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT * FROM tbl WHERE a COLLATE \"C\" > 'foo';" ---- -Parse { - cst: SourceFile@0..46 - SelectStmt@0..46 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..8 - ColumnRef@7..8 - AStar@7..8 - Ascii42@7..8 "*" - Whitespace@8..9 " " - From@9..13 "FROM" - Whitespace@13..14 " " - RangeVar@14..17 - Ident@14..17 "tbl" - Whitespace@17..18 " " - Where@18..23 "WHERE" - Whitespace@23..24 " " - AExpr@24..45 - CollateClause@24..37 - ColumnRef@24..25 - Ident@24..25 "a" - Whitespace@25..26 " " - Collate@26..33 "COLLATE" - Whitespace@33..34 " " - Ident@34..37 "\"C\"" - Whitespace@37..38 " " - Ascii62@38..39 ">" - Whitespace@39..40 " " - AConst@40..45 - Sconst@40..45 "'foo'" - Ascii59@45..46 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 14, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - CollateClause( - CollateClause { - arg: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "a", - }, - ), - ), - }, - ], - location: 24, - }, - ), - ), - }, - ), - collname: [ - Node { - node: Some( - String( - String { - sval: "C", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 40, - val: Some( - Sval( - String { - sval: "foo", - }, - ), - ), - }, - ), - ), - }, - ), - location: 38, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0017@1.snap b/crates/parser/tests/snapshots/statements/valid/0017@1.snap deleted file mode 100644 index e1fc0760..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0017@1.snap +++ /dev/null @@ -1,358 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)\n FROM states;" ---- -Parse { - cst: SourceFile@0..92 - SelectStmt@0..92 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..11 - ColumnRef@7..11 - NameP@7..11 "name" - Ascii44@11..12 "," - Whitespace@12..13 " " - ResTarget@13..74 - SubLink@13..74 - SelectStmt@13..74 - Ascii40@13..14 "(" - Select@14..20 "SELECT" - Whitespace@20..21 " " - ResTarget@21..28 - FuncCall@21..28 - Ident@21..24 "max" - Ascii40@24..25 "(" - ColumnRef@25..28 - Ident@25..28 "pop" - Ascii41@28..29 ")" - Whitespace@29..30 " " - From@30..34 "FROM" - Whitespace@34..35 " " - RangeVar@35..41 - Ident@35..41 "cities" - Whitespace@41..42 " " - Where@42..47 "WHERE" - Whitespace@47..48 " " - AExpr@48..74 - ColumnRef@48..60 - Ident@48..54 "cities" - Ascii46@54..55 "." - Ident@55..60 "state" - Whitespace@60..61 " " - Ascii61@61..62 "=" - Whitespace@62..63 " " - ColumnRef@63..74 - Ident@63..69 "states" - Ascii46@69..70 "." - NameP@70..74 "name" - Ascii41@74..75 ")" - Newline@75..76 "\n" - Whitespace@76..80 " " - From@80..84 "FROM" - Whitespace@84..85 " " - RangeVar@85..91 - Ident@85..91 "states" - Ascii59@91..92 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - SubLink( - SubLink { - xpr: None, - sub_link_type: ExprSublink, - sub_link_id: 0, - testexpr: None, - oper_name: [], - subselect: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "max", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "pop", - }, - ), - ), - }, - ], - location: 25, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 21, - }, - ), - ), - }, - ), - location: 21, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "p", - alias: None, - location: 35, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "cities", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "state", - }, - ), - ), - }, - ], - location: 48, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "states", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - location: 63, - }, - ), - ), - }, - ), - location: 61, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - location: 13, - }, - ), - ), - }, - ), - location: 13, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "states", - inh: true, - relpersistence: "p", - alias: None, - location: 85, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..91, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0018@1.snap b/crates/parser/tests/snapshots/statements/valid/0018@1.snap deleted file mode 100644 index 216198cd..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0018@1.snap +++ /dev/null @@ -1,189 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT ARRAY[1,2,22.7]::integer[];" ---- -Parse { - cst: SourceFile@0..34 - SelectStmt@0..34 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..31 - TypeCast@7..31 - AArrayExpr@7..21 - Array@7..12 "ARRAY" - Ascii91@12..13 "[" - AConst@13..14 - Iconst@13..14 "1" - Ascii44@14..15 "," - AConst@15..16 - Iconst@15..16 "2" - Ascii44@16..17 "," - AConst@17..21 - Fconst@17..21 "22.7" - Ascii93@21..22 "]" - Typecast@22..24 "::" - TypeName@24..31 - Integer@24..31 "integer" - Ascii91@31..32 "[" - Ascii93@32..33 "]" - Ascii59@33..34 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - TypeCast( - TypeCast { - arg: Some( - Node { - node: Some( - AArrayExpr( - AArrayExpr { - elements: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 13, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 15, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 17, - val: Some( - Fval( - Float { - fval: "22.7", - }, - ), - ), - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [ - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - location: 24, - }, - ), - location: 22, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..33, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0019@1.snap b/crates/parser/tests/snapshots/statements/valid/0019@1.snap deleted file mode 100644 index 54b8b8d6..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0019@1.snap +++ /dev/null @@ -1,333 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT CASE WHEN min(employees) > 0\n THEN avg(expenses / employees)\n END\n FROM departments;" ---- -Parse { - cst: SourceFile@0..111 - SelectStmt@0..111 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..89 - CaseExpr@7..89 - Case@7..11 "CASE" - Whitespace@11..12 " " - CaseWhen@12..77 - When@12..16 "WHEN" - Whitespace@16..17 " " - AExpr@17..35 - FuncCall@17..30 - Ident@17..20 "min" - Ascii40@20..21 "(" - ColumnRef@21..30 - Ident@21..30 "employees" - Ascii41@30..31 ")" - Whitespace@31..32 " " - Ascii62@32..33 ">" - Whitespace@33..34 " " - AConst@34..35 - Iconst@34..35 "0" - Newline@35..36 "\n" - Whitespace@36..48 " " - Then@48..52 "THEN" - Whitespace@52..53 " " - FuncCall@53..77 - Ident@53..56 "avg" - Ascii40@56..57 "(" - AExpr@57..77 - ColumnRef@57..65 - Ident@57..65 "expenses" - Whitespace@65..66 " " - Ascii47@66..67 "/" - Whitespace@67..68 " " - ColumnRef@68..77 - Ident@68..77 "employees" - Ascii41@77..78 ")" - Newline@78..79 "\n" - Whitespace@79..86 " " - EndP@86..89 "END" - Newline@89..90 "\n" - Whitespace@90..94 " " - From@94..98 "FROM" - Whitespace@98..99 " " - RangeVar@99..110 - Ident@99..110 "departments" - Ascii59@110..111 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - CaseExpr( - CaseExpr { - xpr: None, - casetype: 0, - casecollid: 0, - arg: None, - args: [ - Node { - node: Some( - CaseWhen( - CaseWhen { - xpr: None, - expr: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "min", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "employees", - }, - ), - ), - }, - ], - location: 21, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 17, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 34, - val: Some( - Ival( - Integer { - ival: 0, - }, - ), - ), - }, - ), - ), - }, - ), - location: 32, - }, - ), - ), - }, - ), - result: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "avg", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "/", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "expenses", - }, - ), - ), - }, - ], - location: 57, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "employees", - }, - ), - ), - }, - ], - location: 68, - }, - ), - ), - }, - ), - location: 66, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 53, - }, - ), - ), - }, - ), - location: 12, - }, - ), - ), - }, - ], - defresult: None, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "departments", - inh: true, - relpersistence: "p", - alias: None, - location: 99, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..110, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0020@1.snap b/crates/parser/tests/snapshots/statements/valid/0020@1.snap deleted file mode 100644 index c10be587..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0020@1.snap +++ /dev/null @@ -1,341 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false)\nRETURNS text\nAS\n$$\n SELECT CASE\n WHEN $3 THEN UPPER($1 || ' ' || $2)\n ELSE LOWER($1 || ' ' || $2)\n END;\n$$\nLANGUAGE SQL IMMUTABLE STRICT;" ---- -Parse { - cst: SourceFile@0..245 - CreateFunctionStmt@0..245 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Function@7..15 "FUNCTION" - Whitespace@15..16 " " - Ident@16..37 "concat_lower_or_upper" - Ascii40@37..38 "(" - FunctionParameter@38..44 - Ident@38..39 "a" - Whitespace@39..40 " " - TypeName@40..44 - TextP@40..44 "text" - Ascii44@44..45 "," - Whitespace@45..46 " " - FunctionParameter@46..52 - Ident@46..47 "b" - Whitespace@47..48 " " - TypeName@48..52 - TextP@48..52 "text" - Ascii44@52..53 "," - Whitespace@53..54 " " - FunctionParameter@54..85 - Ident@54..63 "uppercase" - Whitespace@63..64 " " - TypeName@64..71 - BooleanP@64..71 "boolean" - Whitespace@71..72 " " - Default@72..79 "DEFAULT" - Whitespace@79..80 " " - AConst@80..85 - FalseP@80..85 "false" - Ascii41@85..86 ")" - Newline@86..87 "\n" - Returns@87..94 "RETURNS" - Whitespace@94..95 " " - TypeName@95..99 - TextP@95..99 "text" - Newline@99..100 "\n" - DefElem@100..214 - As@100..102 "AS" - Newline@102..103 "\n" - List@103..214 - Sconst@103..214 "$$\n SELECT CASE\n ..." - Newline@214..215 "\n" - DefElem@215..227 - Language@215..223 "LANGUAGE" - Whitespace@223..224 " " - SqlP@224..227 "SQL" - Whitespace@227..228 " " - DefElem@228..237 - Immutable@228..237 "IMMUTABLE" - Whitespace@237..238 " " - DefElem@238..244 - StrictP@238..244 "STRICT" - Ascii59@244..245 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: false, - funcname: [ - Node { - node: Some( - String( - String { - sval: "concat_lower_or_upper", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "a", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 40, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "b", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 48, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "uppercase", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "bool", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 64, - }, - ), - mode: FuncParamDefault, - defexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 80, - val: Some( - Boolval( - Boolean { - boolval: false, - }, - ), - ), - }, - ), - ), - }, - ), - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 95, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "\n SELECT CASE\n WHEN $3 THEN UPPER($1 || ' ' || $2)\n ELSE LOWER($1 || ' ' || $2)\n END;\n", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 100, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 215, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 228, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "strict", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: true, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 238, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..244, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0021@1.snap b/crates/parser/tests/snapshots/statements/valid/0021@1.snap deleted file mode 100644 index 909a74f4..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0021@1.snap +++ /dev/null @@ -1,209 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true);" ---- -Parse { - cst: SourceFile@0..76 - SelectStmt@0..76 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..74 - FuncCall@7..74 - Ident@7..28 "concat_lower_or_upper" - Ascii40@28..29 "(" - NamedArgExpr@29..41 - Ident@29..30 "a" - Whitespace@30..31 " " - EqualsGreater@31..33 "=>" - Whitespace@33..34 " " - AConst@34..41 - Sconst@34..41 "'Hello'" - Ascii44@41..42 "," - Whitespace@42..43 " " - NamedArgExpr@43..55 - Ident@43..44 "b" - Whitespace@44..45 " " - EqualsGreater@45..47 "=>" - Whitespace@47..48 " " - AConst@48..55 - Sconst@48..55 "'World'" - Ascii44@55..56 "," - Whitespace@56..57 " " - NamedArgExpr@57..74 - Ident@57..66 "uppercase" - Whitespace@66..67 " " - EqualsGreater@67..69 "=>" - Whitespace@69..70 " " - AConst@70..74 - TrueP@70..74 "true" - Ascii41@74..75 ")" - Ascii59@75..76 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "concat_lower_or_upper", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - NamedArgExpr( - NamedArgExpr { - xpr: None, - arg: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 34, - val: Some( - Sval( - String { - sval: "Hello", - }, - ), - ), - }, - ), - ), - }, - ), - name: "a", - argnumber: -1, - location: 29, - }, - ), - ), - }, - Node { - node: Some( - NamedArgExpr( - NamedArgExpr { - xpr: None, - arg: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 48, - val: Some( - Sval( - String { - sval: "World", - }, - ), - ), - }, - ), - ), - }, - ), - name: "b", - argnumber: -1, - location: 43, - }, - ), - ), - }, - Node { - node: Some( - NamedArgExpr( - NamedArgExpr { - xpr: None, - arg: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 70, - val: Some( - Boolval( - Boolean { - boolval: true, - }, - ), - ), - }, - ), - ), - }, - ), - name: "uppercase", - argnumber: -1, - location: 57, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..75, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0022@1.snap b/crates/parser/tests/snapshots/statements/valid/0022@1.snap deleted file mode 100644 index 7e3180e0..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0022@1.snap +++ /dev/null @@ -1,298 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE products (\n product_no integer,\n name text,\n price numeric DEFAULT 9.99\n);" ---- -Parse { - cst: SourceFile@0..96 - CreateStmt@0..96 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..21 - Ident@13..21 "products" - Whitespace@21..22 " " - Ascii40@22..23 "(" - Newline@23..24 "\n" - Whitespace@24..28 " " - ColumnDef@28..46 - Ident@28..38 "product_no" - Whitespace@38..39 " " - TypeName@39..46 - Integer@39..46 "integer" - Ascii44@46..47 "," - Newline@47..48 "\n" - Whitespace@48..52 " " - ColumnDef@52..61 - NameP@52..56 "name" - Whitespace@56..57 " " - TypeName@57..61 - TextP@57..61 "text" - Ascii44@61..62 "," - Newline@62..63 "\n" - Whitespace@63..67 " " - ColumnDef@67..93 - Ident@67..72 "price" - Whitespace@72..73 " " - TypeName@73..80 - Numeric@73..80 "numeric" - Whitespace@80..81 " " - Constraint@81..93 - Default@81..88 "DEFAULT" - Whitespace@88..89 " " - AConst@89..93 - Fconst@89..93 "9.99" - Newline@93..94 "\n" - Ascii41@94..95 ")" - Ascii59@95..96 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "products", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "product_no", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 39, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 28, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 57, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 52, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "price", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "numeric", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 73, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 81, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Fval( - Float { - fval: "9.99", - }, - ), - ), - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 67, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..95, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0023@1.snap b/crates/parser/tests/snapshots/statements/valid/0023@1.snap deleted file mode 100644 index b73b8975..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0023@1.snap +++ /dev/null @@ -1,651 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE products (\n product_no integer,\n name text,\n price numeric CHECK (price > 0),\n discounted_price numeric CHECK (discounted_price > 0),\n CHECK (price > discounted_price)\n);" ---- -Parse { - cst: SourceFile@0..198 - CreateStmt@0..198 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..21 - Ident@13..21 "products" - Whitespace@21..22 " " - Ascii40@22..23 "(" - Newline@23..24 "\n" - Whitespace@24..28 " " - ColumnDef@28..46 - Ident@28..38 "product_no" - Whitespace@38..39 " " - TypeName@39..46 - Integer@39..46 "integer" - Ascii44@46..47 "," - Newline@47..48 "\n" - Whitespace@48..52 " " - ColumnDef@52..61 - NameP@52..56 "name" - Whitespace@56..57 " " - TypeName@57..61 - TextP@57..61 "text" - Ascii44@61..62 "," - Newline@62..63 "\n" - Whitespace@63..67 " " - ColumnDef@67..97 - Ident@67..72 "price" - Whitespace@72..73 " " - TypeName@73..80 - Numeric@73..80 "numeric" - Whitespace@80..81 " " - Constraint@81..97 - Check@81..86 "CHECK" - Whitespace@86..87 " " - Ascii40@87..88 "(" - AExpr@88..97 - ColumnRef@88..93 - Ident@88..93 "price" - Whitespace@93..94 " " - Ascii62@94..95 ">" - Whitespace@95..96 " " - AConst@96..97 - Iconst@96..97 "0" - Ascii41@97..98 ")" - Ascii44@98..99 "," - Newline@99..100 "\n" - Whitespace@100..104 " " - ColumnDef@104..156 - Ident@104..120 "discounted_price" - Whitespace@120..121 " " - TypeName@121..128 - Numeric@121..128 "numeric" - Whitespace@128..129 " " - Constraint@129..156 - Check@129..134 "CHECK" - Whitespace@134..135 " " - Ascii40@135..136 "(" - AExpr@136..156 - ColumnRef@136..152 - Ident@136..152 "discounted_price" - Whitespace@152..153 " " - Ascii62@153..154 ">" - Whitespace@154..155 " " - AConst@155..156 - Iconst@155..156 "0" - Ascii41@156..157 ")" - Ascii44@157..158 "," - Newline@158..159 "\n" - Whitespace@159..163 " " - Constraint@163..194 - Check@163..168 "CHECK" - Whitespace@168..169 " " - Ascii40@169..170 "(" - AExpr@170..194 - ColumnRef@170..175 - Ident@170..175 "price" - Whitespace@175..176 " " - Ascii62@176..177 ">" - Whitespace@177..178 " " - ColumnRef@178..194 - Ident@178..194 "discounted_price" - Ascii41@194..195 ")" - Newline@195..196 "\n" - Ascii41@196..197 ")" - Ascii59@197..198 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "products", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "product_no", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 39, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 28, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 57, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 52, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "price", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "numeric", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 73, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrCheck, - conname: "", - deferrable: false, - initdeferred: false, - location: 81, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "price", - }, - ), - ), - }, - ], - location: 88, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 96, - val: Some( - Ival( - Integer { - ival: 0, - }, - ), - ), - }, - ), - ), - }, - ), - location: 94, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 67, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "discounted_price", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "numeric", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 121, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrCheck, - conname: "", - deferrable: false, - initdeferred: false, - location: 129, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "discounted_price", - }, - ), - ), - }, - ], - location: 136, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 155, - val: Some( - Ival( - Integer { - ival: 0, - }, - ), - ), - }, - ), - ), - }, - ), - location: 153, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 104, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrCheck, - conname: "", - deferrable: false, - initdeferred: false, - location: 163, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: ">", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "price", - }, - ), - ), - }, - ], - location: 170, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "discounted_price", - }, - ), - ), - }, - ], - location: 178, - }, - ), - ), - }, - ), - location: 176, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..197, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0024@1.snap b/crates/parser/tests/snapshots/statements/valid/0024@1.snap deleted file mode 100644 index 669fe527..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0024@1.snap +++ /dev/null @@ -1,425 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE order_items (\n product_no integer REFERENCES products,\n order_id integer REFERENCES orders,\n quantity integer,\n PRIMARY KEY (product_no, order_id)\n);" ---- -Parse { - cst: SourceFile@0..174 - CreateStmt@0..174 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..24 - Ident@13..24 "order_items" - Whitespace@24..25 " " - Ascii40@25..26 "(" - Newline@26..27 "\n" - Whitespace@27..31 " " - ColumnDef@31..69 - Ident@31..41 "product_no" - Whitespace@41..42 " " - TypeName@42..49 - Integer@42..49 "integer" - Whitespace@49..50 " " - Constraint@50..69 - References@50..60 "REFERENCES" - Whitespace@60..61 " " - RangeVar@61..69 - Ident@61..69 "products" - Ascii44@69..70 "," - Newline@70..71 "\n" - Whitespace@71..75 " " - ColumnDef@75..109 - Ident@75..83 "order_id" - Whitespace@83..84 " " - TypeName@84..91 - Integer@84..91 "integer" - Whitespace@91..92 " " - Constraint@92..109 - References@92..102 "REFERENCES" - Whitespace@102..103 " " - RangeVar@103..109 - Ident@103..109 "orders" - Ascii44@109..110 "," - Newline@110..111 "\n" - Whitespace@111..115 " " - ColumnDef@115..131 - Ident@115..123 "quantity" - Whitespace@123..124 " " - TypeName@124..131 - Integer@124..131 "integer" - Ascii44@131..132 "," - Newline@132..133 "\n" - Whitespace@133..137 " " - Constraint@137..170 - Primary@137..144 "PRIMARY" - Whitespace@144..145 " " - Key@145..148 "KEY" - Whitespace@148..149 " " - Ascii40@149..150 "(" - Ident@150..160 "product_no" - Ascii44@160..161 "," - Whitespace@161..162 " " - Ident@162..170 "order_id" - Ascii41@170..171 ")" - Newline@171..172 "\n" - Ascii41@172..173 ")" - Ascii59@173..174 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "order_items", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "product_no", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 42, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrForeign, - conname: "", - deferrable: false, - initdeferred: false, - location: 50, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "products", - inh: true, - relpersistence: "p", - alias: None, - location: 61, - }, - ), - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "s", - fk_upd_action: "a", - fk_del_action: "a", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "order_id", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 84, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrForeign, - conname: "", - deferrable: false, - initdeferred: false, - location: 92, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "orders", - inh: true, - relpersistence: "p", - alias: None, - location: 103, - }, - ), - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "s", - fk_upd_action: "a", - fk_del_action: "a", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 75, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "quantity", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 124, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 115, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrPrimary, - conname: "", - deferrable: false, - initdeferred: false, - location: 137, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [ - Node { - node: Some( - String( - String { - sval: "product_no", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "order_id", - }, - ), - ), - }, - ], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..173, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0025@1.snap b/crates/parser/tests/snapshots/statements/valid/0025@1.snap deleted file mode 100644 index 76ca3e20..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0025@1.snap +++ /dev/null @@ -1,176 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "ALTER TABLE products ADD CHECK (name <> '');" ---- -Parse { - cst: SourceFile@0..44 - AlterTableStmt@0..44 - Alter@0..5 "ALTER" - Whitespace@5..6 " " - Table@6..11 "TABLE" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "products" - Whitespace@20..21 " " - AlterTableCmd@21..42 - AddP@21..24 "ADD" - Whitespace@24..25 " " - Constraint@25..42 - Check@25..30 "CHECK" - Whitespace@30..31 " " - Ascii40@31..32 "(" - AExpr@32..42 - ColumnRef@32..36 - NameP@32..36 "name" - Whitespace@36..37 " " - NotEquals@37..39 "<>" - Whitespace@39..40 " " - AConst@40..42 - Sconst@40..42 "''" - Ascii41@42..43 ")" - Ascii59@43..44 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: AlterTableStmt( - AlterTableStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "products", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cmds: [ - Node { - node: Some( - AlterTableCmd( - AlterTableCmd { - subtype: AtAddConstraint, - name: "", - num: 0, - newowner: None, - def: Some( - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrCheck, - conname: "", - deferrable: false, - initdeferred: false, - location: 25, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "<>", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - location: 32, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 40, - val: Some( - Sval( - String { - sval: "", - }, - ), - ), - }, - ), - ), - }, - ), - location: 37, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ), - behavior: DropRestrict, - missing_ok: false, - recurse: false, - }, - ), - ), - }, - ], - objtype: ObjectTable, - missing_ok: false, - }, - ), - range: 0..43, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0026@1.snap b/crates/parser/tests/snapshots/statements/valid/0026@1.snap deleted file mode 100644 index 4657fe1f..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0026@1.snap +++ /dev/null @@ -1,169 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);" ---- -Parse { - cst: SourceFile@0..59 - AlterTableStmt@0..59 - Alter@0..5 "ALTER" - Whitespace@5..6 " " - Table@6..11 "TABLE" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "products" - Whitespace@20..21 " " - AlterTableCmd@21..57 - Alter@21..26 "ALTER" - Whitespace@26..27 " " - Column@27..33 "COLUMN" - Whitespace@33..34 " " - Ident@34..39 "price" - Whitespace@39..40 " " - TypeP@40..44 "TYPE" - Whitespace@44..45 " " - ColumnDef@45..57 - TypeName@45..57 - Numeric@45..52 "numeric" - Ascii40@52..53 "(" - AConst@53..55 - Iconst@53..55 "10" - Ascii44@55..56 "," - AConst@56..57 - Iconst@56..57 "2" - Ascii41@57..58 ")" - Ascii59@58..59 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: AlterTableStmt( - AlterTableStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "products", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cmds: [ - Node { - node: Some( - AlterTableCmd( - AlterTableCmd { - subtype: AtAlterColumnType, - name: "price", - num: 0, - newowner: None, - def: Some( - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "numeric", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 53, - val: Some( - Ival( - Integer { - ival: 10, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 56, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 45, - }, - ), - compression: "", - inhcount: 0, - is_local: false, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 34, - }, - ), - ), - }, - ), - behavior: DropRestrict, - missing_ok: false, - recurse: false, - }, - ), - ), - }, - ], - objtype: ObjectTable, - missing_ok: false, - }, - ), - range: 0..58, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0027@1.snap b/crates/parser/tests/snapshots/statements/valid/0027@1.snap deleted file mode 100644 index 62d26501..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0027@1.snap +++ /dev/null @@ -1,26 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: GRANT UPDATE ON accounts TO joe; ---- -Parse { - cst: SourceFile@0..31 - Grant@0..5 "GRANT" - Update@5..11 "UPDATE" - Whitespace@11..12 " " - On@12..14 "ON" - Whitespace@14..15 " " - Ident@15..23 "accounts" - Whitespace@23..24 " " - To@24..26 "TO" - Whitespace@26..27 " " - Ident@27..30 "joe" - Ascii59@30..31 ";" - , - errors: [ - SyntaxError( - "Invalid statement: syntax error at or near \"ON\"", - 2..12, - ), - ], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0028@1.snap b/crates/parser/tests/snapshots/statements/valid/0028@1.snap deleted file mode 100644 index 03adcbde..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0028@1.snap +++ /dev/null @@ -1,22 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: REVOKE ALL ON accounts FROM PUBLIC; ---- -Parse { - cst: SourceFile@0..35 - Revoke@0..6 "REVOKE" - Whitespace@6..7 " " - All@7..10 "ALL" - Whitespace@10..11 " " - On@11..13 "ON" - Whitespace@13..14 " " - Ident@14..22 "accounts" - Whitespace@22..23 " " - From@23..27 "FROM" - Whitespace@27..28 " " - Ident@28..34 "PUBLIC" - Ascii59@34..35 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0029@1.snap b/crates/parser/tests/snapshots/statements/valid/0029@1.snap deleted file mode 100644 index 726bb831..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0029@1.snap +++ /dev/null @@ -1,44 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;" ---- -Parse { - cst: SourceFile@0..57 - Grant@0..5 "GRANT" - Select@5..11 "SELECT" - Whitespace@11..12 " " - Ascii40@12..13 "(" - Ident@13..17 "col1" - Ascii41@17..18 ")" - Ascii44@18..19 "," - Update@19..25 "UPDATE" - Whitespace@25..26 " " - Ascii40@26..27 "(" - Ident@27..31 "col1" - Ascii41@31..32 ")" - Whitespace@32..33 " " - On@33..35 "ON" - Whitespace@35..36 " " - Ident@36..43 "mytable" - Whitespace@43..44 " " - To@44..46 "TO" - Whitespace@46..47 " " - Ident@47..56 "miriam_rw" - Ascii59@56..57 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 20..20, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 2..8, - ), - SyntaxError( - "Invalid statement: syntax error at or near \"(\"", - 9..23, - ), - ], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0030@1.snap b/crates/parser/tests/snapshots/statements/valid/0030@1.snap deleted file mode 100644 index 6d0e9db9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0030@1.snap +++ /dev/null @@ -1,137 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE POLICY account_managers ON accounts TO managers\n USING (manager = current_user);" ---- -Parse { - cst: SourceFile@0..90 - CreatePolicyStmt@0..90 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Policy@7..13 "POLICY" - Whitespace@13..14 " " - Ident@14..30 "account_managers" - Whitespace@30..31 " " - On@31..33 "ON" - Whitespace@33..34 " " - RangeVar@34..42 - Ident@34..42 "accounts" - Whitespace@42..43 " " - To@43..45 "TO" - Whitespace@45..46 " " - RoleSpec@46..54 - Ident@46..54 "managers" - Newline@54..55 "\n" - Whitespace@55..59 " " - Using@59..64 "USING" - Whitespace@64..65 " " - Ascii40@65..66 "(" - AExpr@66..88 - ColumnRef@66..73 - Ident@66..73 "manager" - Whitespace@73..74 " " - Ascii61@74..75 "=" - Whitespace@75..76 " " - SqlvalueFunction@76..88 - CurrentUser@76..88 "current_user" - Ascii41@88..89 ")" - Ascii59@89..90 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePolicyStmt( - CreatePolicyStmt { - policy_name: "account_managers", - table: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "accounts", - inh: true, - relpersistence: "p", - alias: None, - location: 34, - }, - ), - cmd_name: "all", - permissive: true, - roles: [ - Node { - node: Some( - RoleSpec( - RoleSpec { - roletype: RolespecCstring, - rolename: "managers", - location: 46, - }, - ), - ), - }, - ], - qual: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "manager", - }, - ), - ), - }, - ], - location: 66, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - SqlvalueFunction( - SqlValueFunction { - xpr: None, - op: SvfopCurrentUser, - r#type: 0, - typmod: -1, - location: 76, - }, - ), - ), - }, - ), - location: 74, - }, - ), - ), - }, - ), - with_check: None, - }, - ), - range: 0..89, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0031@1.snap b/crates/parser/tests/snapshots/statements/valid/0031@1.snap deleted file mode 100644 index eb1a6933..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0031@1.snap +++ /dev/null @@ -1,83 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE POLICY user_mod ON passwd FOR UPDATE\n USING (current_user = user_name)\n WITH CHECK (\n current_user = user_name AND\n shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh')\n );" ---- -Parse { - cst: SourceFile@0..202 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Policy@7..13 "POLICY" - Whitespace@13..14 " " - Ident@14..22 "user_mod" - Whitespace@22..23 " " - On@23..25 "ON" - Whitespace@25..26 " " - Ident@26..32 "passwd" - Whitespace@32..33 " " - For@33..36 "FOR" - Update@36..42 "UPDATE" - Newline@42..43 "\n" - Whitespace@43..45 " " - Using@45..50 "USING" - Whitespace@50..51 " " - Ascii40@51..52 "(" - CurrentUser@52..64 "current_user" - Whitespace@64..65 " " - Ascii61@65..66 "=" - Whitespace@66..67 " " - Ident@67..76 "user_name" - Ascii41@76..77 ")" - Newline@77..78 "\n" - Whitespace@78..80 " " - With@80..84 "WITH" - Whitespace@84..85 " " - Check@85..90 "CHECK" - Whitespace@90..91 " " - Ascii40@91..92 "(" - Newline@92..93 "\n" - Whitespace@93..97 " " - CurrentUser@97..109 "current_user" - Whitespace@109..110 " " - Ascii61@110..111 "=" - Whitespace@111..112 " " - Ident@112..121 "user_name" - Whitespace@121..122 " " - And@122..125 "AND" - Newline@125..126 "\n" - Whitespace@126..130 " " - Ident@130..135 "shell" - Whitespace@135..136 " " - InP@136..138 "IN" - Whitespace@138..139 " " - Ascii40@139..140 "(" - Sconst@140..151 "'/bin/bash'" - Ascii44@151..152 "," - Sconst@152..161 "'/bin/sh'" - Ascii44@161..162 "," - Sconst@162..173 "'/bin/dash'" - Ascii44@173..174 "," - Sconst@174..184 "'/bin/zsh'" - Ascii44@184..185 "," - Sconst@185..196 "'/bin/tcsh'" - Ascii41@196..197 ")" - Newline@197..198 "\n" - Whitespace@198..200 " " - Ascii41@200..201 ")" - Ascii59@201..202 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 36..36, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..11, - ), - SyntaxError( - "Invalid statement: syntax error at or near \"USING\"", - 12..61, - ), - ], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0032@1.snap b/crates/parser/tests/snapshots/statements/valid/0032@1.snap deleted file mode 100644 index 0d57851d..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0032@1.snap +++ /dev/null @@ -1,70 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SET search_path TO myschema,public;" ---- -Parse { - cst: SourceFile@0..35 - VariableSetStmt@0..35 - Set@0..3 "SET" - Whitespace@3..4 " " - Ident@4..15 "search_path" - Whitespace@15..16 " " - To@16..18 "TO" - Whitespace@18..19 " " - AConst@19..27 - Ident@19..27 "myschema" - Ascii44@27..28 "," - AConst@28..34 - Ident@28..34 "public" - Ascii59@34..35 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: VariableSetStmt( - VariableSetStmt { - kind: VarSetValue, - name: "search_path", - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 19, - val: Some( - Sval( - String { - sval: "myschema", - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 28, - val: Some( - Sval( - String { - sval: "public", - }, - ), - ), - }, - ), - ), - }, - ], - is_local: false, - }, - ), - range: 0..34, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0033@1.snap b/crates/parser/tests/snapshots/statements/valid/0033@1.snap deleted file mode 100644 index 313f9261..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0033@1.snap +++ /dev/null @@ -1,419 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE measurement (\n city_id int not null,\n logdate date not null,\n peaktemp int,\n unitsales int\n) PARTITION BY RANGE (logdate);" ---- -Parse { - cst: SourceFile@0..176 - CreateStmt@0..176 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..24 - Ident@13..24 "measurement" - Whitespace@24..25 " " - Ascii40@25..26 "(" - Newline@26..27 "\n" - Whitespace@27..31 " " - ColumnDef@31..59 - Ident@31..38 "city_id" - Whitespace@38..47 " " - TypeName@47..50 - IntP@47..50 "int" - Whitespace@50..51 " " - Constraint@51..59 - Not@51..54 "not" - Whitespace@54..55 " " - NullP@55..59 "null" - Ascii44@59..60 "," - Newline@60..61 "\n" - Whitespace@61..65 " " - ColumnDef@65..94 - Ident@65..72 "logdate" - Whitespace@72..81 " " - TypeName@81..85 - Ident@81..85 "date" - Whitespace@85..86 " " - Constraint@86..94 - Not@86..89 "not" - Whitespace@89..90 " " - NullP@90..94 "null" - Ascii44@94..95 "," - Newline@95..96 "\n" - Whitespace@96..100 " " - ColumnDef@100..119 - Ident@100..108 "peaktemp" - Whitespace@108..116 " " - TypeName@116..119 - IntP@116..119 "int" - Ascii44@119..120 "," - Newline@120..121 "\n" - Whitespace@121..125 " " - ColumnDef@125..144 - Ident@125..134 "unitsales" - Whitespace@134..141 " " - TypeName@141..144 - IntP@141..144 "int" - Newline@144..145 "\n" - Ascii41@145..146 ")" - Whitespace@146..147 " " - PartitionSpec@147..174 - Partition@147..156 "PARTITION" - Whitespace@156..157 " " - By@157..159 "BY" - Whitespace@159..160 " " - Range@160..165 "RANGE" - Whitespace@165..166 " " - Ascii40@166..167 "(" - PartitionElem@167..174 - Ident@167..174 "logdate" - Ascii41@174..175 ")" - Ascii59@175..176 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "measurement", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "city_id", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 47, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrNotnull, - conname: "", - deferrable: false, - initdeferred: false, - location: 51, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "logdate", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "date", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 81, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrNotnull, - conname: "", - deferrable: false, - initdeferred: false, - location: 86, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 65, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "peaktemp", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 116, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 100, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "unitsales", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 141, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 125, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: Some( - PartitionSpec { - strategy: "range", - part_params: [ - Node { - node: Some( - PartitionElem( - PartitionElem { - name: "logdate", - expr: None, - collation: [], - opclass: [], - location: 167, - }, - ), - ), - }, - ], - location: 147, - }, - ), - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..175, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0034@1.snap b/crates/parser/tests/snapshots/statements/valid/0034@1.snap deleted file mode 100644 index 01d25bb1..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0034@1.snap +++ /dev/null @@ -1,210 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "select *,some_col from contact where id = '123 4 5';" ---- -Parse { - cst: SourceFile@0..52 - SelectStmt@0..52 - Select@0..6 "select" - Whitespace@6..7 " " - ResTarget@7..8 - ColumnRef@7..8 - AStar@7..8 - Ascii42@7..8 "*" - Ascii44@8..9 "," - ResTarget@9..17 - ColumnRef@9..17 - Ident@9..17 "some_col" - Whitespace@17..18 " " - From@18..22 "from" - Whitespace@22..23 " " - RangeVar@23..30 - Ident@23..30 "contact" - Whitespace@30..31 " " - Where@31..36 "where" - Whitespace@36..37 " " - AExpr@37..51 - ColumnRef@37..39 - Ident@37..39 "id" - Whitespace@39..40 " " - Ascii61@40..41 "=" - Whitespace@41..42 " " - AConst@42..51 - Sconst@42..51 "'123 4 5'" - Ascii59@51..52 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "some_col", - }, - ), - ), - }, - ], - location: 9, - }, - ), - ), - }, - ), - location: 9, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "contact", - inh: true, - relpersistence: "p", - alias: None, - location: 23, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "id", - }, - ), - ), - }, - ], - location: 37, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 42, - val: Some( - Sval( - String { - sval: "123 4 5", - }, - ), - ), - }, - ), - ), - }, - ), - location: 40, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..51, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0035@1.snap b/crates/parser/tests/snapshots/statements/valid/0035@1.snap deleted file mode 100644 index 01d25bb1..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0035@1.snap +++ /dev/null @@ -1,210 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "select *,some_col from contact where id = '123 4 5';" ---- -Parse { - cst: SourceFile@0..52 - SelectStmt@0..52 - Select@0..6 "select" - Whitespace@6..7 " " - ResTarget@7..8 - ColumnRef@7..8 - AStar@7..8 - Ascii42@7..8 "*" - Ascii44@8..9 "," - ResTarget@9..17 - ColumnRef@9..17 - Ident@9..17 "some_col" - Whitespace@17..18 " " - From@18..22 "from" - Whitespace@22..23 " " - RangeVar@23..30 - Ident@23..30 "contact" - Whitespace@30..31 " " - Where@31..36 "where" - Whitespace@36..37 " " - AExpr@37..51 - ColumnRef@37..39 - Ident@37..39 "id" - Whitespace@39..40 " " - Ascii61@40..41 "=" - Whitespace@41..42 " " - AConst@42..51 - Sconst@42..51 "'123 4 5'" - Ascii59@51..52 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "some_col", - }, - ), - ), - }, - ], - location: 9, - }, - ), - ), - }, - ), - location: 9, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "contact", - inh: true, - relpersistence: "p", - alias: None, - location: 23, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "id", - }, - ), - ), - }, - ], - location: 37, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 42, - val: Some( - Sval( - String { - sval: "123 4 5", - }, - ), - ), - }, - ), - ), - }, - ), - location: 40, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..51, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0036@1.snap b/crates/parser/tests/snapshots/statements/valid/0036@1.snap deleted file mode 100644 index 62999c01..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0036@1.snap +++ /dev/null @@ -1,255 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE FUNCTION dup(in int, out f1 int, out f2 text)\n AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$\n LANGUAGE SQL;" ---- -Parse { - cst: SourceFile@0..125 - CreateFunctionStmt@0..125 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Function@7..15 "FUNCTION" - Whitespace@15..16 " " - Ident@16..19 "dup" - Ascii40@19..20 "(" - FunctionParameter@20..26 - InP@20..22 "in" - Whitespace@22..23 " " - TypeName@23..26 - IntP@23..26 "int" - Ascii44@26..27 "," - Whitespace@27..28 " " - FunctionParameter@28..38 - OutP@28..31 "out" - Whitespace@31..32 " " - Ident@32..34 "f1" - Whitespace@34..35 " " - TypeName@35..38 - IntP@35..38 "int" - Ascii44@38..39 "," - Whitespace@39..40 " " - FunctionParameter@40..51 - OutP@40..43 "out" - Whitespace@43..44 " " - Ident@44..46 "f2" - Whitespace@46..47 " " - TypeName@47..51 - TextP@47..51 "text" - Ascii41@51..52 ")" - Newline@52..53 "\n" - Whitespace@53..57 " " - DefElem@57..107 - As@57..59 "AS" - Whitespace@59..60 " " - List@60..107 - Sconst@60..107 "$$ SELECT $1, CAST($1 ..." - Newline@107..108 "\n" - Whitespace@108..112 " " - DefElem@112..124 - Language@112..120 "LANGUAGE" - Whitespace@120..121 " " - SqlP@121..124 "SQL" - Ascii59@124..125 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: false, - funcname: [ - Node { - node: Some( - String( - String { - sval: "dup", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 23, - }, - ), - mode: FuncParamIn, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "f1", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 35, - }, - ), - mode: FuncParamOut, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "f2", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 47, - }, - ), - mode: FuncParamOut, - defexpr: None, - }, - ), - ), - }, - ], - return_type: None, - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: " SELECT $1, CAST($1 AS text) || ' is text' ", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 57, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 112, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..124, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0037@1.snap b/crates/parser/tests/snapshots/statements/valid/0037@1.snap deleted file mode 100644 index 3af30d52..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0037@1.snap +++ /dev/null @@ -1,79 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');" ---- -Parse { - cst: SourceFile@0..57 - CreateEnumStmt@0..57 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..22 "bug_status" - Whitespace@22..23 " " - As@23..25 "AS" - Whitespace@25..26 " " - EnumP@26..30 "ENUM" - Whitespace@30..31 " " - Ascii40@31..32 "(" - Sconst@32..37 "'new'" - Ascii44@37..38 "," - Whitespace@38..39 " " - Sconst@39..45 "'open'" - Ascii44@45..46 "," - Whitespace@46..47 " " - Sconst@47..55 "'closed'" - Ascii41@55..56 ")" - Ascii59@56..57 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateEnumStmt( - CreateEnumStmt { - type_name: [ - Node { - node: Some( - String( - String { - sval: "bug_status", - }, - ), - ), - }, - ], - vals: [ - Node { - node: Some( - String( - String { - sval: "new", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "open", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "closed", - }, - ), - ), - }, - ], - }, - ), - range: 0..56, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0038@1.snap b/crates/parser/tests/snapshots/statements/valid/0038@1.snap deleted file mode 100644 index b50617e4..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0038@1.snap +++ /dev/null @@ -1,200 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT; ---- -Parse { - cst: SourceFile@0..70 - CreateCastStmt@0..70 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Cast@7..11 "CAST" - Whitespace@11..12 " " - Ascii40@12..13 "(" - TypeName@13..19 - Bigint@13..19 "bigint" - Whitespace@19..20 " " - As@20..22 "AS" - Whitespace@22..23 " " - TypeName@23..27 - Ident@23..27 "int4" - Ascii41@27..28 ")" - Whitespace@28..29 " " - With@29..33 "WITH" - Whitespace@33..34 " " - Function@34..42 "FUNCTION" - Whitespace@42..43 " " - ObjectWithArgs@43..55 - Ident@43..47 "int4" - Ascii40@47..48 "(" - TypeName@48..54 - Bigint@48..54 "bigint" - Ascii41@54..55 ")" - Whitespace@55..56 " " - As@56..58 "AS" - Whitespace@58..59 " " - Assignment@59..69 "ASSIGNMENT" - Ascii59@69..70 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateCastStmt( - CreateCastStmt { - sourcetype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 13, - }, - ), - targettype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 23, - }, - ), - func: Some( - ObjectWithArgs { - objname: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - objargs: [ - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 48, - }, - ), - ), - }, - ], - objfuncargs: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 48, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - args_unspecified: false, - }, - ), - context: CoercionAssignment, - inout: false, - }, - ), - range: 0..69, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0038@2.snap b/crates/parser/tests/snapshots/statements/valid/0038@2.snap deleted file mode 100644 index b2939349..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0038@2.snap +++ /dev/null @@ -1,97 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE CAST (bigint AS int4) WITHOUT FUNCTION AS IMPLICIT; ---- -Parse { - cst: SourceFile@0..58 - CreateCastStmt@0..58 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Cast@7..11 "CAST" - Whitespace@11..12 " " - Ascii40@12..13 "(" - TypeName@13..19 - Bigint@13..19 "bigint" - Whitespace@19..20 " " - As@20..22 "AS" - Whitespace@22..23 " " - TypeName@23..27 - Ident@23..27 "int4" - Ascii41@27..28 ")" - Whitespace@28..29 " " - Without@29..36 "WITHOUT" - Whitespace@36..37 " " - Function@37..45 "FUNCTION" - Whitespace@45..46 " " - As@46..48 "AS" - Whitespace@48..49 " " - ImplicitP@49..57 "IMPLICIT" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateCastStmt( - CreateCastStmt { - sourcetype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 13, - }, - ), - targettype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 23, - }, - ), - func: None, - context: CoercionImplicit, - inout: false, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0038@3.snap b/crates/parser/tests/snapshots/statements/valid/0038@3.snap deleted file mode 100644 index 7deada38..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0038@3.snap +++ /dev/null @@ -1,97 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE CAST (bigint AS int4) WITH INOUT AS ASSIGNMENT; ---- -Parse { - cst: SourceFile@0..54 - CreateCastStmt@0..54 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Cast@7..11 "CAST" - Whitespace@11..12 " " - Ascii40@12..13 "(" - TypeName@13..19 - Bigint@13..19 "bigint" - Whitespace@19..20 " " - As@20..22 "AS" - Whitespace@22..23 " " - TypeName@23..27 - Ident@23..27 "int4" - Ascii41@27..28 ")" - Whitespace@28..29 " " - With@29..33 "WITH" - Whitespace@33..34 " " - Inout@34..39 "INOUT" - Whitespace@39..40 " " - As@40..42 "AS" - Whitespace@42..43 " " - Assignment@43..53 "ASSIGNMENT" - Ascii59@53..54 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateCastStmt( - CreateCastStmt { - sourcetype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 13, - }, - ), - targettype: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 23, - }, - ), - func: None, - context: CoercionAssignment, - inout: true, - }, - ), - range: 0..53, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@1.snap b/crates/parser/tests/snapshots/statements/valid/0039@1.snap deleted file mode 100644 index 2d929afa..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@1.snap +++ /dev/null @@ -1,202 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1);" ---- -Parse { - cst: SourceFile@0..68 - DefineStmt@0..68 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..27 "aggregate1" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..33 - FunctionParameter@29..33 - TypeName@29..33 - Ident@29..33 "int4" - Ascii41@33..34 ")" - Whitespace@34..35 " " - Ascii40@35..36 "(" - DefElem@36..50 - Ident@36..41 "sfunc" - Whitespace@41..42 " " - Ascii61@42..43 "=" - Whitespace@43..44 " " - TypeName@44..50 - Ident@44..50 "sfunc1" - Ascii44@50..51 "," - Whitespace@51..52 " " - DefElem@52..66 - Ident@52..57 "stype" - Whitespace@57..58 " " - Ascii61@58..59 "=" - Whitespace@59..60 " " - TypeName@60..66 - Ident@60..66 "stype1" - Ascii41@66..67 ")" - Ascii59@67..68 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "aggregate1", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 29, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 36, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 60, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 52, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..67, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@2.snap b/crates/parser/tests/snapshots/statements/valid/0039@2.snap deleted file mode 100644 index e0321af3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@2.snap +++ /dev/null @@ -1,240 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE aggregate1 (int4, bool) (sfunc = sfunc1, stype = stype1);" ---- -Parse { - cst: SourceFile@0..74 - DefineStmt@0..74 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..27 "aggregate1" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..39 - FunctionParameter@29..33 - TypeName@29..33 - Ident@29..33 "int4" - Ascii44@33..34 "," - Whitespace@34..35 " " - FunctionParameter@35..39 - TypeName@35..39 - Ident@35..39 "bool" - Ascii41@39..40 ")" - Whitespace@40..41 " " - Ascii40@41..42 "(" - DefElem@42..56 - Ident@42..47 "sfunc" - Whitespace@47..48 " " - Ascii61@48..49 "=" - Whitespace@49..50 " " - TypeName@50..56 - Ident@50..56 "sfunc1" - Ascii44@56..57 "," - Whitespace@57..58 " " - DefElem@58..72 - Ident@58..63 "stype" - Whitespace@63..64 " " - Ascii61@64..65 "=" - Whitespace@65..66 " " - TypeName@66..72 - Ident@66..72 "stype1" - Ascii41@72..73 ")" - Ascii59@73..74 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "aggregate1", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 29, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "bool", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 35, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 50, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 42, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 66, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 58, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..73, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@3.snap b/crates/parser/tests/snapshots/statements/valid/0039@3.snap deleted file mode 100644 index 5a697a73..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@3.snap +++ /dev/null @@ -1,159 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE aggregate1 (*) (sfunc = sfunc1, stype = stype1);" ---- -Parse { - cst: SourceFile@0..65 - DefineStmt@0..65 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..27 "aggregate1" - Whitespace@27..28 " " - Ascii40@28..29 "(" - Ascii42@29..30 "*" - Ascii41@30..31 ")" - Whitespace@31..32 " " - Ascii40@32..33 "(" - DefElem@33..47 - Ident@33..38 "sfunc" - Whitespace@38..39 " " - Ascii61@39..40 "=" - Whitespace@40..41 " " - TypeName@41..47 - Ident@41..47 "sfunc1" - Ascii44@47..48 "," - Whitespace@48..49 " " - DefElem@49..63 - Ident@49..54 "stype" - Whitespace@54..55 " " - Ascii61@55..56 "=" - Whitespace@56..57 " " - TypeName@57..63 - Ident@57..63 "stype1" - Ascii41@63..64 ")" - Ascii59@64..65 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "aggregate1", - }, - ), - ), - }, - ], - args: [ - Node { - node: None, - }, - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 41, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 33, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 57, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 49, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..64, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@4.snap b/crates/parser/tests/snapshots/statements/valid/0039@4.snap deleted file mode 100644 index 63b0f1db..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@4.snap +++ /dev/null @@ -1,236 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1, finalfunc_extra, mfinalfuncextra);" ---- -Parse { - cst: SourceFile@0..102 - DefineStmt@0..102 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..27 "aggregate1" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..33 - FunctionParameter@29..33 - TypeName@29..33 - Ident@29..33 "int4" - Ascii41@33..34 ")" - Whitespace@34..35 " " - Ascii40@35..36 "(" - DefElem@36..50 - Ident@36..41 "sfunc" - Whitespace@41..42 " " - Ascii61@42..43 "=" - Whitespace@43..44 " " - TypeName@44..50 - Ident@44..50 "sfunc1" - Ascii44@50..51 "," - Whitespace@51..52 " " - DefElem@52..66 - Ident@52..57 "stype" - Whitespace@57..58 " " - Ascii61@58..59 "=" - Whitespace@59..60 " " - TypeName@60..66 - Ident@60..66 "stype1" - Ascii44@66..67 "," - Whitespace@67..68 " " - DefElem@68..83 - Ident@68..83 "finalfunc_extra" - Ascii44@83..84 "," - Whitespace@84..85 " " - DefElem@85..100 - Ident@85..100 "mfinalfuncextra" - Ascii41@100..101 ")" - Ascii59@101..102 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "aggregate1", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 29, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 36, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 60, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 52, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "finalfunc_extra", - arg: None, - defaction: DefelemUnspec, - location: 68, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "mfinalfuncextra", - arg: None, - defaction: DefelemUnspec, - location: 85, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..101, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@5.snap b/crates/parser/tests/snapshots/statements/valid/0039@5.snap deleted file mode 100644 index 5a16ba96..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@5.snap +++ /dev/null @@ -1,300 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1, finalfunc_modify = read_only, parallel = restricted);" ---- -Parse { - cst: SourceFile@0..121 - DefineStmt@0..121 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..27 "aggregate1" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..33 - FunctionParameter@29..33 - TypeName@29..33 - Ident@29..33 "int4" - Ascii41@33..34 ")" - Whitespace@34..35 " " - Ascii40@35..36 "(" - DefElem@36..50 - Ident@36..41 "sfunc" - Whitespace@41..42 " " - Ascii61@42..43 "=" - Whitespace@43..44 " " - TypeName@44..50 - Ident@44..50 "sfunc1" - Ascii44@50..51 "," - Whitespace@51..52 " " - DefElem@52..66 - Ident@52..57 "stype" - Whitespace@57..58 " " - Ascii61@58..59 "=" - Whitespace@59..60 " " - TypeName@60..66 - Ident@60..66 "stype1" - Ascii44@66..67 "," - Whitespace@67..68 " " - DefElem@68..96 - Ident@68..84 "finalfunc_modify" - Whitespace@84..85 " " - Ascii61@85..86 "=" - Whitespace@86..87 " " - TypeName@87..96 - Ident@87..96 "read_only" - Ascii44@96..97 "," - Whitespace@97..98 " " - DefElem@98..119 - Parallel@98..106 "parallel" - Whitespace@106..107 " " - Ascii61@107..108 "=" - Whitespace@108..109 " " - TypeName@109..119 - Ident@109..119 "restricted" - Ascii41@119..120 ")" - Ascii59@120..121 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "aggregate1", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 29, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 36, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 60, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 52, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "finalfunc_modify", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "read_only", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 87, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 68, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "parallel", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "restricted", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 109, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 98, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..120, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@6.snap b/crates/parser/tests/snapshots/statements/valid/0039@6.snap deleted file mode 100644 index aa6d8a06..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@6.snap +++ /dev/null @@ -1,309 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement) (sfunc = ordered_set_transition, stype = internal, finalfunc = percentile_disc_final, finalfunc_extra);" ---- -Parse { - cst: SourceFile@0..165 - DefineStmt@0..165 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..32 "percentile_disc" - Whitespace@32..33 " " - Ascii40@33..34 "(" - List@34..60 - FunctionParameter@34..40 - TypeName@34..40 - Ident@34..40 "float8" - Whitespace@40..41 " " - Order@41..46 "ORDER" - Whitespace@46..47 " " - By@47..49 "BY" - Whitespace@49..50 " " - FunctionParameter@50..60 - TypeName@50..60 - Ident@50..60 "anyelement" - Ascii41@60..61 ")" - Whitespace@61..62 " " - Ascii40@62..63 "(" - DefElem@63..93 - Ident@63..68 "sfunc" - Whitespace@68..69 " " - Ascii61@69..70 "=" - Whitespace@70..71 " " - TypeName@71..93 - Ident@71..93 "ordered_set_transition" - Ascii44@93..94 "," - Whitespace@94..95 " " - DefElem@95..111 - Ident@95..100 "stype" - Whitespace@100..101 " " - Ascii61@101..102 "=" - Whitespace@102..103 " " - TypeName@103..111 - Ident@103..111 "internal" - Ascii44@111..112 "," - Whitespace@112..113 " " - DefElem@113..146 - Ident@113..122 "finalfunc" - Whitespace@122..123 " " - Ascii61@123..124 "=" - Whitespace@124..125 " " - TypeName@125..146 - Ident@125..146 "percentile_disc_final" - Ascii44@146..147 "," - Whitespace@147..148 " " - DefElem@148..163 - Ident@148..163 "finalfunc_extra" - Ascii41@163..164 ")" - Ascii59@164..165 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "percentile_disc", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "float8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "anyelement", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 50, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: 1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "ordered_set_transition", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 71, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 63, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 103, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 95, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "finalfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "percentile_disc_final", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 125, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 113, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "finalfunc_extra", - arg: None, - defaction: DefelemUnspec, - location: 148, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..164, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0039@7.snap b/crates/parser/tests/snapshots/statements/valid/0039@7.snap deleted file mode 100644 index d0fe38a5..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0039@7.snap +++ /dev/null @@ -1,281 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE AGGREGATE custom_aggregate (float8 ORDER BY column1, column2) (sfunc = sfunc1, stype = stype1);" ---- -Parse { - cst: SourceFile@0..102 - DefineStmt@0..102 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Aggregate@7..16 "AGGREGATE" - Whitespace@16..17 " " - Ident@17..33 "custom_aggregate" - Whitespace@33..34 " " - Ascii40@34..35 "(" - List@35..67 - FunctionParameter@35..41 - TypeName@35..41 - Ident@35..41 "float8" - Whitespace@41..42 " " - Order@42..47 "ORDER" - Whitespace@47..48 " " - By@48..50 "BY" - Whitespace@50..51 " " - FunctionParameter@51..58 - TypeName@51..58 - Ident@51..58 "column1" - Ascii44@58..59 "," - Whitespace@59..60 " " - FunctionParameter@60..67 - TypeName@60..67 - Ident@60..67 "column2" - Ascii41@67..68 ")" - Whitespace@68..69 " " - Ascii40@69..70 "(" - DefElem@70..84 - Ident@70..75 "sfunc" - Whitespace@75..76 " " - Ascii61@76..77 "=" - Whitespace@77..78 " " - TypeName@78..84 - Ident@78..84 "sfunc1" - Ascii44@84..85 "," - Whitespace@85..86 " " - DefElem@86..100 - Ident@86..91 "stype" - Whitespace@91..92 " " - Ascii61@92..93 "=" - Whitespace@93..94 " " - TypeName@94..100 - Ident@94..100 "stype1" - Ascii41@100..101 ")" - Ascii59@101..102 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectAggregate, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "custom_aggregate", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "float8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 35, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "column1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 51, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "column2", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 60, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - }, - ), - ), - }, - Node { - node: Some( - Integer( - Integer { - ival: 1, - }, - ), - ), - }, - ], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "sfunc", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "sfunc1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 78, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 70, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "stype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "stype1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 94, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 86, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..101, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@1.snap b/crates/parser/tests/snapshots/statements/valid/0040@1.snap deleted file mode 100644 index ed782c0b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@1.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql;" ---- -Parse { - cst: SourceFile@0..113 - CreateFunctionStmt@0..113 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Function@7..15 "FUNCTION" - Whitespace@15..16 " " - Ident@16..22 "getfoo" - Ascii40@22..23 "(" - FunctionParameter@23..26 - TypeName@23..26 - IntP@23..26 "int" - Ascii41@26..27 ")" - Whitespace@27..28 " " - Returns@28..35 "RETURNS" - Whitespace@35..36 " " - Setof@36..41 "SETOF" - Whitespace@41..42 " " - TypeName@42..47 - Ident@42..47 "users" - Whitespace@47..48 " " - DefElem@48..99 - As@48..50 "AS" - Whitespace@50..51 " " - List@51..99 - Sconst@51..99 "$$SELECT * FROM \\\"use ..." - Whitespace@99..100 " " - DefElem@100..112 - Language@100..108 "LANGUAGE" - Whitespace@108..109 " " - SqlP@109..112 "sql" - Ascii59@112..113 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: false, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 23, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 42, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 48, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 100, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..112, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@2.snap b/crates/parser/tests/snapshots/statements/valid/0040@2.snap deleted file mode 100644 index a1e51fc8..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@2.snap +++ /dev/null @@ -1,190 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql;" ---- -Parse { - cst: SourceFile@0..124 - CreateFunctionStmt@0..124 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - FunctionParameter@34..37 - TypeName@34..37 - IntP@34..37 "int" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Returns@39..46 "RETURNS" - Whitespace@46..47 " " - Setof@47..52 "SETOF" - Whitespace@52..53 " " - TypeName@53..58 - Ident@53..58 "users" - Whitespace@58..59 " " - DefElem@59..110 - As@59..61 "AS" - Whitespace@61..62 " " - List@62..110 - Sconst@62..110 "$$SELECT * FROM \\\"use ..." - Whitespace@110..111 " " - DefElem@111..123 - Language@111..119 "LANGUAGE" - Whitespace@119..120 " " - SqlP@120..123 "sql" - Ascii59@123..124 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 53, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 59, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 111, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..123, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@3.snap b/crates/parser/tests/snapshots/statements/valid/0040@3.snap deleted file mode 100644 index d39c658a..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@3.snap +++ /dev/null @@ -1,216 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE;" ---- -Parse { - cst: SourceFile@0..134 - CreateFunctionStmt@0..134 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - FunctionParameter@34..37 - TypeName@34..37 - IntP@34..37 "int" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Returns@39..46 "RETURNS" - Whitespace@46..47 " " - Setof@47..52 "SETOF" - Whitespace@52..53 " " - TypeName@53..58 - Ident@53..58 "users" - Whitespace@58..59 " " - DefElem@59..110 - As@59..61 "AS" - Whitespace@61..62 " " - List@62..110 - Sconst@62..110 "$$SELECT * FROM \\\"use ..." - Whitespace@110..111 " " - DefElem@111..123 - Language@111..119 "LANGUAGE" - Whitespace@119..120 " " - SqlP@120..123 "sql" - Whitespace@123..124 " " - DefElem@124..133 - Immutable@124..133 "IMMUTABLE" - Ascii59@133..134 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 53, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 59, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 111, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 124, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..133, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@4.snap b/crates/parser/tests/snapshots/statements/valid/0040@4.snap deleted file mode 100644 index 6d89ee01..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@4.snap +++ /dev/null @@ -1,242 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE STRICT;" ---- -Parse { - cst: SourceFile@0..141 - CreateFunctionStmt@0..141 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - FunctionParameter@34..37 - TypeName@34..37 - IntP@34..37 "int" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Returns@39..46 "RETURNS" - Whitespace@46..47 " " - Setof@47..52 "SETOF" - Whitespace@52..53 " " - TypeName@53..58 - Ident@53..58 "users" - Whitespace@58..59 " " - DefElem@59..110 - As@59..61 "AS" - Whitespace@61..62 " " - List@62..110 - Sconst@62..110 "$$SELECT * FROM \\\"use ..." - Whitespace@110..111 " " - DefElem@111..123 - Language@111..119 "LANGUAGE" - Whitespace@119..120 " " - SqlP@120..123 "sql" - Whitespace@123..124 " " - DefElem@124..133 - Immutable@124..133 "IMMUTABLE" - Whitespace@133..134 " " - DefElem@134..140 - StrictP@134..140 "STRICT" - Ascii59@140..141 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 53, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 59, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 111, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 124, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "strict", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: true, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 134, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..140, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@5.snap b/crates/parser/tests/snapshots/statements/valid/0040@5.snap deleted file mode 100644 index 275f2fc9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@5.snap +++ /dev/null @@ -1,250 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE RETURNS NULL ON NULL INPUT;" ---- -Parse { - cst: SourceFile@0..161 - CreateFunctionStmt@0..161 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - FunctionParameter@34..37 - TypeName@34..37 - IntP@34..37 "int" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Returns@39..46 "RETURNS" - Whitespace@46..47 " " - Setof@47..52 "SETOF" - Whitespace@52..53 " " - TypeName@53..58 - Ident@53..58 "users" - Whitespace@58..59 " " - DefElem@59..110 - As@59..61 "AS" - Whitespace@61..62 " " - List@62..110 - Sconst@62..110 "$$SELECT * FROM \\\"use ..." - Whitespace@110..111 " " - DefElem@111..123 - Language@111..119 "LANGUAGE" - Whitespace@119..120 " " - SqlP@120..123 "sql" - Whitespace@123..124 " " - DefElem@124..133 - Immutable@124..133 "IMMUTABLE" - Whitespace@133..134 " " - DefElem@134..141 - Returns@134..141 "RETURNS" - Whitespace@141..142 " " - NullP@142..146 "NULL" - Whitespace@146..147 " " - On@147..149 "ON" - Whitespace@149..150 " " - NullP@150..154 "NULL" - Whitespace@154..155 " " - InputP@155..160 "INPUT" - Ascii59@160..161 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 53, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 59, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 111, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 124, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "strict", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: true, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 134, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..160, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@6.snap b/crates/parser/tests/snapshots/statements/valid/0040@6.snap deleted file mode 100644 index 296f9dde..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@6.snap +++ /dev/null @@ -1,248 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT;" ---- -Parse { - cst: SourceFile@0..155 - CreateFunctionStmt@0..155 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - FunctionParameter@34..37 - TypeName@34..37 - IntP@34..37 "int" - Ascii41@37..38 ")" - Whitespace@38..39 " " - Returns@39..46 "RETURNS" - Whitespace@46..47 " " - Setof@47..52 "SETOF" - Whitespace@52..53 " " - TypeName@53..58 - Ident@53..58 "users" - Whitespace@58..59 " " - DefElem@59..110 - As@59..61 "AS" - Whitespace@61..62 " " - List@62..110 - Sconst@62..110 "$$SELECT * FROM \\\"use ..." - Whitespace@110..111 " " - DefElem@111..123 - Language@111..119 "LANGUAGE" - Whitespace@119..120 " " - SqlP@120..123 "sql" - Whitespace@123..124 " " - DefElem@124..133 - Immutable@124..133 "IMMUTABLE" - Whitespace@133..134 " " - DefElem@134..140 - Called@134..140 "CALLED" - Whitespace@140..141 " " - On@141..143 "ON" - Whitespace@143..144 " " - NullP@144..148 "NULL" - Whitespace@148..149 " " - InputP@149..154 "INPUT" - Ascii59@154..155 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 34, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "users", - }, - ), - ), - }, - ], - type_oid: 0, - setof: true, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 53, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT * FROM \\\"users\\\" WHERE users.id = $1;", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 59, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 111, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 124, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "strict", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: false, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 134, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..154, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0040@7.snap b/crates/parser/tests/snapshots/statements/valid/0040@7.snap deleted file mode 100644 index ca41f566..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0040@7.snap +++ /dev/null @@ -1,200 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE FUNCTION getfoo() RETURNS text AS $$SELECT name FROM \\\"users\\\" LIMIT 1$$ LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT;" ---- -Parse { - cst: SourceFile@0..135 - CreateFunctionStmt@0..135 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Function@18..26 "FUNCTION" - Whitespace@26..27 " " - Ident@27..33 "getfoo" - Ascii40@33..34 "(" - Ascii41@34..35 ")" - Whitespace@35..36 " " - Returns@36..43 "RETURNS" - Whitespace@43..44 " " - TypeName@44..48 - TextP@44..48 "text" - Whitespace@48..49 " " - DefElem@49..90 - As@49..51 "AS" - Whitespace@51..52 " " - List@52..90 - Sconst@52..90 "$$SELECT name FROM \\\" ..." - Whitespace@90..91 " " - DefElem@91..103 - Language@91..99 "LANGUAGE" - Whitespace@99..100 " " - SqlP@100..103 "sql" - Whitespace@103..104 " " - DefElem@104..113 - Immutable@104..113 "IMMUTABLE" - Whitespace@113..114 " " - DefElem@114..120 - Called@114..120 "CALLED" - Whitespace@120..121 " " - On@121..123 "ON" - Whitespace@123..124 " " - NullP@124..128 "NULL" - Whitespace@128..129 " " - InputP@129..134 "INPUT" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateFunctionStmt( - CreateFunctionStmt { - is_procedure: false, - replace: true, - funcname: [ - Node { - node: Some( - String( - String { - sval: "getfoo", - }, - ), - ), - }, - ], - parameters: [], - return_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "as", - arg: Some( - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - String( - String { - sval: "SELECT name FROM \\\"users\\\" LIMIT 1", - }, - ), - ), - }, - ], - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 49, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "language", - arg: Some( - Node { - node: Some( - String( - String { - sval: "sql", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 91, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "volatility", - arg: Some( - Node { - node: Some( - String( - String { - sval: "immutable", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 104, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "strict", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: false, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 114, - }, - ), - ), - }, - ], - sql_body: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0041@1.snap b/crates/parser/tests/snapshots/statements/valid/0041@1.snap deleted file mode 100644 index c09e3aec..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0041@1.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE SCHEMA myschema; ---- -Parse { - cst: SourceFile@0..23 - CreateSchemaStmt@0..23 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Schema@7..13 "SCHEMA" - Whitespace@13..14 " " - Ident@14..22 "myschema" - Ascii59@22..23 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateSchemaStmt( - CreateSchemaStmt { - schemaname: "myschema", - authrole: None, - schema_elts: [], - if_not_exists: false, - }, - ), - range: 0..22, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0041@2.snap b/crates/parser/tests/snapshots/statements/valid/0041@2.snap deleted file mode 100644 index 3893d4bd..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0041@2.snap +++ /dev/null @@ -1,38 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE SCHEMA AUTHORIZATION joe; ---- -Parse { - cst: SourceFile@0..32 - CreateSchemaStmt@0..32 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Schema@7..13 "SCHEMA" - Whitespace@13..14 " " - Authorization@14..27 "AUTHORIZATION" - Whitespace@27..28 " " - RoleSpec@28..31 - Ident@28..31 "joe" - Ascii59@31..32 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateSchemaStmt( - CreateSchemaStmt { - schemaname: "", - authrole: Some( - RoleSpec { - roletype: RolespecCstring, - rolename: "joe", - location: 28, - }, - ), - schema_elts: [], - if_not_exists: false, - }, - ), - range: 0..31, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0041@3.snap b/crates/parser/tests/snapshots/statements/valid/0041@3.snap deleted file mode 100644 index 3c83312e..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0041@3.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe; ---- -Parse { - cst: SourceFile@0..51 - CreateSchemaStmt@0..51 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Schema@7..13 "SCHEMA" - Whitespace@13..14 " " - IfP@14..16 "IF" - Whitespace@16..17 " " - Not@17..20 "NOT" - Whitespace@20..21 " " - Exists@21..27 "EXISTS" - Whitespace@27..28 " " - Ident@28..32 "test" - Whitespace@32..33 " " - Authorization@33..46 "AUTHORIZATION" - Whitespace@46..47 " " - RoleSpec@47..50 - Ident@47..50 "joe" - Ascii59@50..51 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateSchemaStmt( - CreateSchemaStmt { - schemaname: "test", - authrole: Some( - RoleSpec { - roletype: RolespecCstring, - rolename: "joe", - location: 47, - }, - ), - schema_elts: [], - if_not_exists: true, - }, - ), - range: 0..50, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0041@4.snap b/crates/parser/tests/snapshots/statements/valid/0041@4.snap deleted file mode 100644 index 1fc76ac3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0041@4.snap +++ /dev/null @@ -1,458 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE SCHEMA hollywood CREATE TABLE films (title text, release date, awards text[]) CREATE VIEW winners AS SELECT title, release FROM films WHERE awards IS NOT NULL;" ---- -Parse { - cst: SourceFile@0..164 - CreateSchemaStmt@0..23 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Schema@7..13 "SCHEMA" - Whitespace@13..14 " " - Ident@14..23 "hollywood" - CreateStmt@23..83 - Create@23..29 "CREATE" - Whitespace@29..30 " " - Table@30..35 "TABLE" - Whitespace@35..36 " " - RangeVar@36..41 - Ident@36..41 "films" - Whitespace@41..42 " " - Ascii40@42..43 "(" - ColumnDef@43..53 - Ident@43..48 "title" - Whitespace@48..49 " " - TypeName@49..53 - TextP@49..53 "text" - Ascii44@53..54 "," - Whitespace@54..55 " " - ColumnDef@55..67 - Release@55..62 "release" - Whitespace@62..63 " " - TypeName@63..67 - Ident@63..67 "date" - Ascii44@67..68 "," - Whitespace@68..69 " " - ColumnDef@69..80 - Ident@69..75 "awards" - Whitespace@75..76 " " - TypeName@76..80 - TextP@76..80 "text" - Ascii91@80..81 "[" - Ascii93@81..82 "]" - Ascii41@82..83 ")" - ViewStmt@83..164 - Create@83..89 "CREATE" - Whitespace@89..90 " " - View@90..94 "VIEW" - Whitespace@94..95 " " - RangeVar@95..102 - Ident@95..102 "winners" - Whitespace@102..103 " " - As@103..105 "AS" - Whitespace@105..106 " " - SelectStmt@106..163 - Select@106..112 "SELECT" - Whitespace@112..113 " " - ResTarget@113..118 - ColumnRef@113..118 - Ident@113..118 "title" - Ascii44@118..119 "," - Whitespace@119..120 " " - ResTarget@120..127 - ColumnRef@120..127 - Release@120..127 "release" - Whitespace@127..128 " " - From@128..132 "FROM" - Whitespace@132..133 " " - RangeVar@133..138 - Ident@133..138 "films" - Whitespace@138..139 " " - Where@139..144 "WHERE" - Whitespace@144..145 " " - NullTest@145..163 - ColumnRef@145..151 - Ident@145..151 "awards" - Whitespace@151..152 " " - Is@152..154 "IS" - Whitespace@154..155 " " - Not@155..158 "NOT" - Whitespace@158..159 " " - NullP@159..163 "NULL" - Ascii59@163..164 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 23..23, - ), - SyntaxError( - "Expected Ascii59, found Whitespace", - 84..84, - ), - ], - stmts: [ - RawStmt { - stmt: CreateSchemaStmt( - CreateSchemaStmt { - schemaname: "hollywood", - authrole: None, - schema_elts: [], - if_not_exists: false, - }, - ), - range: 0..23, - }, - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "title", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 26, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 20, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "release", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "date", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 40, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 32, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "awards", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [ - Node { - node: Some( - Integer( - Integer { - ival: -1, - }, - ), - ), - }, - ], - location: 53, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 46, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 23..84, - }, - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "winners", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - aliases: [], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "title", - }, - ), - ), - }, - ], - location: 30, - }, - ), - ), - }, - ), - location: 30, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "release", - }, - ), - ), - }, - ], - location: 37, - }, - ), - ), - }, - ), - location: 37, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 50, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - NullTest( - NullTest { - xpr: None, - arg: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "awards", - }, - ), - ), - }, - ], - location: 62, - }, - ), - ), - }, - ), - nulltesttype: IsNotNull, - argisrow: false, - location: 69, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: NoCheckOption, - }, - ), - range: 84..165, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0042@1.snap b/crates/parser/tests/snapshots/statements/valid/0042@1.snap deleted file mode 100644 index a7e9c50d..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0042@1.snap +++ /dev/null @@ -1,267 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE DOMAIN us_postal_code AS TEXT CHECK(VALUE ~ '^\\d{5}$' OR VALUE ~ '^\\d{5}-\\d{4}$');" ---- -Parse { - cst: SourceFile@0..89 - CreateDomainStmt@0..89 - Create@0..6 "CREATE" - Whitespace@6..7 " " - DomainP@7..13 "DOMAIN" - Whitespace@13..14 " " - Ident@14..28 "us_postal_code" - Whitespace@28..29 " " - As@29..31 "AS" - Whitespace@31..32 " " - TypeName@32..36 - TextP@32..36 "TEXT" - Whitespace@36..37 " " - Constraint@37..87 - Check@37..42 "CHECK" - Ascii40@42..43 "(" - BoolExpr@43..87 - AExpr@43..60 - ColumnRef@43..48 - ValueP@43..48 "VALUE" - Whitespace@48..49 " " - Op@49..50 "~" - Whitespace@50..51 " " - AConst@51..60 - Sconst@51..60 "'^\\d{5}$'" - Whitespace@60..61 " " - Or@61..63 "OR" - Whitespace@63..64 " " - AExpr@64..87 - ColumnRef@64..69 - ValueP@64..69 "VALUE" - Whitespace@69..70 " " - Op@70..71 "~" - Whitespace@71..72 " " - AConst@72..87 - Sconst@72..87 "'^\\d{5}-\\d{4}$'" - Ascii41@87..88 ")" - Ascii59@88..89 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateDomainStmt( - CreateDomainStmt { - domainname: [ - Node { - node: Some( - String( - String { - sval: "us_postal_code", - }, - ), - ), - }, - ], - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 32, - }, - ), - coll_clause: None, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrCheck, - conname: "", - deferrable: false, - initdeferred: false, - location: 37, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - BoolExpr( - BoolExpr { - xpr: None, - boolop: OrExpr, - args: [ - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "~", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "value", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 51, - val: Some( - Sval( - String { - sval: "^\\d{5}$", - }, - ), - ), - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "~", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "value", - }, - ), - ), - }, - ], - location: 64, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 72, - val: Some( - Sval( - String { - sval: "^\\d{5}-\\d{4}$", - }, - ), - ), - }, - ), - ), - }, - ), - location: 70, - }, - ), - ), - }, - ], - location: 61, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: true, - }, - ), - ), - }, - ], - }, - ), - range: 0..88, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@1.snap b/crates/parser/tests/snapshots/statements/valid/0043@1.snap deleted file mode 100644 index 8723aab6..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@1.snap +++ /dev/null @@ -1,412 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE UNLOGGED TABLE cities (name text, population real, altitude double, identifier smallint, postal_code int, foreign_id bigint);" ---- -Parse { - cst: SourceFile@0..132 - CreateStmt@0..132 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Unlogged@7..15 "UNLOGGED" - Whitespace@15..16 " " - Table@16..21 "TABLE" - Whitespace@21..22 " " - RangeVar@22..28 - Ident@22..28 "cities" - Whitespace@28..29 " " - Ascii40@29..30 "(" - ColumnDef@30..39 - NameP@30..34 "name" - Whitespace@34..35 " " - TypeName@35..39 - TextP@35..39 "text" - Ascii44@39..40 "," - Whitespace@40..41 " " - ColumnDef@41..56 - Ident@41..51 "population" - Whitespace@51..52 " " - TypeName@52..56 - Real@52..56 "real" - Ascii44@56..57 "," - Whitespace@57..58 " " - ColumnDef@58..73 - Ident@58..66 "altitude" - Whitespace@66..67 " " - TypeName@67..73 - DoubleP@67..73 "double" - Ascii44@73..74 "," - Whitespace@74..75 " " - ColumnDef@75..94 - Ident@75..85 "identifier" - Whitespace@85..86 " " - TypeName@86..94 - Smallint@86..94 "smallint" - Ascii44@94..95 "," - Whitespace@95..96 " " - ColumnDef@96..111 - Ident@96..107 "postal_code" - Whitespace@107..108 " " - TypeName@108..111 - IntP@108..111 "int" - Ascii44@111..112 "," - Whitespace@112..113 " " - ColumnDef@113..130 - Ident@113..123 "foreign_id" - Whitespace@123..124 " " - TypeName@124..130 - Bigint@124..130 "bigint" - Ascii41@130..131 ")" - Ascii59@131..132 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "u", - alias: None, - location: 22, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "text", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 35, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 30, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "population", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "float4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 52, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 41, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "altitude", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "double", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 67, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 58, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "identifier", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int2", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 86, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 75, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "postal_code", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 108, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 96, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "foreign_id", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int8", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 124, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 113, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..131, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@10.snap b/crates/parser/tests/snapshots/statements/valid/0043@10.snap deleted file mode 100644 index e1da7400..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@10.snap +++ /dev/null @@ -1,82 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TABLE like_constraint_rename_cache (LIKE constraint_rename_cache INCLUDING ALL); ---- -Parse { - cst: SourceFile@0..87 - CreateStmt@0..87 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..41 - Ident@13..41 "like_constraint_renam ..." - Whitespace@41..42 " " - Ascii40@42..43 "(" - TableLikeClause@43..85 - Like@43..47 "LIKE" - Whitespace@47..48 " " - RangeVar@48..71 - Ident@48..71 "constraint_rename_cache" - Whitespace@71..72 " " - Including@72..81 "INCLUDING" - Whitespace@81..82 " " - All@82..85 "ALL" - Ascii41@85..86 ")" - Ascii59@86..87 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "like_constraint_rename_cache", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - TableLikeClause( - TableLikeClause { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "constraint_rename_cache", - inh: true, - relpersistence: "p", - alias: None, - location: 48, - }, - ), - options: 2147483647, - relation_oid: 0, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..86, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@11.snap b/crates/parser/tests/snapshots/statements/valid/0043@11.snap deleted file mode 100644 index 148fd2ac..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@11.snap +++ /dev/null @@ -1,320 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE distributors (did int, name varchar(40), UNIQUE (name) WITH (fillfactor=70)) WITH (fillfactor=70);" ---- -Parse { - cst: SourceFile@0..111 - CreateStmt@0..111 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..25 - Ident@13..25 "distributors" - Whitespace@25..26 " " - Ascii40@26..27 "(" - ColumnDef@27..34 - Ident@27..30 "did" - Whitespace@30..31 " " - TypeName@31..34 - IntP@31..34 "int" - Ascii44@34..35 "," - Whitespace@35..36 " " - ColumnDef@36..51 - NameP@36..40 "name" - Whitespace@40..41 " " - TypeName@41..51 - Varchar@41..48 "varchar" - Ascii40@48..49 "(" - AConst@49..51 - Iconst@49..51 "40" - Ascii41@51..52 ")" - Ascii44@52..53 "," - Whitespace@53..54 " " - Constraint@54..87 - Unique@54..60 "UNIQUE" - Whitespace@60..61 " " - Ascii40@61..62 "(" - NameP@62..66 "name" - Ascii41@66..67 ")" - Whitespace@67..68 " " - With@68..72 "WITH" - Whitespace@72..73 " " - Ascii40@73..74 "(" - DefElem@74..87 - Ident@74..84 "fillfactor" - Ascii61@84..85 "=" - Iconst@85..87 "70" - Ascii41@87..88 ")" - Ascii41@88..89 ")" - Whitespace@89..90 " " - With@90..94 "WITH" - Whitespace@94..95 " " - Ascii40@95..96 "(" - DefElem@96..109 - Ident@96..106 "fillfactor" - Ascii61@106..107 "=" - Iconst@107..109 "70" - Ascii41@109..110 ")" - Ascii59@110..111 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "distributors", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "did", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 31, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 27, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "varchar", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 49, - val: Some( - Ival( - Integer { - ival: 40, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 41, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 36, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrUnique, - conname: "", - deferrable: false, - initdeferred: false, - location: 54, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - ], - including: [], - exclusions: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "fillfactor", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 70, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 74, - }, - ), - ), - }, - ], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "fillfactor", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 70, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 96, - }, - ), - ), - }, - ], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..110, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@2.snap b/crates/parser/tests/snapshots/statements/valid/0043@2.snap deleted file mode 100644 index 7eb40dcf..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@2.snap +++ /dev/null @@ -1,1123 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE IF NOT EXISTS distributors (name varchar(40) DEFAULT 'Luso Films', len interval hour to second(3), name varchar(40) DEFAULT 'Luso Films', did int DEFAULT nextval('distributors_serial'), stamp timestamp DEFAULT now() NOT NULL, stamptz timestamp with time zone, \"time\" time NOT NULL, timetz time with time zone, CONSTRAINT name_len PRIMARY KEY (name, len));" ---- -Parse { - cst: SourceFile@0..368 - CreateStmt@0..368 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - IfP@13..15 "IF" - Whitespace@15..16 " " - Not@16..19 "NOT" - Whitespace@19..20 " " - Exists@20..26 "EXISTS" - Whitespace@26..27 " " - RangeVar@27..39 - Ident@27..39 "distributors" - Whitespace@39..40 " " - Ascii40@40..41 "(" - ColumnDef@41..78 - NameP@41..45 "name" - Whitespace@45..46 " " - TypeName@46..56 - Varchar@46..53 "varchar" - Ascii40@53..54 "(" - AConst@54..56 - Iconst@54..56 "40" - Ascii41@56..57 ")" - Whitespace@57..58 " " - Constraint@58..78 - Default@58..65 "DEFAULT" - Whitespace@65..66 " " - AConst@66..78 - Sconst@66..78 "'Luso Films'" - Ascii44@78..79 "," - Whitespace@79..80 " " - ColumnDef@80..109 - Ident@80..83 "len" - Whitespace@83..84 " " - TypeName@84..109 - Interval@84..92 "interval" - Whitespace@92..93 " " - AConst@93..97 - HourP@93..97 "hour" - Whitespace@97..98 " " - To@98..100 "to" - Whitespace@100..101 " " - SecondP@101..107 "second" - Ascii40@107..108 "(" - AConst@108..109 - Iconst@108..109 "3" - Ascii41@109..110 ")" - Ascii44@110..111 "," - Whitespace@111..112 " " - ColumnDef@112..149 - NameP@112..116 "name" - Whitespace@116..117 " " - TypeName@117..127 - Varchar@117..124 "varchar" - Ascii40@124..125 "(" - AConst@125..127 - Iconst@125..127 "40" - Ascii41@127..128 ")" - Whitespace@128..129 " " - Constraint@129..149 - Default@129..136 "DEFAULT" - Whitespace@136..137 " " - AConst@137..149 - Sconst@137..149 "'Luso Films'" - Ascii44@149..150 "," - Whitespace@150..151 " " - ColumnDef@151..196 - Ident@151..154 "did" - Whitespace@154..155 " " - TypeName@155..158 - IntP@155..158 "int" - Whitespace@158..159 " " - Constraint@159..196 - Default@159..166 "DEFAULT" - Whitespace@166..167 " " - FuncCall@167..196 - Ident@167..174 "nextval" - Ascii40@174..175 "(" - AConst@175..196 - Sconst@175..196 "'distributors_serial'" - Ascii41@196..197 ")" - Ascii44@197..198 "," - Whitespace@198..199 " " - ColumnDef@199..237 - Ident@199..204 "stamp" - Whitespace@204..205 " " - TypeName@205..214 - Timestamp@205..214 "timestamp" - Whitespace@214..215 " " - Constraint@215..226 - Default@215..222 "DEFAULT" - Whitespace@222..223 " " - FuncCall@223..226 - Ident@223..226 "now" - Ascii40@226..227 "(" - Ascii41@227..228 ")" - Whitespace@228..229 " " - Constraint@229..237 - Not@229..232 "NOT" - Whitespace@232..233 " " - NullP@233..237 "NULL" - Ascii44@237..238 "," - Whitespace@238..239 " " - ColumnDef@239..271 - Ident@239..246 "stamptz" - Whitespace@246..247 " " - TypeName@247..271 - Timestamp@247..256 "timestamp" - Whitespace@256..257 " " - With@257..261 "with" - Whitespace@261..262 " " - Time@262..266 "time" - Whitespace@266..267 " " - Zone@267..271 "zone" - Ascii44@271..272 "," - Whitespace@272..273 " " - ColumnDef@273..293 - Ident@273..279 "\"time\"" - Whitespace@279..280 " " - TypeName@280..284 - Time@280..284 "time" - Whitespace@284..285 " " - Constraint@285..293 - Not@285..288 "NOT" - Whitespace@288..289 " " - NullP@289..293 "NULL" - Ascii44@293..294 "," - Whitespace@294..295 " " - ColumnDef@295..321 - Ident@295..301 "timetz" - Whitespace@301..302 " " - TypeName@302..321 - Time@302..306 "time" - Whitespace@306..307 " " - With@307..311 "with" - Whitespace@311..312 " " - Time@312..316 "time" - Whitespace@316..317 " " - Zone@317..321 "zone" - Ascii44@321..322 "," - Whitespace@322..323 " " - Constraint@323..365 - Constraint@323..333 "CONSTRAINT" - Whitespace@333..334 " " - Ident@334..342 "name_len" - Whitespace@342..343 " " - Primary@343..350 "PRIMARY" - Whitespace@350..351 " " - Key@351..354 "KEY" - Whitespace@354..355 " " - Ascii40@355..356 "(" - NameP@356..360 "name" - Ascii44@360..361 "," - Whitespace@361..362 " " - Ident@362..365 "len" - Ascii41@365..366 ")" - Ascii41@366..367 ")" - Ascii59@367..368 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "distributors", - inh: true, - relpersistence: "p", - alias: None, - location: 27, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "varchar", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 54, - val: Some( - Ival( - Integer { - ival: 40, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 46, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 58, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 66, - val: Some( - Sval( - String { - sval: "Luso Films", - }, - ), - ), - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 41, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "len", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "interval", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 93, - val: Some( - Ival( - Integer { - ival: 7168, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 108, - val: Some( - Ival( - Integer { - ival: 3, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 84, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 80, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "name", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "varchar", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 125, - val: Some( - Ival( - Integer { - ival: 40, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 117, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 129, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 137, - val: Some( - Sval( - String { - sval: "Luso Films", - }, - ), - ), - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 112, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "did", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 155, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 159, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "nextval", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 175, - val: Some( - Sval( - String { - sval: "distributors_serial", - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 167, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 151, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "stamp", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "timestamp", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 205, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 215, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "now", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 223, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrNotnull, - conname: "", - deferrable: false, - initdeferred: false, - location: 229, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 199, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "stamptz", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "timestamptz", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 247, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 239, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "time", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "time", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 280, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrNotnull, - conname: "", - deferrable: false, - initdeferred: false, - location: 285, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 273, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "timetz", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "timetz", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 302, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 295, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrPrimary, - conname: "name_len", - deferrable: false, - initdeferred: false, - location: 323, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [ - Node { - node: Some( - String( - String { - sval: "name", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "len", - }, - ), - ), - }, - ], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: true, - }, - ), - range: 0..367, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@3.snap b/crates/parser/tests/snapshots/statements/valid/0043@3.snap deleted file mode 100644 index 62d6038f..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@3.snap +++ /dev/null @@ -1,72 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE types (a real, b double precision, c numeric(2, 3), d char(4), e char(5), f varchar(6), g varchar(7));" ---- -Parse { - cst: SourceFile@0..115 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - TypesP@13..18 "types" - Whitespace@18..19 " " - Ascii40@19..20 "(" - Ident@20..21 "a" - Whitespace@21..22 " " - Real@22..26 "real" - Ascii44@26..27 "," - Whitespace@27..28 " " - Ident@28..29 "b" - Whitespace@29..30 " " - DoubleP@30..36 "double" - Whitespace@36..37 " " - Precision@37..46 "precision" - Ascii44@46..47 "," - Whitespace@47..48 " " - Ident@48..49 "c" - Whitespace@49..50 " " - Numeric@50..57 "numeric" - Ascii40@57..58 "(" - Iconst@58..59 "2" - Ascii44@59..60 "," - Whitespace@60..61 " " - Iconst@61..62 "3" - Ascii41@62..63 ")" - Ascii44@63..64 "," - Whitespace@64..65 " " - Ident@65..66 "d" - Whitespace@66..67 " " - CharP@67..71 "char" - Ascii40@71..72 "(" - Iconst@72..73 "4" - Ascii41@73..74 ")" - Ascii44@74..75 "," - Whitespace@75..76 " " - Ident@76..77 "e" - Whitespace@77..78 " " - CharP@78..82 "char" - Ascii40@82..83 "(" - Iconst@83..84 "5" - Ascii41@84..85 ")" - Ascii44@85..86 "," - Whitespace@86..87 " " - Ident@87..88 "f" - Whitespace@88..89 " " - Varchar@89..96 "varchar" - Ascii40@96..97 "(" - Iconst@97..98 "6" - Ascii41@98..99 ")" - Ascii44@99..100 "," - Whitespace@100..101 " " - Ident@101..102 "g" - Whitespace@102..103 " " - Varchar@103..110 "varchar" - Ascii40@110..111 "(" - Iconst@111..112 "7" - Ascii41@112..113 ")" - Ascii41@113..114 ")" - Ascii59@114..115 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@4.snap b/crates/parser/tests/snapshots/statements/valid/0043@4.snap deleted file mode 100644 index 868f8535..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@4.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TABLE types (a geometry(point) NOT NULL); ---- -Parse { - cst: SourceFile@0..48 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - TypesP@13..18 "types" - Whitespace@18..19 " " - Ascii40@19..20 "(" - Ident@20..21 "a" - Whitespace@21..22 " " - Ident@22..30 "geometry" - Ascii40@30..31 "(" - Ident@31..36 "point" - Ascii41@36..37 ")" - Whitespace@37..38 " " - Not@38..41 "NOT" - Whitespace@41..42 " " - NullP@42..46 "NULL" - Ascii41@46..47 ")" - Ascii59@47..48 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@5.snap b/crates/parser/tests/snapshots/statements/valid/0043@5.snap deleted file mode 100644 index 077179b6..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@5.snap +++ /dev/null @@ -1,253 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLE tablename (colname int NOT NULL DEFAULT nextval('tablename_colname_seq'));" ---- -Parse { - cst: SourceFile@0..87 - CreateStmt@0..87 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..22 - Ident@13..22 "tablename" - Whitespace@22..23 " " - Ascii40@23..24 "(" - ColumnDef@24..84 - Ident@24..31 "colname" - Whitespace@31..32 " " - TypeName@32..35 - IntP@32..35 "int" - Whitespace@35..36 " " - Constraint@36..44 - Not@36..39 "NOT" - Whitespace@39..40 " " - NullP@40..44 "NULL" - Whitespace@44..45 " " - Constraint@45..84 - Default@45..52 "DEFAULT" - Whitespace@52..53 " " - FuncCall@53..84 - Ident@53..60 "nextval" - Ascii40@60..61 "(" - AConst@61..84 - Sconst@61..84 "'tablename_colname_seq'" - Ascii41@84..85 ")" - Ascii41@85..86 ")" - Ascii59@86..87 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "tablename", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "colname", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 32, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [ - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrNotnull, - conname: "", - deferrable: false, - initdeferred: false, - location: 36, - is_no_inherit: false, - raw_expr: None, - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - Node { - node: Some( - Constraint( - Constraint { - contype: ConstrDefault, - conname: "", - deferrable: false, - initdeferred: false, - location: 45, - is_no_inherit: false, - raw_expr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "nextval", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 61, - val: Some( - Sval( - String { - sval: "tablename_colname_seq", - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 53, - }, - ), - ), - }, - ), - cooked_expr: "", - generated_when: "", - nulls_not_distinct: false, - keys: [], - including: [], - exclusions: [], - options: [], - indexname: "", - indexspace: "", - reset_default_tblspc: false, - access_method: "", - where_clause: None, - pktable: None, - fk_attrs: [], - pk_attrs: [], - fk_matchtype: "", - fk_upd_action: "", - fk_del_action: "", - fk_del_set_cols: [], - old_conpfeqop: [], - old_pktable_oid: 0, - skip_validation: false, - initially_valid: false, - }, - ), - ), - }, - ], - fdwoptions: [], - location: 24, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..86, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@6.snap b/crates/parser/tests/snapshots/statements/valid/0043@6.snap deleted file mode 100644 index 03643d51..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@6.snap +++ /dev/null @@ -1,158 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TABLE capitals (state char(2)) INHERITS (cities); ---- -Parse { - cst: SourceFile@0..56 - CreateStmt@0..56 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - RangeVar@13..21 - Ident@13..21 "capitals" - Whitespace@21..22 " " - Ascii40@22..23 "(" - ColumnDef@23..35 - Ident@23..28 "state" - Whitespace@28..29 " " - TypeName@29..35 - CharP@29..33 "char" - Ascii40@33..34 "(" - AConst@34..35 - Iconst@34..35 "2" - Ascii41@35..36 ")" - Ascii41@36..37 ")" - Whitespace@37..38 " " - Inherits@38..46 "INHERITS" - Whitespace@46..47 " " - Ascii40@47..48 "(" - RangeVar@48..54 - Ident@48..54 "cities" - Ascii41@54..55 ")" - Ascii59@55..56 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "capitals", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "state", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "pg_catalog", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "bpchar", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 34, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - typemod: -1, - array_bounds: [], - location: 29, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 23, - }, - ), - ), - }, - ], - inh_relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "cities", - inh: true, - relpersistence: "p", - alias: None, - location: 48, - }, - ), - ), - }, - ], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 0..55, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@7.snap b/crates/parser/tests/snapshots/statements/valid/0043@7.snap deleted file mode 100644 index 8f0a9c90..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@7.snap +++ /dev/null @@ -1,118 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TEMPORARY TABLE temp AS SELECT c FROM t; ---- -Parse { - cst: SourceFile@0..46 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Temporary@7..16 "TEMPORARY" - Whitespace@16..17 " " - Table@17..22 "TABLE" - Whitespace@22..23 " " - Temp@23..27 "temp" - Whitespace@27..28 " " - As@28..30 "AS" - SelectStmt@30..46 - Select@30..36 "SELECT" - Whitespace@36..37 " " - ResTarget@37..38 - ColumnRef@37..38 - Ident@37..38 "c" - Whitespace@38..39 " " - From@39..43 "FROM" - Whitespace@43..44 " " - RangeVar@44..45 - Ident@44..45 "t" - Ascii59@45..46 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 30..30, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..9, - ), - ], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "c", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "t", - inh: true, - relpersistence: "p", - alias: None, - location: 14, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 30..46, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@8.snap b/crates/parser/tests/snapshots/statements/valid/0043@8.snap deleted file mode 100644 index c1918b1d..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@8.snap +++ /dev/null @@ -1,115 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TABLE films2 AS SELECT * FROM films; ---- -Parse { - cst: SourceFile@0..42 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Table@7..12 "TABLE" - Whitespace@12..13 " " - Ident@13..19 "films2" - Whitespace@19..20 " " - As@20..22 "AS" - SelectStmt@22..42 - Select@22..28 "SELECT" - Whitespace@28..29 " " - ResTarget@29..30 - ColumnRef@29..30 - AStar@29..30 - Ascii42@29..30 "*" - Whitespace@30..31 " " - From@31..35 "FROM" - Whitespace@35..36 " " - RangeVar@36..41 - Ident@36..41 "films" - Ascii59@41..42 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 22..22, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..7, - ), - ], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 14, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 22..42, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0043@9.snap b/crates/parser/tests/snapshots/statements/valid/0043@9.snap deleted file mode 100644 index 1828a77b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0043@9.snap +++ /dev/null @@ -1,71 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TEMPORARY TABLE films_recent ON COMMIT DROP AS SELECT * FROM films WHERE date_prod > $1; ---- -Parse { - cst: SourceFile@0..93 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Temporary@7..16 "TEMPORARY" - Whitespace@16..17 " " - Table@17..22 "TABLE" - Whitespace@22..23 " " - Ident@23..35 "films_recent" - Whitespace@35..36 " " - On@36..38 "ON" - TransactionStmt@38..44 - Commit@38..44 "COMMIT" - Drop@44..48 "DROP" - Whitespace@48..49 " " - As@49..51 "AS" - Whitespace@51..52 " " - Select@52..58 "SELECT" - Whitespace@58..59 " " - Ascii42@59..60 "*" - Whitespace@60..61 " " - From@61..65 "FROM" - Whitespace@65..66 " " - Ident@66..71 "films" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - Ident@78..87 "date_prod" - Whitespace@87..88 " " - Ascii62@88..89 ">" - Whitespace@89..90 " " - Param@90..92 "$1" - Ascii59@92..93 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 38..38, - ), - SyntaxError( - "Invalid statement: syntax error at end of input", - 0..9, - ), - SyntaxError( - "Expected Ascii59, found Whitespace", - 45..45, - ), - SyntaxError( - "Invalid statement: syntax error at or near \"AS\"", - 12..32, - ), - ], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtCommit, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 38..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0044@1.snap b/crates/parser/tests/snapshots/statements/valid/0044@1.snap deleted file mode 100644 index a26f04f9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0044@1.snap +++ /dev/null @@ -1,208 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE VIEW comedies AS SELECT * FROM films WHERE kind = 'Comedy';" ---- -Parse { - cst: SourceFile@0..66 - ViewStmt@0..66 - Create@0..6 "CREATE" - Whitespace@6..7 " " - View@7..11 "VIEW" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "comedies" - Whitespace@20..21 " " - As@21..23 "AS" - Whitespace@23..24 " " - SelectStmt@24..65 - Select@24..30 "SELECT" - Whitespace@30..31 " " - ResTarget@31..32 - ColumnRef@31..32 - AStar@31..32 - Ascii42@31..32 "*" - Whitespace@32..33 " " - From@33..37 "FROM" - Whitespace@37..38 " " - RangeVar@38..43 - Ident@38..43 "films" - Whitespace@43..44 " " - Where@44..49 "WHERE" - Whitespace@49..50 " " - AExpr@50..65 - ColumnRef@50..54 - Ident@50..54 "kind" - Whitespace@54..55 " " - Ascii61@55..56 "=" - Whitespace@56..57 " " - AConst@57..65 - Sconst@57..65 "'Comedy'" - Ascii59@65..66 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - aliases: [], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 31, - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 38, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "kind", - }, - ), - ), - }, - ], - location: 50, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 57, - val: Some( - Sval( - String { - sval: "Comedy", - }, - ), - ), - }, - ), - ), - }, - ), - location: 55, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: NoCheckOption, - }, - ), - range: 0..65, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0044@2.snap b/crates/parser/tests/snapshots/statements/valid/0044@2.snap deleted file mode 100644 index cf3f34b5..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0044@2.snap +++ /dev/null @@ -1,216 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE VIEW universal_comedies AS SELECT * FROM comedies WHERE classification = 'U' WITH LOCAL CHECK OPTION;" ---- -Parse { - cst: SourceFile@0..108 - ViewStmt@0..108 - Create@0..6 "CREATE" - Whitespace@6..7 " " - View@7..11 "VIEW" - Whitespace@11..12 " " - RangeVar@12..30 - Ident@12..30 "universal_comedies" - Whitespace@30..31 " " - As@31..33 "AS" - Whitespace@33..34 " " - SelectStmt@34..83 - Select@34..40 "SELECT" - Whitespace@40..41 " " - ResTarget@41..42 - ColumnRef@41..42 - AStar@41..42 - Ascii42@41..42 "*" - Whitespace@42..43 " " - From@43..47 "FROM" - Whitespace@47..48 " " - RangeVar@48..56 - Ident@48..56 "comedies" - Whitespace@56..57 " " - Where@57..62 "WHERE" - Whitespace@62..63 " " - AExpr@63..83 - ColumnRef@63..77 - Ident@63..77 "classification" - Whitespace@77..78 " " - Ascii61@78..79 "=" - Whitespace@79..80 " " - AConst@80..83 - Sconst@80..83 "'U'" - Whitespace@83..84 " " - With@84..88 "WITH" - Whitespace@88..89 " " - Local@89..94 "LOCAL" - Whitespace@94..95 " " - Check@95..100 "CHECK" - Whitespace@100..101 " " - Option@101..107 "OPTION" - Ascii59@107..108 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "universal_comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - aliases: [], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 41, - }, - ), - ), - }, - ), - location: 41, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 48, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classification", - }, - ), - ), - }, - ], - location: 63, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 80, - val: Some( - Sval( - String { - sval: "U", - }, - ), - ), - }, - ), - ), - }, - ), - location: 78, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: LocalCheckOption, - }, - ), - range: 0..107, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0044@3.snap b/crates/parser/tests/snapshots/statements/valid/0044@3.snap deleted file mode 100644 index 91f00a46..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0044@3.snap +++ /dev/null @@ -1,216 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE VIEW pg_comedies AS SELECT * FROM comedies WHERE classification = 'PG' WITH CASCADED CHECK OPTION;" ---- -Parse { - cst: SourceFile@0..105 - ViewStmt@0..105 - Create@0..6 "CREATE" - Whitespace@6..7 " " - View@7..11 "VIEW" - Whitespace@11..12 " " - RangeVar@12..23 - Ident@12..23 "pg_comedies" - Whitespace@23..24 " " - As@24..26 "AS" - Whitespace@26..27 " " - SelectStmt@27..77 - Select@27..33 "SELECT" - Whitespace@33..34 " " - ResTarget@34..35 - ColumnRef@34..35 - AStar@34..35 - Ascii42@34..35 "*" - Whitespace@35..36 " " - From@36..40 "FROM" - Whitespace@40..41 " " - RangeVar@41..49 - Ident@41..49 "comedies" - Whitespace@49..50 " " - Where@50..55 "WHERE" - Whitespace@55..56 " " - AExpr@56..77 - ColumnRef@56..70 - Ident@56..70 "classification" - Whitespace@70..71 " " - Ascii61@71..72 "=" - Whitespace@72..73 " " - AConst@73..77 - Sconst@73..77 "'PG'" - Whitespace@77..78 " " - With@78..82 "WITH" - Whitespace@82..83 " " - Cascaded@83..91 "CASCADED" - Whitespace@91..92 " " - Check@92..97 "CHECK" - Whitespace@97..98 " " - Option@98..104 "OPTION" - Ascii59@104..105 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - aliases: [], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 34, - }, - ), - ), - }, - ), - location: 34, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 41, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classification", - }, - ), - ), - }, - ], - location: 56, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 73, - val: Some( - Sval( - String { - sval: "PG", - }, - ), - ), - }, - ), - ), - }, - ), - location: 71, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: CascadedCheckOption, - }, - ), - range: 0..104, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0044@4.snap b/crates/parser/tests/snapshots/statements/valid/0044@4.snap deleted file mode 100644 index c95512b2..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0044@4.snap +++ /dev/null @@ -1,605 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE VIEW comedies AS SELECT f.*, country_code_to_name(f.country_code) AS country, (SELECT avg(r.rating) FROM user_ratings r WHERE r.film_id = f.id) AS avg_rating FROM films f WHERE f.kind = 'Comedy';" ---- -Parse { - cst: SourceFile@0..202 - ViewStmt@0..202 - Create@0..6 "CREATE" - Whitespace@6..7 " " - View@7..11 "VIEW" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "comedies" - Whitespace@20..21 " " - As@21..23 "AS" - Whitespace@23..24 " " - SelectStmt@24..201 - Select@24..30 "SELECT" - Whitespace@30..31 " " - ResTarget@31..34 - ColumnRef@31..34 - Ident@31..32 "f" - Ascii46@32..33 "." - AStar@33..34 - Ascii42@33..34 "*" - Ascii44@34..35 "," - Whitespace@35..36 " " - ResTarget@36..83 - FuncCall@36..71 - Ident@36..56 "country_code_to_name" - Ascii40@56..57 "(" - ColumnRef@57..71 - Ident@57..58 "f" - Ascii46@58..59 "." - Ident@59..71 "country_code" - Ascii41@71..72 ")" - Whitespace@72..73 " " - As@73..75 "AS" - Whitespace@75..76 " " - Ident@76..83 "country" - Ascii44@83..84 "," - Whitespace@84..85 " " - ResTarget@85..164 - SubLink@85..149 - SelectStmt@85..149 - Ascii40@85..86 "(" - Select@86..92 "SELECT" - Whitespace@92..93 " " - ResTarget@93..105 - FuncCall@93..105 - Ident@93..96 "avg" - Ascii40@96..97 "(" - ColumnRef@97..105 - Ident@97..98 "r" - Ascii46@98..99 "." - Ident@99..105 "rating" - Ascii41@105..106 ")" - Whitespace@106..107 " " - From@107..111 "FROM" - Whitespace@111..112 " " - RangeVar@112..126 - Ident@112..124 "user_ratings" - Whitespace@124..125 " " - Alias@125..126 - Ident@125..126 "r" - Whitespace@126..127 " " - Where@127..132 "WHERE" - Whitespace@132..133 " " - AExpr@133..149 - ColumnRef@133..142 - Ident@133..134 "r" - Ascii46@134..135 "." - Ident@135..142 "film_id" - Whitespace@142..143 " " - Ascii61@143..144 "=" - Whitespace@144..145 " " - ColumnRef@145..149 - Ident@145..146 "f" - Ascii46@146..147 "." - Ident@147..149 "id" - Ascii41@149..150 ")" - Whitespace@150..151 " " - As@151..153 "AS" - Whitespace@153..154 " " - Ident@154..164 "avg_rating" - Whitespace@164..165 " " - From@165..169 "FROM" - Whitespace@169..170 " " - RangeVar@170..177 - Ident@170..175 "films" - Whitespace@175..176 " " - Alias@176..177 - Ident@176..177 "f" - Whitespace@177..178 " " - Where@178..183 "WHERE" - Whitespace@183..184 " " - AExpr@184..201 - ColumnRef@184..190 - Ident@184..185 "f" - Ascii46@185..186 "." - Ident@186..190 "kind" - Whitespace@190..191 " " - Ascii61@191..192 "=" - Whitespace@192..193 " " - AConst@193..201 - Sconst@193..201 "'Comedy'" - Ascii59@201..202 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "comedies", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - aliases: [], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "f", - }, - ), - ), - }, - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 31, - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "country", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "country_code_to_name", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "f", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "country_code", - }, - ), - ), - }, - ], - location: 57, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 36, - }, - ), - ), - }, - ), - location: 36, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "avg_rating", - indirection: [], - val: Some( - Node { - node: Some( - SubLink( - SubLink { - xpr: None, - sub_link_type: ExprSublink, - sub_link_id: 0, - testexpr: None, - oper_name: [], - subselect: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "avg", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "r", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "rating", - }, - ), - ), - }, - ], - location: 97, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 93, - }, - ), - ), - }, - ), - location: 93, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "user_ratings", - inh: true, - relpersistence: "p", - alias: Some( - Alias { - aliasname: "r", - colnames: [], - }, - ), - location: 112, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "r", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "film_id", - }, - ), - ), - }, - ], - location: 133, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "f", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "id", - }, - ), - ), - }, - ], - location: 145, - }, - ), - ), - }, - ), - location: 143, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - location: 85, - }, - ), - ), - }, - ), - location: 85, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: Some( - Alias { - aliasname: "f", - colnames: [], - }, - ), - location: 170, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "f", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "kind", - }, - ), - ), - }, - ], - location: 184, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 193, - val: Some( - Sval( - String { - sval: "Comedy", - }, - ), - ), - }, - ), - ), - }, - ), - location: 191, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: NoCheckOption, - }, - ), - range: 0..201, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0044@5.snap b/crates/parser/tests/snapshots/statements/valid/0044@5.snap deleted file mode 100644 index 1b163db8..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0044@5.snap +++ /dev/null @@ -1,481 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE RECURSIVE VIEW public.nums_1_100 (n) AS VALUES (1) UNION ALL SELECT n+1 FROM nums_1_100 WHERE n < 100; ---- -Parse { - cst: SourceFile@0..109 - ViewStmt@0..109 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Recursive@7..16 "RECURSIVE" - Whitespace@16..17 " " - View@17..21 "VIEW" - Whitespace@21..22 " " - RangeVar@22..39 - Ident@22..28 "public" - Ascii46@28..29 "." - Ident@29..39 "nums_1_100" - Whitespace@39..40 " " - Ascii40@40..41 "(" - Ident@41..42 "n" - Ascii41@42..43 ")" - Whitespace@43..44 " " - As@44..46 "AS" - Whitespace@46..47 " " - SelectStmt@47..109 - WithClause@47..108 - CommonTableExpr@47..108 - SelectStmt@47..108 - SelectStmt@47..56 - Values@47..53 "VALUES" - Whitespace@53..54 " " - Ascii40@54..55 "(" - List@55..56 - AConst@55..56 - Iconst@55..56 "1" - Ascii41@56..57 ")" - Whitespace@57..58 " " - Union@58..63 "UNION" - Whitespace@63..64 " " - All@64..67 "ALL" - Whitespace@67..68 " " - Select@68..74 "SELECT" - Whitespace@74..75 " " - SelectStmt@75..108 - ResTarget@75..78 - AExpr@75..78 - ColumnRef@75..76 - Ident@75..76 "n" - Ascii43@76..77 "+" - AConst@77..78 - Iconst@77..78 "1" - Whitespace@78..79 " " - From@79..83 "FROM" - Whitespace@83..84 " " - RangeVar@84..94 - Ident@84..94 "nums_1_100" - Whitespace@94..95 " " - Where@95..100 "WHERE" - Whitespace@100..101 " " - AExpr@101..108 - ColumnRef@101..102 - Ident@101..102 "n" - Whitespace@102..103 " " - Ascii60@103..104 "<" - Whitespace@104..105 " " - AConst@105..108 - Iconst@105..108 "100" - Ascii59@108..109 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: ViewStmt( - ViewStmt { - view: Some( - RangeVar { - catalogname: "", - schemaname: "public", - relname: "nums_1_100", - inh: true, - relpersistence: "p", - alias: None, - location: 22, - }, - ), - aliases: [ - Node { - node: Some( - String( - String { - sval: "n", - }, - ), - ), - }, - ], - query: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "n", - }, - ), - ), - }, - ], - location: -1, - }, - ), - ), - }, - ), - location: -1, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "nums_1_100", - inh: true, - relpersistence: "p", - alias: None, - location: -1, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: Some( - WithClause { - ctes: [ - Node { - node: Some( - CommonTableExpr( - CommonTableExpr { - ctename: "nums_1_100", - aliascolnames: [ - Node { - node: Some( - String( - String { - sval: "n", - }, - ), - ), - }, - ], - ctematerialized: Default, - ctequery: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopUnion, - all: true, - larg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 55, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - rarg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "+", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "n", - }, - ), - ), - }, - ], - location: 75, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 77, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ), - location: 76, - }, - ), - ), - }, - ), - location: 75, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "nums_1_100", - inh: true, - relpersistence: "p", - alias: None, - location: 84, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "<", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "n", - }, - ), - ), - }, - ], - location: 101, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 105, - val: Some( - Ival( - Integer { - ival: 100, - }, - ), - ), - }, - ), - ), - }, - ), - location: 103, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - }, - ), - ), - }, - ), - search_clause: None, - cycle_clause: None, - location: -1, - cterecursive: false, - cterefcount: 0, - ctecolnames: [], - ctecoltypes: [], - ctecoltypmods: [], - ctecolcollations: [], - }, - ), - ), - }, - ], - recursive: true, - location: -1, - }, - ), - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - replace: false, - options: [], - with_check_option: NoCheckOption, - }, - ), - range: 0..108, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@1.snap b/crates/parser/tests/snapshots/statements/valid/0046@1.snap deleted file mode 100644 index 0b8ca061..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@1.snap +++ /dev/null @@ -1,42 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TYPE type1; ---- -Parse { - cst: SourceFile@0..18 - DefineStmt@0..18 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Ascii59@17..18 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectType, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - args: [], - definition: [], - if_not_exists: false, - replace: false, - }, - ), - range: 0..17, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@2.snap b/crates/parser/tests/snapshots/statements/valid/0046@2.snap deleted file mode 100644 index 0d9f8496..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@2.snap +++ /dev/null @@ -1,150 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE type1 AS (attr1 int4, attr2 bool);" ---- -Parse { - cst: SourceFile@0..46 - CompositeTypeStmt@0..46 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - RangeVar@12..17 - Ident@12..17 "type1" - Whitespace@17..18 " " - As@18..20 "AS" - Whitespace@20..21 " " - Ascii40@21..22 "(" - ColumnDef@22..32 - Ident@22..27 "attr1" - Whitespace@27..28 " " - TypeName@28..32 - Ident@28..32 "int4" - Ascii44@32..33 "," - Whitespace@33..34 " " - ColumnDef@34..44 - Ident@34..39 "attr2" - Whitespace@39..40 " " - TypeName@40..44 - Ident@40..44 "bool" - Ascii41@44..45 ")" - Ascii59@45..46 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CompositeTypeStmt( - CompositeTypeStmt { - typevar: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "type1", - inh: false, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - coldeflist: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "attr1", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 28, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 22, - }, - ), - ), - }, - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "attr2", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "bool", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 40, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 34, - }, - ), - ), - }, - ], - }, - ), - range: 0..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@3.snap b/crates/parser/tests/snapshots/statements/valid/0046@3.snap deleted file mode 100644 index 2af873b3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@3.snap +++ /dev/null @@ -1,77 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "/* TODO: CREATE TYPE type1 AS (attr1 int4 COLLATE collation1, attr2 bool); */ SELECT 1;" ---- -Parse { - cst: SourceFile@0..86 - CComment@0..77 "/* TODO: CREATE TYPE ..." - SelectStmt@77..86 - Select@77..83 "SELECT" - Whitespace@83..84 " " - ResTarget@84..85 - AConst@84..85 - Iconst@84..85 "1" - Ascii59@85..86 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 7, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 77..86, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@4.snap b/crates/parser/tests/snapshots/statements/valid/0046@4.snap deleted file mode 100644 index 699bf596..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@4.snap +++ /dev/null @@ -1,79 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE type1 AS ENUM ('value1', 'value2', 'value3');" ---- -Parse { - cst: SourceFile@0..57 - CreateEnumStmt@0..57 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Whitespace@17..18 " " - As@18..20 "AS" - Whitespace@20..21 " " - EnumP@21..25 "ENUM" - Whitespace@25..26 " " - Ascii40@26..27 "(" - Sconst@27..35 "'value1'" - Ascii44@35..36 "," - Whitespace@36..37 " " - Sconst@37..45 "'value2'" - Ascii44@45..46 "," - Whitespace@46..47 " " - Sconst@47..55 "'value3'" - Ascii41@55..56 ")" - Ascii59@56..57 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateEnumStmt( - CreateEnumStmt { - type_name: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - vals: [ - Node { - node: Some( - String( - String { - sval: "value1", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "value2", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "value3", - }, - ), - ), - }, - ], - }, - ), - range: 0..56, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@5.snap b/crates/parser/tests/snapshots/statements/valid/0046@5.snap deleted file mode 100644 index 37d96c6e..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@5.snap +++ /dev/null @@ -1,92 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE TYPE type1 AS RANGE (subtype = int4); ---- -Parse { - cst: SourceFile@0..44 - CreateRangeStmt@0..44 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Whitespace@17..18 " " - As@18..20 "AS" - Whitespace@20..21 " " - Range@21..26 "RANGE" - Whitespace@26..27 " " - Ascii40@27..28 "(" - DefElem@28..42 - Ident@28..35 "subtype" - Whitespace@35..36 " " - Ascii61@36..37 "=" - Whitespace@37..38 " " - TypeName@38..42 - Ident@38..42 "int4" - Ascii41@42..43 ")" - Ascii59@43..44 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateRangeStmt( - CreateRangeStmt { - type_name: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - params: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "subtype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 38, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 28, - }, - ), - ), - }, - ], - }, - ), - range: 0..43, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@6.snap b/crates/parser/tests/snapshots/statements/valid/0046@6.snap deleted file mode 100644 index 45852c11..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@6.snap +++ /dev/null @@ -1,158 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE type1 AS RANGE (subtype = int4, receive = receive_func, passedbyvalue);" ---- -Parse { - cst: SourceFile@0..83 - CreateRangeStmt@0..83 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Whitespace@17..18 " " - As@18..20 "AS" - Whitespace@20..21 " " - Range@21..26 "RANGE" - Whitespace@26..27 " " - Ascii40@27..28 "(" - DefElem@28..42 - Ident@28..35 "subtype" - Whitespace@35..36 " " - Ascii61@36..37 "=" - Whitespace@37..38 " " - TypeName@38..42 - Ident@38..42 "int4" - Ascii44@42..43 "," - Whitespace@43..44 " " - DefElem@44..66 - Ident@44..51 "receive" - Whitespace@51..52 " " - Ascii61@52..53 "=" - Whitespace@53..54 " " - TypeName@54..66 - Ident@54..66 "receive_func" - Ascii44@66..67 "," - Whitespace@67..68 " " - DefElem@68..81 - Ident@68..81 "passedbyvalue" - Ascii41@81..82 ")" - Ascii59@82..83 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateRangeStmt( - CreateRangeStmt { - type_name: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - params: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "subtype", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "int4", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 38, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 28, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "receive", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "receive_func", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 54, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 44, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "passedbyvalue", - arg: None, - defaction: DefelemUnspec, - location: 68, - }, - ), - ), - }, - ], - }, - ), - range: 0..82, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@7.snap b/crates/parser/tests/snapshots/statements/valid/0046@7.snap deleted file mode 100644 index 01d15077..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@7.snap +++ /dev/null @@ -1,142 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE type1 (input = input1, output = output1);" ---- -Parse { - cst: SourceFile@0..53 - DefineStmt@0..53 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Whitespace@17..18 " " - Ascii40@18..19 "(" - DefElem@19..33 - InputP@19..24 "input" - Whitespace@24..25 " " - Ascii61@25..26 "=" - Whitespace@26..27 " " - TypeName@27..33 - Ident@27..33 "input1" - Ascii44@33..34 "," - Whitespace@34..35 " " - DefElem@35..51 - Ident@35..41 "output" - Whitespace@41..42 " " - Ascii61@42..43 "=" - Whitespace@43..44 " " - TypeName@44..51 - Ident@44..51 "output1" - Ascii41@51..52 ")" - Ascii59@52..53 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectType, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - args: [], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "input", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "input1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 27, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 19, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "output", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "output1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 35, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..52, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0046@8.snap b/crates/parser/tests/snapshots/statements/valid/0046@8.snap deleted file mode 100644 index 7853dad5..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0046@8.snap +++ /dev/null @@ -1,159 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TYPE type1 (input = input1, output = output1, passedbyvalue);" ---- -Parse { - cst: SourceFile@0..68 - DefineStmt@0..68 - Create@0..6 "CREATE" - Whitespace@6..7 " " - TypeP@7..11 "TYPE" - Whitespace@11..12 " " - Ident@12..17 "type1" - Whitespace@17..18 " " - Ascii40@18..19 "(" - DefElem@19..33 - InputP@19..24 "input" - Whitespace@24..25 " " - Ascii61@25..26 "=" - Whitespace@26..27 " " - TypeName@27..33 - Ident@27..33 "input1" - Ascii44@33..34 "," - Whitespace@34..35 " " - DefElem@35..51 - Ident@35..41 "output" - Whitespace@41..42 " " - Ascii61@42..43 "=" - Whitespace@43..44 " " - TypeName@44..51 - Ident@44..51 "output1" - Ascii44@51..52 "," - Whitespace@52..53 " " - DefElem@53..66 - Ident@53..66 "passedbyvalue" - Ascii41@66..67 ")" - Ascii59@67..68 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: DefineStmt( - DefineStmt { - kind: ObjectType, - oldstyle: false, - defnames: [ - Node { - node: Some( - String( - String { - sval: "type1", - }, - ), - ), - }, - ], - args: [], - definition: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "input", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "input1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 27, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 19, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "output", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "output1", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 44, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 35, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "passedbyvalue", - arg: None, - defaction: DefelemUnspec, - location: 53, - }, - ), - ), - }, - ], - if_not_exists: false, - replace: false, - }, - ), - range: 0..67, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@1.snap b/crates/parser/tests/snapshots/statements/valid/0047@1.snap deleted file mode 100644 index a472c058..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@1.snap +++ /dev/null @@ -1,86 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE DATABASE x OWNER abc CONNECTION LIMIT 5; ---- -Parse { - cst: SourceFile@0..47 - CreatedbStmt@0..47 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..27 - Owner@18..23 "OWNER" - Whitespace@23..24 " " - Ident@24..27 "abc" - Whitespace@27..28 " " - DefElem@28..46 - Connection@28..38 "CONNECTION" - Whitespace@38..39 " " - Limit@39..44 "LIMIT" - Whitespace@44..45 " " - Iconst@45..46 "5" - Ascii59@46..47 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "owner", - arg: Some( - Node { - node: Some( - String( - String { - sval: "abc", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "connection_limit", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 5, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 28, - }, - ), - ), - }, - ], - }, - ), - range: 0..46, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@2.snap b/crates/parser/tests/snapshots/statements/valid/0047@2.snap deleted file mode 100644 index bad286db..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@2.snap +++ /dev/null @@ -1,56 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE DATABASE x ENCODING \"SQL_ASCII\";" ---- -Parse { - cst: SourceFile@0..39 - CreatedbStmt@0..39 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..38 - Encoding@18..26 "ENCODING" - Whitespace@26..27 " " - Ident@27..38 "\"SQL_ASCII\"" - Ascii59@38..39 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "encoding", - arg: Some( - Node { - node: Some( - String( - String { - sval: "SQL_ASCII", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - ], - }, - ), - range: 0..38, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@3.snap b/crates/parser/tests/snapshots/statements/valid/0047@3.snap deleted file mode 100644 index c219a202..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@3.snap +++ /dev/null @@ -1,56 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE DATABASE x LC_COLLATE \"en_US.UTF-8\";" ---- -Parse { - cst: SourceFile@0..43 - CreatedbStmt@0..43 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..42 - Ident@18..28 "LC_COLLATE" - Whitespace@28..29 " " - Ident@29..42 "\"en_US.UTF-8\"" - Ascii59@42..43 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "lc_collate", - arg: Some( - Node { - node: Some( - String( - String { - sval: "en_US.UTF-8", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - ], - }, - ), - range: 0..42, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@4.snap b/crates/parser/tests/snapshots/statements/valid/0047@4.snap deleted file mode 100644 index b9b2a0bc..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@4.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE DATABASE x LOCATION DEFAULT; ---- -Parse { - cst: SourceFile@0..35 - CreatedbStmt@0..35 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..34 - Location@18..26 "LOCATION" - Whitespace@26..27 " " - Default@27..34 "DEFAULT" - Ascii59@34..35 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "location", - arg: None, - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - ], - }, - ), - range: 0..34, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@5.snap b/crates/parser/tests/snapshots/statements/valid/0047@5.snap deleted file mode 100644 index 708ceca4..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@5.snap +++ /dev/null @@ -1,56 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE DATABASE x TABLESPACE abc; ---- -Parse { - cst: SourceFile@0..33 - CreatedbStmt@0..33 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..32 - Tablespace@18..28 "TABLESPACE" - Whitespace@28..29 " " - Ident@29..32 "abc" - Ascii59@32..33 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "tablespace", - arg: Some( - Node { - node: Some( - String( - String { - sval: "abc", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - ], - }, - ), - range: 0..32, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0047@6.snap b/crates/parser/tests/snapshots/statements/valid/0047@6.snap deleted file mode 100644 index 3e02fff1..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0047@6.snap +++ /dev/null @@ -1,56 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE DATABASE x TEMPLATE TRUE; ---- -Parse { - cst: SourceFile@0..32 - CreatedbStmt@0..32 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Database@7..15 "DATABASE" - Whitespace@15..16 " " - Ident@16..17 "x" - Whitespace@17..18 " " - DefElem@18..31 - Template@18..26 "TEMPLATE" - Whitespace@26..27 " " - TrueP@27..31 "TRUE" - Ascii59@31..32 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatedbStmt( - CreatedbStmt { - dbname: "x", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "template", - arg: Some( - Node { - node: Some( - String( - String { - sval: "true", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 18, - }, - ), - ), - }, - ], - }, - ), - range: 0..31, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0048@1.snap b/crates/parser/tests/snapshots/statements/valid/0048@1.snap deleted file mode 100644 index d2573da0..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0048@1.snap +++ /dev/null @@ -1,33 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLESPACE x LOCATION 'a';" ---- -Parse { - cst: SourceFile@0..33 - CreateTableSpaceStmt@0..33 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Tablespace@7..17 "TABLESPACE" - Whitespace@17..18 " " - Ident@18..19 "x" - Whitespace@19..20 " " - Location@20..28 "LOCATION" - Whitespace@28..29 " " - Sconst@29..32 "'a'" - Ascii59@32..33 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateTableSpaceStmt( - CreateTableSpaceStmt { - tablespacename: "x", - owner: None, - location: "a", - options: [], - }, - ), - range: 0..32, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0048@2.snap b/crates/parser/tests/snapshots/statements/valid/0048@2.snap deleted file mode 100644 index 41863927..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0048@2.snap +++ /dev/null @@ -1,106 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TABLESPACE x OWNER a LOCATION 'b' WITH (random_page_cost=42, seq_page_cost=3);" ---- -Parse { - cst: SourceFile@0..85 - CreateTableSpaceStmt@0..85 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Tablespace@7..17 "TABLESPACE" - Whitespace@17..18 " " - Ident@18..19 "x" - Whitespace@19..20 " " - Owner@20..25 "OWNER" - Whitespace@25..26 " " - RoleSpec@26..27 - Ident@26..27 "a" - Whitespace@27..28 " " - Location@28..36 "LOCATION" - Whitespace@36..37 " " - Sconst@37..40 "'b'" - Whitespace@40..41 " " - With@41..45 "WITH" - Whitespace@45..46 " " - Ascii40@46..47 "(" - DefElem@47..66 - Ident@47..63 "random_page_cost" - Ascii61@63..64 "=" - Iconst@64..66 "42" - Ascii44@66..67 "," - Whitespace@67..68 " " - DefElem@68..83 - Ident@68..81 "seq_page_cost" - Ascii61@81..82 "=" - Iconst@82..83 "3" - Ascii41@83..84 ")" - Ascii59@84..85 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateTableSpaceStmt( - CreateTableSpaceStmt { - tablespacename: "x", - owner: Some( - RoleSpec { - roletype: RolespecCstring, - rolename: "a", - location: 26, - }, - ), - location: "b", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "random_page_cost", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 42, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 47, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "seq_page_cost", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 3, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 68, - }, - ), - ), - }, - ], - }, - ), - range: 0..84, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0049@1.snap b/crates/parser/tests/snapshots/statements/valid/0049@1.snap deleted file mode 100644 index 79c95b41..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0049@1.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE EXTENSION x; ---- -Parse { - cst: SourceFile@0..19 - CreateExtensionStmt@0..19 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Extension@7..16 "EXTENSION" - Whitespace@16..17 " " - Ident@17..18 "x" - Ascii59@18..19 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateExtensionStmt( - CreateExtensionStmt { - extname: "x", - if_not_exists: false, - options: [], - }, - ), - range: 0..18, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0049@2.snap b/crates/parser/tests/snapshots/statements/valid/0049@2.snap deleted file mode 100644 index d4b59350..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0049@2.snap +++ /dev/null @@ -1,117 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE EXTENSION IF NOT EXISTS x CASCADE VERSION \"1.2\" SCHEMA a;" ---- -Parse { - cst: SourceFile@0..64 - CreateExtensionStmt@0..64 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Extension@7..16 "EXTENSION" - Whitespace@16..17 " " - IfP@17..19 "IF" - Whitespace@19..20 " " - Not@20..23 "NOT" - Whitespace@23..24 " " - Exists@24..30 "EXISTS" - Whitespace@30..31 " " - Ident@31..32 "x" - Whitespace@32..33 " " - DefElem@33..40 - Cascade@33..40 "CASCADE" - Whitespace@40..41 " " - DefElem@41..54 - VersionP@41..48 "VERSION" - Whitespace@48..49 " " - Ident@49..54 "\"1.2\"" - Whitespace@54..55 " " - DefElem@55..63 - Schema@55..61 "SCHEMA" - Whitespace@61..62 " " - Ident@62..63 "a" - Ascii59@63..64 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateExtensionStmt( - CreateExtensionStmt { - extname: "x", - if_not_exists: true, - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "cascade", - arg: Some( - Node { - node: Some( - Boolean( - Boolean { - boolval: true, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 33, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "new_version", - arg: Some( - Node { - node: Some( - String( - String { - sval: "1.2", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 41, - }, - ), - ), - }, - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "schema", - arg: Some( - Node { - node: Some( - String( - String { - sval: "a", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 55, - }, - ), - ), - }, - ], - }, - ), - range: 0..63, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@1.snap b/crates/parser/tests/snapshots/statements/valid/0051@1.snap deleted file mode 100644 index 14f5696e..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@1.snap +++ /dev/null @@ -1,88 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE UNIQUE INDEX title_idx ON films (title); ---- -Parse { - cst: SourceFile@0..47 - IndexStmt@0..47 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Unique@7..13 "UNIQUE" - Whitespace@13..14 " " - Index@14..19 "INDEX" - Whitespace@19..20 " " - Ident@20..29 "title_idx" - Whitespace@29..30 " " - On@30..32 "ON" - Whitespace@32..33 " " - RangeVar@33..38 - Ident@33..38 "films" - Whitespace@38..39 " " - Ascii40@39..40 "(" - IndexElem@40..45 - Ident@40..45 "title" - Ascii41@45..46 ")" - Ascii59@46..47 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 33, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: true, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..46, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@10.snap b/crates/parser/tests/snapshots/statements/valid/0051@10.snap deleted file mode 100644 index f4348651..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@10.snap +++ /dev/null @@ -1,169 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE INDEX pointloc ON points USING gist (box(location,location));" ---- -Parse { - cst: SourceFile@0..68 - IndexStmt@0..68 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..21 "pointloc" - Whitespace@21..22 " " - On@22..24 "ON" - Whitespace@24..25 " " - RangeVar@25..31 - Ident@25..31 "points" - Whitespace@31..32 " " - Using@32..37 "USING" - Whitespace@37..38 " " - Ident@38..42 "gist" - Whitespace@42..43 " " - Ascii40@43..44 "(" - IndexElem@44..65 - FuncCall@44..65 - Ident@44..47 "box" - Ascii40@47..48 "(" - ColumnRef@48..56 - Location@48..56 "location" - Ascii44@56..57 "," - ColumnRef@57..65 - Location@57..65 "location" - Ascii41@65..66 ")" - Ascii41@66..67 ")" - Ascii59@67..68 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "pointloc", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "points", - inh: true, - relpersistence: "p", - alias: None, - location: 25, - }, - ), - access_method: "gist", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "", - expr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "box", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "location", - }, - ), - ), - }, - ], - location: 48, - }, - ), - ), - }, - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "location", - }, - ), - ), - }, - ], - location: 57, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 44, - }, - ), - ), - }, - ), - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..67, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@11.snap b/crates/parser/tests/snapshots/statements/valid/0051@11.snap deleted file mode 100644 index e75bffb7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@11.snap +++ /dev/null @@ -1,88 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity); ---- -Parse { - cst: SourceFile@0..73 - IndexStmt@0..73 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Concurrently@13..25 "CONCURRENTLY" - Whitespace@25..26 " " - Ident@26..46 "sales_quantity_index" - Whitespace@46..47 " " - On@47..49 "ON" - Whitespace@49..50 " " - RangeVar@50..61 - Ident@50..61 "sales_table" - Whitespace@61..62 " " - Ascii40@62..63 "(" - IndexElem@63..71 - Ident@63..71 "quantity" - Ascii41@71..72 ")" - Ascii59@72..73 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "sales_quantity_index", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "sales_table", - inh: true, - relpersistence: "p", - alias: None, - location: 50, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "quantity", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: true, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..72, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@2.snap b/crates/parser/tests/snapshots/statements/valid/0051@2.snap deleted file mode 100644 index 69e76c3a..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@2.snap +++ /dev/null @@ -1,132 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);" ---- -Parse { - cst: SourceFile@0..74 - IndexStmt@0..74 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Unique@7..13 "UNIQUE" - Whitespace@13..14 " " - Index@14..19 "INDEX" - Whitespace@19..20 " " - Ident@20..29 "title_idx" - Whitespace@29..30 " " - On@30..32 "ON" - Whitespace@32..33 " " - RangeVar@33..38 - Ident@33..38 "films" - Whitespace@38..39 " " - Ascii40@39..40 "(" - IndexElem@40..45 - Ident@40..45 "title" - Ascii41@45..46 ")" - Whitespace@46..47 " " - Include@47..54 "INCLUDE" - Whitespace@54..55 " " - Ascii40@55..56 "(" - IndexElem@56..64 - Ident@56..64 "director" - Ascii44@64..65 "," - Whitespace@65..66 " " - IndexElem@66..72 - Ident@66..72 "rating" - Ascii41@72..73 ")" - Ascii59@73..74 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 33, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "director", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - Node { - node: Some( - IndexElem( - IndexElem { - name: "rating", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: true, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..73, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@3.snap b/crates/parser/tests/snapshots/statements/valid/0051@3.snap deleted file mode 100644 index a2a0436b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@3.snap +++ /dev/null @@ -1,139 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off); ---- -Parse { - cst: SourceFile@0..71 - IndexStmt@0..71 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..22 "title_idx" - Whitespace@22..23 " " - On@23..25 "ON" - Whitespace@25..26 " " - RangeVar@26..31 - Ident@26..31 "films" - Whitespace@31..32 " " - Ascii40@32..33 "(" - IndexElem@33..38 - Ident@33..38 "title" - Ascii41@38..39 ")" - Whitespace@39..40 " " - With@40..44 "WITH" - Whitespace@44..45 " " - Ascii40@45..46 "(" - DefElem@46..69 - Ident@46..63 "deduplicate_items" - Whitespace@63..64 " " - Ascii61@64..65 "=" - Whitespace@65..66 " " - TypeName@66..69 - Off@66..69 "off" - Ascii41@69..70 ")" - Ascii59@70..71 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 26, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "deduplicate_items", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "off", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 66, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 46, - }, - ), - ), - }, - ], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..70, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@4.snap b/crates/parser/tests/snapshots/statements/valid/0051@4.snap deleted file mode 100644 index a516e1df..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@4.snap +++ /dev/null @@ -1,142 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX ON films ((lower(title))); ---- -Parse { - cst: SourceFile@0..39 - IndexStmt@0..39 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - On@13..15 "ON" - Whitespace@15..16 " " - RangeVar@16..21 - Ident@16..21 "films" - Whitespace@21..22 " " - Ascii40@22..23 "(" - Ascii40@23..24 "(" - IndexElem@24..35 - FuncCall@24..35 - Ident@24..29 "lower" - Ascii40@29..30 "(" - ColumnRef@30..35 - Ident@30..35 "title" - Ascii41@35..36 ")" - Ascii41@36..37 ")" - Ascii41@37..38 ")" - Ascii59@38..39 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 16, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "", - expr: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "lower", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "title", - }, - ), - ), - }, - ], - location: 30, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 24, - }, - ), - ), - }, - ), - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..38, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@5.snap b/crates/parser/tests/snapshots/statements/valid/0051@5.snap deleted file mode 100644 index ed65b7e7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@5.snap +++ /dev/null @@ -1,100 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE INDEX title_idx_german ON films (title COLLATE \"de_DE\");" ---- -Parse { - cst: SourceFile@0..63 - IndexStmt@0..63 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..29 "title_idx_german" - Whitespace@29..30 " " - On@30..32 "ON" - Whitespace@32..33 " " - RangeVar@33..38 - Ident@33..38 "films" - Whitespace@38..39 " " - Ascii40@39..40 "(" - IndexElem@40..61 - Ident@40..45 "title" - Whitespace@45..46 " " - Collate@46..53 "COLLATE" - Whitespace@53..54 " " - Ident@54..61 "\"de_DE\"" - Ascii41@61..62 ")" - Ascii59@62..63 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx_german", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 33, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [ - Node { - node: Some( - String( - String { - sval: "de_DE", - }, - ), - ), - }, - ], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..62, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@6.snap b/crates/parser/tests/snapshots/statements/valid/0051@6.snap deleted file mode 100644 index 8c3a5294..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@6.snap +++ /dev/null @@ -1,90 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST); ---- -Parse { - cst: SourceFile@0..62 - IndexStmt@0..62 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..32 "title_idx_nulls_low" - Whitespace@32..33 " " - On@33..35 "ON" - Whitespace@35..36 " " - RangeVar@36..41 - Ident@36..41 "films" - Whitespace@41..42 " " - Ascii40@42..43 "(" - IndexElem@43..60 - Ident@43..48 "title" - Whitespace@48..49 " " - NullsP@49..54 "NULLS" - Whitespace@54..55 " " - FirstP@55..60 "FIRST" - Ascii41@60..61 ")" - Ascii59@61..62 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx_nulls_low", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 36, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsFirst, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..61, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@7.snap b/crates/parser/tests/snapshots/statements/valid/0051@7.snap deleted file mode 100644 index f608de5e..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@7.snap +++ /dev/null @@ -1,123 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70); ---- -Parse { - cst: SourceFile@0..70 - IndexStmt@0..70 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Unique@7..13 "UNIQUE" - Whitespace@13..14 " " - Index@14..19 "INDEX" - Whitespace@19..20 " " - Ident@20..29 "title_idx" - Whitespace@29..30 " " - On@30..32 "ON" - Whitespace@32..33 " " - RangeVar@33..38 - Ident@33..38 "films" - Whitespace@38..39 " " - Ascii40@39..40 "(" - IndexElem@40..45 - Ident@40..45 "title" - Ascii41@45..46 ")" - Whitespace@46..47 " " - With@47..51 "WITH" - Whitespace@51..52 " " - Ascii40@52..53 "(" - DefElem@53..68 - Ident@53..63 "fillfactor" - Whitespace@63..64 " " - Ascii61@64..65 "=" - Whitespace@65..66 " " - Iconst@66..68 "70" - Ascii41@68..69 ")" - Ascii59@69..70 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "title_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 33, - }, - ), - access_method: "btree", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "title", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "fillfactor", - arg: Some( - Node { - node: Some( - Integer( - Integer { - ival: 70, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 53, - }, - ), - ), - }, - ], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: true, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..69, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@8.snap b/crates/parser/tests/snapshots/statements/valid/0051@8.snap deleted file mode 100644 index 5bd6febc..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@8.snap +++ /dev/null @@ -1,143 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off); ---- -Parse { - cst: SourceFile@0..86 - IndexStmt@0..86 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..20 "gin_idx" - Whitespace@20..21 " " - On@21..23 "ON" - Whitespace@23..24 " " - RangeVar@24..39 - Ident@24..39 "documents_table" - Whitespace@39..40 " " - Using@40..45 "USING" - Whitespace@45..46 " " - Ident@46..49 "GIN" - Whitespace@49..50 " " - Ascii40@50..51 "(" - IndexElem@51..60 - Ident@51..60 "locations" - Ascii41@60..61 ")" - Whitespace@61..62 " " - With@62..66 "WITH" - Whitespace@66..67 " " - Ascii40@67..68 "(" - DefElem@68..84 - Ident@68..78 "fastupdate" - Whitespace@78..79 " " - Ascii61@79..80 "=" - Whitespace@80..81 " " - TypeName@81..84 - Off@81..84 "off" - Ascii41@84..85 ")" - Ascii59@85..86 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "gin_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "documents_table", - inh: true, - relpersistence: "p", - alias: None, - location: 24, - }, - ), - access_method: "gin", - table_space: "", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "locations", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "fastupdate", - arg: Some( - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "off", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 81, - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 68, - }, - ), - ), - }, - ], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..85, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0051@9.snap b/crates/parser/tests/snapshots/statements/valid/0051@9.snap deleted file mode 100644 index a9be4d38..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0051@9.snap +++ /dev/null @@ -1,90 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE INDEX code_idx ON films (code) TABLESPACE indexspace; ---- -Parse { - cst: SourceFile@0..60 - IndexStmt@0..60 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Index@7..12 "INDEX" - Whitespace@12..13 " " - Ident@13..21 "code_idx" - Whitespace@21..22 " " - On@22..24 "ON" - Whitespace@24..25 " " - RangeVar@25..30 - Ident@25..30 "films" - Whitespace@30..31 " " - Ascii40@31..32 "(" - IndexElem@32..36 - Ident@32..36 "code" - Ascii41@36..37 ")" - Whitespace@37..38 " " - Tablespace@38..48 "TABLESPACE" - Whitespace@48..49 " " - Ident@49..59 "indexspace" - Ascii59@59..60 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: IndexStmt( - IndexStmt { - idxname: "code_idx", - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "films", - inh: true, - relpersistence: "p", - alias: None, - location: 25, - }, - ), - access_method: "btree", - table_space: "indexspace", - index_params: [ - Node { - node: Some( - IndexElem( - IndexElem { - name: "code", - expr: None, - indexcolname: "", - collation: [], - opclass: [], - opclassopts: [], - ordering: SortbyDefault, - nulls_ordering: SortbyNullsDefault, - }, - ), - ), - }, - ], - index_including_params: [], - options: [], - where_clause: None, - exclude_op_names: [], - idxcomment: "", - index_oid: 0, - old_node: 0, - old_create_subid: 0, - old_first_relfilenode_subid: 0, - unique: false, - nulls_not_distinct: false, - primary: false, - isconstraint: false, - deferrable: false, - initdeferred: false, - transformed: false, - concurrent: false, - if_not_exists: false, - reset_default_tblspc: false, - }, - ), - range: 0..59, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0052@1.snap b/crates/parser/tests/snapshots/statements/valid/0052@1.snap deleted file mode 100644 index f028c9b7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0052@1.snap +++ /dev/null @@ -1,34 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b);$$;" ---- -Parse { - cst: SourceFile@0..127 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Procedure@7..16 "PROCEDURE" - Whitespace@16..17 " " - Ident@17..28 "insert_data" - Ascii40@28..29 "(" - Ident@29..30 "a" - Whitespace@30..31 " " - Integer@31..38 "integer" - Ascii44@38..39 "," - Whitespace@39..40 " " - Ident@40..41 "b" - Whitespace@41..42 " " - Integer@42..49 "integer" - Ascii41@49..50 ")" - Whitespace@50..51 " " - Language@51..59 "LANGUAGE" - Whitespace@59..60 " " - SqlP@60..63 "SQL" - Whitespace@63..64 " " - As@64..66 "AS" - Whitespace@66..67 " " - Sconst@67..126 "$$INSERT INTO tbl VAL ..." - Ascii59@126..127 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0052@2.snap b/crates/parser/tests/snapshots/statements/valid/0052@2.snap deleted file mode 100644 index 7815a6e0..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0052@2.snap +++ /dev/null @@ -1,247 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;" ---- -Parse { - cst: SourceFile@0..134 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Procedure@7..16 "PROCEDURE" - Whitespace@16..17 " " - Ident@17..28 "insert_data" - Ascii40@28..29 "(" - Ident@29..30 "a" - Whitespace@30..31 " " - Integer@31..38 "integer" - Ascii44@38..39 "," - Whitespace@39..40 " " - Ident@40..41 "b" - Whitespace@41..42 " " - Integer@42..49 "integer" - Ascii41@49..50 ")" - Whitespace@50..51 " " - Language@51..59 "LANGUAGE" - Whitespace@59..60 " " - SqlP@60..63 "SQL" - BeginP@63..68 "BEGIN" - Whitespace@68..69 " " - Atomic@69..75 "ATOMIC" - InsertStmt@75..102 - Insert@75..81 "INSERT" - Whitespace@81..82 " " - Into@82..86 "INTO" - Whitespace@86..87 " " - RangeVar@87..90 - Ident@87..90 "tbl" - Whitespace@90..91 " " - SelectStmt@91..100 - Values@91..97 "VALUES" - Whitespace@97..98 " " - Ascii40@98..99 "(" - List@99..100 - ColumnRef@99..100 - Ident@99..100 "a" - Ascii41@100..101 ")" - Ascii59@101..102 ";" - InsertStmt@102..129 - Insert@102..108 "INSERT" - Whitespace@108..109 " " - Into@109..113 "INTO" - Whitespace@113..114 " " - RangeVar@114..117 - Ident@114..117 "tbl" - Whitespace@117..118 " " - SelectStmt@118..127 - Values@118..124 "VALUES" - Whitespace@124..125 " " - Ascii40@125..126 "(" - List@126..127 - ColumnRef@126..127 - Ident@126..127 "b" - Ascii41@127..128 ")" - Ascii59@128..129 ";" - Whitespace@129..130 " " - EndP@130..133 "END" - Ascii59@133..134 ";" - , - errors: [ - SyntaxError( - "Expected Ascii59, found Whitespace", - 76..76, - ), - SyntaxError( - "Invalid statement: syntax error at or near \"ATOMIC\"", - 20..23, - ), - ], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "a", - }, - ), - ), - }, - ], - location: 24, - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 76..104, - }, - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "b", - }, - ), - ), - }, - ], - location: 24, - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 104..132, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@1.snap b/crates/parser/tests/snapshots/statements/valid/0053@1.snap deleted file mode 100644 index 93bc15fd..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@1.snap +++ /dev/null @@ -1,101 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PUBLICATION mypublication FOR TABLE users, departments;" ---- -Parse { - cst: SourceFile@0..62 - CreatePublicationStmt@0..62 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..32 "mypublication" - Whitespace@32..33 " " - For@33..36 "FOR" - Whitespace@36..37 " " - Table@37..42 "TABLE" - Whitespace@42..43 " " - PublicationObjSpec@43..48 - PublicationTable@43..48 - RangeVar@43..48 - Ident@43..48 "users" - Ascii44@48..49 "," - Whitespace@49..50 " " - PublicationObjSpec@50..61 - PublicationTable@50..61 - RangeVar@50..61 - Ident@50..61 "departments" - Ascii59@61..62 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "mypublication", - options: [], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 43, - }, - ), - where_clause: None, - columns: [], - }, - ), - location: 0, - }, - ), - ), - }, - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "departments", - inh: true, - relpersistence: "p", - alias: None, - location: 50, - }, - ), - where_clause: None, - columns: [], - }, - ), - location: 50, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..61, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@2.snap b/crates/parser/tests/snapshots/statements/valid/0053@2.snap deleted file mode 100644 index 9cba1ecd..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@2.snap +++ /dev/null @@ -1,113 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE); ---- -Parse { - cst: SourceFile@0..83 - CreatePublicationStmt@0..83 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..37 "active_departments" - Whitespace@37..38 " " - For@38..41 "FOR" - Whitespace@41..42 " " - Table@42..47 "TABLE" - Whitespace@47..48 " " - PublicationObjSpec@48..81 - PublicationTable@48..81 - RangeVar@48..59 - Ident@48..59 "departments" - Whitespace@59..60 " " - Where@60..65 "WHERE" - Whitespace@65..66 " " - Ascii40@66..67 "(" - BooleanTest@67..81 - ColumnRef@67..73 - Ident@67..73 "active" - Whitespace@73..74 " " - Is@74..76 "IS" - Whitespace@76..77 " " - TrueP@77..81 "TRUE" - Ascii41@81..82 ")" - Ascii59@82..83 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "active_departments", - options: [], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "departments", - inh: true, - relpersistence: "p", - alias: None, - location: 48, - }, - ), - where_clause: Some( - Node { - node: Some( - BooleanTest( - BooleanTest { - xpr: None, - arg: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "active", - }, - ), - ), - }, - ], - location: 67, - }, - ), - ), - }, - ), - booltesttype: IsTrue, - location: 74, - }, - ), - ), - }, - ), - columns: [], - }, - ), - location: 0, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..82, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@3.snap b/crates/parser/tests/snapshots/statements/valid/0053@3.snap deleted file mode 100644 index 988c4acb..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@3.snap +++ /dev/null @@ -1,35 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: CREATE PUBLICATION alltables FOR ALL TABLES; ---- -Parse { - cst: SourceFile@0..44 - CreatePublicationStmt@0..44 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..28 "alltables" - Whitespace@28..29 " " - For@29..32 "FOR" - Whitespace@32..33 " " - All@33..36 "ALL" - Whitespace@36..37 " " - Tables@37..43 "TABLES" - Ascii59@43..44 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "alltables", - options: [], - pubobjects: [], - for_all_tables: true, - }, - ), - range: 0..43, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@4.snap b/crates/parser/tests/snapshots/statements/valid/0053@4.snap deleted file mode 100644 index 73d2ab6b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@4.snap +++ /dev/null @@ -1,102 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PUBLICATION insert_only FOR TABLE mydata WITH (publish = 'insert');" ---- -Parse { - cst: SourceFile@0..74 - CreatePublicationStmt@0..74 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..30 "insert_only" - Whitespace@30..31 " " - For@31..34 "FOR" - Whitespace@34..35 " " - Table@35..40 "TABLE" - Whitespace@40..41 " " - PublicationObjSpec@41..47 - PublicationTable@41..47 - RangeVar@41..47 - Ident@41..47 "mydata" - Whitespace@47..48 " " - With@48..52 "WITH" - Whitespace@52..53 " " - Ascii40@53..54 "(" - DefElem@54..72 - Ident@54..61 "publish" - Whitespace@61..62 " " - Ascii61@62..63 "=" - Whitespace@63..64 " " - Sconst@64..72 "'insert'" - Ascii41@72..73 ")" - Ascii59@73..74 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "insert_only", - options: [ - Node { - node: Some( - DefElem( - DefElem { - defnamespace: "", - defname: "publish", - arg: Some( - Node { - node: Some( - String( - String { - sval: "insert", - }, - ), - ), - }, - ), - defaction: DefelemUnspec, - location: 54, - }, - ), - ), - }, - ], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "mydata", - inh: true, - relpersistence: "p", - alias: None, - location: 41, - }, - ), - where_clause: None, - columns: [], - }, - ), - location: 0, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..73, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@5.snap b/crates/parser/tests/snapshots/statements/valid/0053@5.snap deleted file mode 100644 index 30366130..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@5.snap +++ /dev/null @@ -1,123 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;" ---- -Parse { - cst: SourceFile@0..100 - CreatePublicationStmt@0..100 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..41 "production_publication" - Whitespace@41..42 " " - For@42..45 "FOR" - Whitespace@45..46 " " - Table@46..51 "TABLE" - Whitespace@51..52 " " - PublicationObjSpec@52..57 - PublicationTable@52..57 - RangeVar@52..57 - Ident@52..57 "users" - Ascii44@57..58 "," - Whitespace@58..59 " " - PublicationObjSpec@59..70 - PublicationTable@59..70 - RangeVar@59..70 - Ident@59..70 "departments" - Ascii44@70..71 "," - Whitespace@71..72 " " - Tables@72..78 "TABLES" - Whitespace@78..79 " " - InP@79..81 "IN" - Whitespace@81..82 " " - Schema@82..88 "SCHEMA" - Whitespace@88..89 " " - PublicationObjSpec@89..99 - Ident@89..99 "production" - Ascii59@99..100 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "production_publication", - options: [], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 52, - }, - ), - where_clause: None, - columns: [], - }, - ), - location: 0, - }, - ), - ), - }, - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "departments", - inh: true, - relpersistence: "p", - alias: None, - location: 59, - }, - ), - where_clause: None, - columns: [], - }, - ), - location: 59, - }, - ), - ), - }, - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTablesInSchema, - name: "production", - pubtable: None, - location: 89, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..99, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@6.snap b/crates/parser/tests/snapshots/statements/valid/0053@6.snap deleted file mode 100644 index cf552bd2..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@6.snap +++ /dev/null @@ -1,69 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;" ---- -Parse { - cst: SourceFile@0..75 - CreatePublicationStmt@0..75 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..36 "sales_publication" - Whitespace@36..37 " " - For@37..40 "FOR" - Whitespace@40..41 " " - Tables@41..47 "TABLES" - Whitespace@47..48 " " - InP@48..50 "IN" - Whitespace@50..51 " " - Schema@51..57 "SCHEMA" - Whitespace@57..58 " " - PublicationObjSpec@58..67 - Ident@58..67 "marketing" - Ascii44@67..68 "," - Whitespace@68..69 " " - PublicationObjSpec@69..74 - Ident@69..74 "sales" - Ascii59@74..75 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "sales_publication", - options: [], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTablesInSchema, - name: "marketing", - pubtable: None, - location: 58, - }, - ), - ), - }, - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTablesInSchema, - name: "sales", - pubtable: None, - location: 69, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..74, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0053@7.snap b/crates/parser/tests/snapshots/statements/valid/0053@7.snap deleted file mode 100644 index a23e6d48..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0053@7.snap +++ /dev/null @@ -1,93 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);" ---- -Parse { - cst: SourceFile@0..71 - CreatePublicationStmt@0..71 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Publication@7..18 "PUBLICATION" - Whitespace@18..19 " " - Ident@19..33 "users_filtered" - Whitespace@33..34 " " - For@34..37 "FOR" - Whitespace@37..38 " " - Table@38..43 "TABLE" - Whitespace@43..44 " " - PublicationObjSpec@44..69 - PublicationTable@44..69 - RangeVar@44..49 - Ident@44..49 "users" - Whitespace@49..50 " " - Ascii40@50..51 "(" - Ident@51..58 "user_id" - Ascii44@58..59 "," - Whitespace@59..60 " " - Ident@60..69 "firstname" - Ascii41@69..70 ")" - Ascii59@70..71 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreatePublicationStmt( - CreatePublicationStmt { - pubname: "users_filtered", - options: [], - pubobjects: [ - Node { - node: Some( - PublicationObjSpec( - PublicationObjSpec { - pubobjtype: PublicationobjTable, - name: "", - pubtable: Some( - PublicationTable { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 44, - }, - ), - where_clause: None, - columns: [ - Node { - node: Some( - String( - String { - sval: "user_id", - }, - ), - ), - }, - Node { - node: Some( - String( - String { - sval: "firstname", - }, - ), - ), - }, - ], - }, - ), - location: 0, - }, - ), - ), - }, - ], - for_all_tables: false, - }, - ), - range: 0..70, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0054@1.snap b/crates/parser/tests/snapshots/statements/valid/0054@1.snap deleted file mode 100644 index 385e235f..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0054@1.snap +++ /dev/null @@ -1,62 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" ---- -Parse { - cst: SourceFile@0..60 - CreateConversionStmt@0..60 - Create@0..6 "CREATE" - Whitespace@6..7 " " - ConversionP@7..17 "CONVERSION" - Whitespace@17..18 " " - Ident@18..24 "myconv" - Whitespace@24..25 " " - For@25..28 "FOR" - Whitespace@28..29 " " - Sconst@29..35 "'UTF8'" - Whitespace@35..36 " " - To@36..38 "TO" - Whitespace@38..39 " " - Sconst@39..47 "'LATIN1'" - Whitespace@47..48 " " - From@48..52 "FROM" - Whitespace@52..53 " " - Ident@53..59 "myfunc" - Ascii59@59..60 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateConversionStmt( - CreateConversionStmt { - conversion_name: [ - Node { - node: Some( - String( - String { - sval: "myconv", - }, - ), - ), - }, - ], - for_encoding_name: "UTF8", - to_encoding_name: "LATIN1", - func_name: [ - Node { - node: Some( - String( - String { - sval: "myfunc", - }, - ), - ), - }, - ], - def: false, - }, - ), - range: 0..59, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0054@2.snap b/crates/parser/tests/snapshots/statements/valid/0054@2.snap deleted file mode 100644 index 42806a70..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0054@2.snap +++ /dev/null @@ -1,64 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" ---- -Parse { - cst: SourceFile@0..68 - CreateConversionStmt@0..68 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Default@7..14 "DEFAULT" - Whitespace@14..15 " " - ConversionP@15..25 "CONVERSION" - Whitespace@25..26 " " - Ident@26..32 "myconv" - Whitespace@32..33 " " - For@33..36 "FOR" - Whitespace@36..37 " " - Sconst@37..43 "'UTF8'" - Whitespace@43..44 " " - To@44..46 "TO" - Whitespace@46..47 " " - Sconst@47..55 "'LATIN1'" - Whitespace@55..56 " " - From@56..60 "FROM" - Whitespace@60..61 " " - Ident@61..67 "myfunc" - Ascii59@67..68 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateConversionStmt( - CreateConversionStmt { - conversion_name: [ - Node { - node: Some( - String( - String { - sval: "myconv", - }, - ), - ), - }, - ], - for_encoding_name: "UTF8", - to_encoding_name: "LATIN1", - func_name: [ - Node { - node: Some( - String( - String { - sval: "myfunc", - }, - ), - ), - }, - ], - def: true, - }, - ), - range: 0..67, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0055@1.snap b/crates/parser/tests/snapshots/statements/valid/0055@1.snap deleted file mode 100644 index 5fd77413..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0055@1.snap +++ /dev/null @@ -1,165 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: select 1 union all select 2; ---- -Parse { - cst: SourceFile@0..28 - SelectStmt@0..28 - Select@0..6 "select" - Whitespace@6..7 " " - SelectStmt@7..8 - ResTarget@7..8 - AConst@7..8 - Iconst@7..8 "1" - Whitespace@8..9 " " - Union@9..14 "union" - Whitespace@14..15 " " - All@15..18 "all" - Whitespace@18..19 " " - SelectStmt@19..27 - Select@19..25 "select" - Whitespace@25..26 " " - ResTarget@26..27 - AConst@26..27 - Iconst@26..27 "2" - Ascii59@27..28 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopUnion, - all: true, - larg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 7, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - rarg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 26, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - }, - ), - range: 0..27, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0055@2.snap b/crates/parser/tests/snapshots/statements/valid/0055@2.snap deleted file mode 100644 index 96be67fc..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0055@2.snap +++ /dev/null @@ -1,163 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: select 1 union select 2; ---- -Parse { - cst: SourceFile@0..24 - SelectStmt@0..24 - Select@0..6 "select" - Whitespace@6..7 " " - SelectStmt@7..8 - ResTarget@7..8 - AConst@7..8 - Iconst@7..8 "1" - Whitespace@8..9 " " - Union@9..14 "union" - Whitespace@14..15 " " - SelectStmt@15..23 - Select@15..21 "select" - Whitespace@21..22 " " - ResTarget@22..23 - AConst@22..23 - Iconst@22..23 "2" - Ascii59@23..24 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopUnion, - all: false, - larg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 7, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - rarg: Some( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 22, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ), - location: 22, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - }, - ), - range: 0..23, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0056@1.snap b/crates/parser/tests/snapshots/statements/valid/0056@1.snap deleted file mode 100644 index c378ba0f..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0056@1.snap +++ /dev/null @@ -1,251 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE TRANSFORM FOR hstore LANGUAGE plpython3u (\n FROM SQL WITH FUNCTION hstore_to_plpython(internal),\n TO SQL WITH FUNCTION plpython_to_hstore(internal)\n);" ---- -Parse { - cst: SourceFile@0..163 - CreateTransformStmt@0..163 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Transform@7..16 "TRANSFORM" - Whitespace@16..17 " " - For@17..20 "FOR" - Whitespace@20..21 " " - TypeName@21..27 - Ident@21..27 "hstore" - Whitespace@27..28 " " - Language@28..36 "LANGUAGE" - Whitespace@36..37 " " - Ident@37..47 "plpython3u" - Whitespace@47..48 " " - Ascii40@48..49 "(" - Newline@49..50 "\n" - Whitespace@50..54 " " - From@54..58 "FROM" - Whitespace@58..59 " " - SqlP@59..62 "SQL" - Whitespace@62..63 " " - With@63..67 "WITH" - Whitespace@67..68 " " - Function@68..76 "FUNCTION" - Whitespace@76..77 " " - ObjectWithArgs@77..107 - Ident@77..95 "hstore_to_plpython" - Ascii40@95..96 "(" - TypeName@96..104 - Ident@96..104 "internal" - Ascii41@104..105 ")" - Ascii44@105..106 "," - Newline@106..107 "\n" - Whitespace@107..111 " " - To@111..113 "TO" - Whitespace@113..114 " " - SqlP@114..117 "SQL" - Whitespace@117..118 " " - With@118..122 "WITH" - Whitespace@122..123 " " - Function@123..131 "FUNCTION" - Whitespace@131..132 " " - ObjectWithArgs@132..163 - Ident@132..150 "plpython_to_hstore" - Ascii40@150..151 "(" - TypeName@151..159 - Ident@151..159 "internal" - Ascii41@159..160 ")" - Newline@160..161 "\n" - Ascii41@161..162 ")" - Ascii59@162..163 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateTransformStmt( - CreateTransformStmt { - replace: false, - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "hstore", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 21, - }, - ), - lang: "plpython3u", - fromsql: Some( - ObjectWithArgs { - objname: [ - Node { - node: Some( - String( - String { - sval: "hstore_to_plpython", - }, - ), - ), - }, - ], - objargs: [ - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 96, - }, - ), - ), - }, - ], - objfuncargs: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 96, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - args_unspecified: false, - }, - ), - tosql: Some( - ObjectWithArgs { - objname: [ - Node { - node: Some( - String( - String { - sval: "plpython_to_hstore", - }, - ), - ), - }, - ], - objargs: [ - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 151, - }, - ), - ), - }, - ], - objfuncargs: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 151, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - args_unspecified: false, - }, - ), - }, - ), - range: 0..162, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0056@2.snap b/crates/parser/tests/snapshots/statements/valid/0056@2.snap deleted file mode 100644 index d9ee6d34..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0056@2.snap +++ /dev/null @@ -1,255 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "CREATE OR REPLACE TRANSFORM FOR hstore LANGUAGE plpython3u (\n FROM SQL WITH FUNCTION hstore_to_plpython(internal),\n TO SQL WITH FUNCTION plpython_to_hstore(internal)\n);" ---- -Parse { - cst: SourceFile@0..174 - CreateTransformStmt@0..174 - Create@0..6 "CREATE" - Whitespace@6..7 " " - Or@7..9 "OR" - Whitespace@9..10 " " - Replace@10..17 "REPLACE" - Whitespace@17..18 " " - Transform@18..27 "TRANSFORM" - Whitespace@27..28 " " - For@28..31 "FOR" - Whitespace@31..32 " " - TypeName@32..38 - Ident@32..38 "hstore" - Whitespace@38..39 " " - Language@39..47 "LANGUAGE" - Whitespace@47..48 " " - Ident@48..58 "plpython3u" - Whitespace@58..59 " " - Ascii40@59..60 "(" - Newline@60..61 "\n" - Whitespace@61..65 " " - From@65..69 "FROM" - Whitespace@69..70 " " - SqlP@70..73 "SQL" - Whitespace@73..74 " " - With@74..78 "WITH" - Whitespace@78..79 " " - Function@79..87 "FUNCTION" - Whitespace@87..88 " " - ObjectWithArgs@88..118 - Ident@88..106 "hstore_to_plpython" - Ascii40@106..107 "(" - TypeName@107..115 - Ident@107..115 "internal" - Ascii41@115..116 ")" - Ascii44@116..117 "," - Newline@117..118 "\n" - Whitespace@118..122 " " - To@122..124 "TO" - Whitespace@124..125 " " - SqlP@125..128 "SQL" - Whitespace@128..129 " " - With@129..133 "WITH" - Whitespace@133..134 " " - Function@134..142 "FUNCTION" - Whitespace@142..143 " " - ObjectWithArgs@143..174 - Ident@143..161 "plpython_to_hstore" - Ascii40@161..162 "(" - TypeName@162..170 - Ident@162..170 "internal" - Ascii41@170..171 ")" - Newline@171..172 "\n" - Ascii41@172..173 ")" - Ascii59@173..174 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateTransformStmt( - CreateTransformStmt { - replace: true, - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "hstore", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 32, - }, - ), - lang: "plpython3u", - fromsql: Some( - ObjectWithArgs { - objname: [ - Node { - node: Some( - String( - String { - sval: "hstore_to_plpython", - }, - ), - ), - }, - ], - objargs: [ - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 107, - }, - ), - ), - }, - ], - objfuncargs: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 107, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - args_unspecified: false, - }, - ), - tosql: Some( - ObjectWithArgs { - objname: [ - Node { - node: Some( - String( - String { - sval: "plpython_to_hstore", - }, - ), - ), - }, - ], - objargs: [ - Node { - node: Some( - TypeName( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 162, - }, - ), - ), - }, - ], - objfuncargs: [ - Node { - node: Some( - FunctionParameter( - FunctionParameter { - name: "", - arg_type: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "internal", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 162, - }, - ), - mode: FuncParamDefault, - defexpr: None, - }, - ), - ), - }, - ], - args_unspecified: false, - }, - ), - }, - ), - range: 0..173, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@1.snap b/crates/parser/tests/snapshots/statements/valid/0057@1.snap deleted file mode 100644 index 2f3f3705..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@1.snap +++ /dev/null @@ -1,50 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE users CONTINUE IDENTITY RESTRICT; ---- -Parse { - cst: SourceFile@0..42 - TruncateStmt@0..42 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - RangeVar@9..14 - Ident@9..14 "users" - Whitespace@14..15 " " - ContinueP@15..23 "CONTINUE" - Whitespace@23..24 " " - IdentityP@24..32 "IDENTITY" - Whitespace@32..33 " " - Restrict@33..41 "RESTRICT" - Ascii59@41..42 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 9, - }, - ), - ), - }, - ], - restart_seqs: false, - behavior: DropRestrict, - }, - ), - range: 0..41, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@2.snap b/crates/parser/tests/snapshots/statements/valid/0057@2.snap deleted file mode 100644 index 1072629c..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@2.snap +++ /dev/null @@ -1,52 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE TABLE users RESTART IDENTITY CASCADE; ---- -Parse { - cst: SourceFile@0..46 - TruncateStmt@0..46 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - Table@9..14 "TABLE" - Whitespace@14..15 " " - RangeVar@15..20 - Ident@15..20 "users" - Whitespace@20..21 " " - Restart@21..28 "RESTART" - Whitespace@28..29 " " - IdentityP@29..37 "IDENTITY" - Whitespace@37..38 " " - Cascade@38..45 "CASCADE" - Ascii59@45..46 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 15, - }, - ), - ), - }, - ], - restart_seqs: true, - behavior: DropCascade, - }, - ), - range: 0..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@3.snap b/crates/parser/tests/snapshots/statements/valid/0057@3.snap deleted file mode 100644 index cbc0dbad..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@3.snap +++ /dev/null @@ -1,44 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE users; ---- -Parse { - cst: SourceFile@0..15 - TruncateStmt@0..15 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - RangeVar@9..14 - Ident@9..14 "users" - Ascii59@14..15 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 9, - }, - ), - ), - }, - ], - restart_seqs: false, - behavior: DropRestrict, - }, - ), - range: 0..14, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@4.snap b/crates/parser/tests/snapshots/statements/valid/0057@4.snap deleted file mode 100644 index 524f90d1..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@4.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE accounts CASCADE; ---- -Parse { - cst: SourceFile@0..26 - TruncateStmt@0..26 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - RangeVar@9..17 - Ident@9..17 "accounts" - Whitespace@17..18 " " - Cascade@18..25 "CASCADE" - Ascii59@25..26 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "accounts", - inh: true, - relpersistence: "p", - alias: None, - location: 9, - }, - ), - ), - }, - ], - restart_seqs: false, - behavior: DropCascade, - }, - ), - range: 0..25, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@5.snap b/crates/parser/tests/snapshots/statements/valid/0057@5.snap deleted file mode 100644 index 974597ad..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@5.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE accounts RESTRICT; ---- -Parse { - cst: SourceFile@0..27 - TruncateStmt@0..27 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - RangeVar@9..17 - Ident@9..17 "accounts" - Whitespace@17..18 " " - Restrict@18..26 "RESTRICT" - Ascii59@26..27 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "accounts", - inh: true, - relpersistence: "p", - alias: None, - location: 9, - }, - ), - ), - }, - ], - restart_seqs: false, - behavior: DropRestrict, - }, - ), - range: 0..26, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/0057@6.snap b/crates/parser/tests/snapshots/statements/valid/0057@6.snap deleted file mode 100644 index ff4635f5..00000000 --- a/crates/parser/tests/snapshots/statements/valid/0057@6.snap +++ /dev/null @@ -1,46 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -assertion_line: 62 -description: TRUNCATE TABLE users; ---- -Parse { - cst: SourceFile@0..21 - TruncateStmt@0..21 - Truncate@0..8 "TRUNCATE" - Whitespace@8..9 " " - Table@9..14 "TABLE" - Whitespace@14..15 " " - RangeVar@15..20 - Ident@15..20 "users" - Ascii59@20..21 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TruncateStmt( - TruncateStmt { - relations: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "users", - inh: true, - relpersistence: "p", - alias: None, - location: 15, - }, - ), - ), - }, - ], - restart_seqs: false, - behavior: DropRestrict, - }, - ), - range: 0..20, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@1.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@1.snap deleted file mode 100644 index 0f825006..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@1.snap +++ /dev/null @@ -1,32 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "--\n-- ADVISORY LOCKS\n--\n\nBEGIN;" ---- -Parse { - cst: SourceFile@0..31 - SqlComment@0..2 "--" - Newline@2..3 "\n" - SqlComment@3..20 "-- ADVISORY LOCKS" - Newline@20..21 "\n" - SqlComment@21..23 "--" - Newline@23..25 "\n\n" - TransactionStmt@25..31 - BeginP@25..30 "BEGIN" - Ascii59@30..31 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtBegin, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 24..30, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@10.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@10.snap deleted file mode 100644 index 9577decd..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@10.snap +++ /dev/null @@ -1,363 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- holding both session and xact locks on the same objects, xact first\nSELECT\n\tpg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),\n\tpg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..203 - SqlComment@0..70 "-- holding both sessi ..." - Newline@70..71 "\n" - SelectStmt@71..203 - Select@71..77 "SELECT" - Newline@77..78 "\n" - Newline@78..79 "\t" - ResTarget@79..102 - FuncCall@79..102 - Ident@79..100 "pg_advisory_xact_lock" - Ascii40@100..101 "(" - AConst@101..102 - Iconst@101..102 "1" - Ascii41@102..103 ")" - Ascii44@103..104 "," - Whitespace@104..105 " " - ResTarget@105..135 - FuncCall@105..135 - Ident@105..133 "pg_advisory_xact_lock ..." - Ascii40@133..134 "(" - AConst@134..135 - Iconst@134..135 "2" - Ascii41@135..136 ")" - Ascii44@136..137 "," - Newline@137..138 "\n" - Newline@138..139 "\t" - ResTarget@139..165 - FuncCall@139..165 - Ident@139..160 "pg_advisory_xact_lock" - Ascii40@160..161 "(" - AConst@161..162 - Iconst@161..162 "1" - Ascii44@162..163 "," - Whitespace@163..164 " " - AConst@164..165 - Iconst@164..165 "1" - Ascii41@165..166 ")" - Ascii44@166..167 "," - Whitespace@167..168 " " - ResTarget@168..201 - FuncCall@168..201 - Ident@168..196 "pg_advisory_xact_lock ..." - Ascii40@196..197 "(" - AConst@197..198 - Iconst@197..198 "2" - Ascii44@198..199 "," - Whitespace@199..200 " " - AConst@200..201 - Iconst@200..201 "2" - Ascii41@201..202 ")" - Ascii59@202..203 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 30, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 63, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 34, - }, - ), - ), - }, - ), - location: 34, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 90, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 93, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 68, - }, - ), - ), - }, - ), - location: 68, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 126, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 129, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 97, - }, - ), - ), - }, - ), - location: 97, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 70..202, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@11.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@11.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@11.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@12.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@12.snap deleted file mode 100644 index cb6961c0..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@12.snap +++ /dev/null @@ -1,361 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT\n\tpg_advisory_lock(1), pg_advisory_lock_shared(2),\n\tpg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..112 - SelectStmt@0..112 - Select@0..6 "SELECT" - Newline@6..7 "\n" - Newline@7..8 "\t" - ResTarget@8..26 - FuncCall@8..26 - Ident@8..24 "pg_advisory_lock" - Ascii40@24..25 "(" - AConst@25..26 - Iconst@25..26 "1" - Ascii41@26..27 ")" - Ascii44@27..28 "," - Whitespace@28..29 " " - ResTarget@29..54 - FuncCall@29..54 - Ident@29..52 "pg_advisory_lock_shared" - Ascii40@52..53 "(" - AConst@53..54 - Iconst@53..54 "2" - Ascii41@54..55 ")" - Ascii44@55..56 "," - Newline@56..57 "\n" - Newline@57..58 "\t" - ResTarget@58..79 - FuncCall@58..79 - Ident@58..74 "pg_advisory_lock" - Ascii40@74..75 "(" - AConst@75..76 - Iconst@75..76 "1" - Ascii44@76..77 "," - Whitespace@77..78 " " - AConst@78..79 - Iconst@78..79 "1" - Ascii41@79..80 ")" - Ascii44@80..81 "," - Whitespace@81..82 " " - ResTarget@82..110 - FuncCall@82..110 - Ident@82..105 "pg_advisory_lock_shared" - Ascii40@105..106 "(" - AConst@106..107 - Iconst@106..107 "2" - Ascii44@107..108 "," - Whitespace@108..109 " " - AConst@109..110 - Iconst@109..110 "2" - Ascii41@110..111 ")" - Ascii59@111..112 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 25, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 53, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 29, - }, - ), - ), - }, - ), - location: 29, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 75, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 78, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 58, - }, - ), - ), - }, - ), - location: 58, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 106, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 109, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 82, - }, - ), - ), - }, - ), - location: 82, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..111, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@13.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@13.snap deleted file mode 100644 index b1814251..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@13.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: ROLLBACK; ---- -Parse { - cst: SourceFile@0..9 - Rollback@0..8 "ROLLBACK" - Ascii59@8..9 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@14.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@14.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@14.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@15.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@15.snap deleted file mode 100644 index ea3a97ec..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@15.snap +++ /dev/null @@ -1,683 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- unlocking session locks\nSELECT\n\tpg_advisory_unlock(1), pg_advisory_unlock(1),\n\tpg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2),\n\tpg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1),\n\tpg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..261 - SqlComment@0..26 "-- unlocking session ..." - Newline@26..27 "\n" - SelectStmt@27..261 - Select@27..33 "SELECT" - Newline@33..34 "\n" - Newline@34..35 "\t" - ResTarget@35..55 - FuncCall@35..55 - Ident@35..53 "pg_advisory_unlock" - Ascii40@53..54 "(" - AConst@54..55 - Iconst@54..55 "1" - Ascii41@55..56 ")" - Ascii44@56..57 "," - Whitespace@57..58 " " - ResTarget@58..78 - FuncCall@58..78 - Ident@58..76 "pg_advisory_unlock" - Ascii40@76..77 "(" - AConst@77..78 - Iconst@77..78 "1" - Ascii41@78..79 ")" - Ascii44@79..80 "," - Newline@80..81 "\n" - Newline@81..82 "\t" - ResTarget@82..109 - FuncCall@82..109 - Ident@82..107 "pg_advisory_unlock_sh ..." - Ascii40@107..108 "(" - AConst@108..109 - Iconst@108..109 "2" - Ascii41@109..110 ")" - Ascii44@110..111 "," - Whitespace@111..112 " " - ResTarget@112..139 - FuncCall@112..139 - Ident@112..137 "pg_advisory_unlock_sh ..." - Ascii40@137..138 "(" - AConst@138..139 - Iconst@138..139 "2" - Ascii41@139..140 ")" - Ascii44@140..141 "," - Newline@141..142 "\n" - Newline@142..143 "\t" - ResTarget@143..166 - FuncCall@143..166 - Ident@143..161 "pg_advisory_unlock" - Ascii40@161..162 "(" - AConst@162..163 - Iconst@162..163 "1" - Ascii44@163..164 "," - Whitespace@164..165 " " - AConst@165..166 - Iconst@165..166 "1" - Ascii41@166..167 ")" - Ascii44@167..168 "," - Whitespace@168..169 " " - ResTarget@169..192 - FuncCall@169..192 - Ident@169..187 "pg_advisory_unlock" - Ascii40@187..188 "(" - AConst@188..189 - Iconst@188..189 "1" - Ascii44@189..190 "," - Whitespace@190..191 " " - AConst@191..192 - Iconst@191..192 "1" - Ascii41@192..193 ")" - Ascii44@193..194 "," - Newline@194..195 "\n" - Newline@195..196 "\t" - ResTarget@196..226 - FuncCall@196..226 - Ident@196..221 "pg_advisory_unlock_sh ..." - Ascii40@221..222 "(" - AConst@222..223 - Iconst@222..223 "2" - Ascii44@223..224 "," - Whitespace@224..225 " " - AConst@225..226 - Iconst@225..226 "2" - Ascii41@226..227 ")" - Ascii44@227..228 "," - Whitespace@228..229 " " - ResTarget@229..259 - FuncCall@229..259 - Ident@229..254 "pg_advisory_unlock_sh ..." - Ascii40@254..255 "(" - AConst@255..256 - Iconst@255..256 "2" - Ascii44@256..257 "," - Whitespace@257..258 " " - AConst@258..259 - Iconst@258..259 "2" - Ascii41@259..260 ")" - Ascii59@260..261 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 27, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 50, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 31, - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 81, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 55, - }, - ), - ), - }, - ), - location: 55, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 111, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 85, - }, - ), - ), - }, - ), - location: 85, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 135, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 138, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 116, - }, - ), - ), - }, - ), - location: 116, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 161, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 164, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 142, - }, - ), - ), - }, - ), - location: 142, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 195, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 198, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 169, - }, - ), - ), - }, - ), - location: 169, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 228, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 231, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 202, - }, - ), - ), - }, - ), - location: 202, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 26..260, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@16.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@16.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@16.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@17.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@17.snap deleted file mode 100644 index 7c25e8c9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@17.snap +++ /dev/null @@ -1,26 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: BEGIN; ---- -Parse { - cst: SourceFile@0..6 - TransactionStmt@0..6 - BeginP@0..5 "BEGIN" - Ascii59@5..6 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtBegin, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 0..5, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@18.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@18.snap deleted file mode 100644 index 188649a7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@18.snap +++ /dev/null @@ -1,363 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- holding both session and xact locks on the same objects, session first\nSELECT\n\tpg_advisory_lock(1), pg_advisory_lock_shared(2),\n\tpg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..186 - SqlComment@0..73 "-- holding both sessi ..." - Newline@73..74 "\n" - SelectStmt@74..186 - Select@74..80 "SELECT" - Newline@80..81 "\n" - Newline@81..82 "\t" - ResTarget@82..100 - FuncCall@82..100 - Ident@82..98 "pg_advisory_lock" - Ascii40@98..99 "(" - AConst@99..100 - Iconst@99..100 "1" - Ascii41@100..101 ")" - Ascii44@101..102 "," - Whitespace@102..103 " " - ResTarget@103..128 - FuncCall@103..128 - Ident@103..126 "pg_advisory_lock_shared" - Ascii40@126..127 "(" - AConst@127..128 - Iconst@127..128 "2" - Ascii41@128..129 ")" - Ascii44@129..130 "," - Newline@130..131 "\n" - Newline@131..132 "\t" - ResTarget@132..153 - FuncCall@132..153 - Ident@132..148 "pg_advisory_lock" - Ascii40@148..149 "(" - AConst@149..150 - Iconst@149..150 "1" - Ascii44@150..151 "," - Whitespace@151..152 " " - AConst@152..153 - Iconst@152..153 "1" - Ascii41@153..154 ")" - Ascii44@154..155 "," - Whitespace@155..156 " " - ResTarget@156..184 - FuncCall@156..184 - Ident@156..179 "pg_advisory_lock_shared" - Ascii40@179..180 "(" - AConst@180..181 - Iconst@180..181 "2" - Ascii44@181..182 "," - Whitespace@182..183 " " - AConst@183..184 - Iconst@183..184 "2" - Ascii41@184..185 ")" - Ascii59@185..186 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 25, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 53, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 29, - }, - ), - ), - }, - ), - location: 29, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 75, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 78, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 58, - }, - ), - ), - }, - ), - location: 58, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 106, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 109, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 82, - }, - ), - ), - }, - ), - location: 82, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 73..185, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@19.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@19.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@19.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@2.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@2.snap deleted file mode 100644 index 97f7ae62..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@2.snap +++ /dev/null @@ -1,361 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT\n\tpg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),\n\tpg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..132 - SelectStmt@0..132 - Select@0..6 "SELECT" - Newline@6..7 "\n" - Newline@7..8 "\t" - ResTarget@8..31 - FuncCall@8..31 - Ident@8..29 "pg_advisory_xact_lock" - Ascii40@29..30 "(" - AConst@30..31 - Iconst@30..31 "1" - Ascii41@31..32 ")" - Ascii44@32..33 "," - Whitespace@33..34 " " - ResTarget@34..64 - FuncCall@34..64 - Ident@34..62 "pg_advisory_xact_lock ..." - Ascii40@62..63 "(" - AConst@63..64 - Iconst@63..64 "2" - Ascii41@64..65 ")" - Ascii44@65..66 "," - Newline@66..67 "\n" - Newline@67..68 "\t" - ResTarget@68..94 - FuncCall@68..94 - Ident@68..89 "pg_advisory_xact_lock" - Ascii40@89..90 "(" - AConst@90..91 - Iconst@90..91 "1" - Ascii44@91..92 "," - Whitespace@92..93 " " - AConst@93..94 - Iconst@93..94 "1" - Ascii41@94..95 ")" - Ascii44@95..96 "," - Whitespace@96..97 " " - ResTarget@97..130 - FuncCall@97..130 - Ident@97..125 "pg_advisory_xact_lock ..." - Ascii40@125..126 "(" - AConst@126..127 - Iconst@126..127 "2" - Ascii44@127..128 "," - Whitespace@128..129 " " - AConst@129..130 - Iconst@129..130 "2" - Ascii41@130..131 ")" - Ascii59@131..132 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 30, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 63, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 34, - }, - ), - ), - }, - ), - location: 34, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 90, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 93, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 68, - }, - ), - ), - }, - ), - location: 68, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 126, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 129, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 97, - }, - ), - ), - }, - ), - location: 97, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..131, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@20.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@20.snap deleted file mode 100644 index 97f7ae62..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@20.snap +++ /dev/null @@ -1,361 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT\n\tpg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),\n\tpg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..132 - SelectStmt@0..132 - Select@0..6 "SELECT" - Newline@6..7 "\n" - Newline@7..8 "\t" - ResTarget@8..31 - FuncCall@8..31 - Ident@8..29 "pg_advisory_xact_lock" - Ascii40@29..30 "(" - AConst@30..31 - Iconst@30..31 "1" - Ascii41@31..32 ")" - Ascii44@32..33 "," - Whitespace@33..34 " " - ResTarget@34..64 - FuncCall@34..64 - Ident@34..62 "pg_advisory_xact_lock ..." - Ascii40@62..63 "(" - AConst@63..64 - Iconst@63..64 "2" - Ascii41@64..65 ")" - Ascii44@65..66 "," - Newline@66..67 "\n" - Newline@67..68 "\t" - ResTarget@68..94 - FuncCall@68..94 - Ident@68..89 "pg_advisory_xact_lock" - Ascii40@89..90 "(" - AConst@90..91 - Iconst@90..91 "1" - Ascii44@91..92 "," - Whitespace@92..93 " " - AConst@93..94 - Iconst@93..94 "1" - Ascii41@94..95 ")" - Ascii44@95..96 "," - Whitespace@96..97 " " - ResTarget@97..130 - FuncCall@97..130 - Ident@97..125 "pg_advisory_xact_lock ..." - Ascii40@125..126 "(" - AConst@126..127 - Iconst@126..127 "2" - Ascii44@127..128 "," - Whitespace@128..129 " " - AConst@129..130 - Iconst@129..130 "2" - Ascii41@130..131 ")" - Ascii59@131..132 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 30, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 63, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 34, - }, - ), - ), - }, - ), - location: 34, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 90, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 93, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 68, - }, - ), - ), - }, - ), - location: 68, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 126, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 129, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 97, - }, - ), - ), - }, - ), - location: 97, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..131, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@21.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@21.snap deleted file mode 100644 index b1814251..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@21.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: ROLLBACK; ---- -Parse { - cst: SourceFile@0..9 - Rollback@0..8 "ROLLBACK" - Ascii59@8..9 ";" - , - errors: [], - stmts: [], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@22.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@22.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@22.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@23.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@23.snap deleted file mode 100644 index 52b8f1ba..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@23.snap +++ /dev/null @@ -1,92 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- releasing all session locks\nSELECT pg_advisory_unlock_all();" ---- -Parse { - cst: SourceFile@0..63 - SqlComment@0..30 "-- releasing all sess ..." - Newline@30..31 "\n" - SelectStmt@31..63 - Select@31..37 "SELECT" - Whitespace@37..38 " " - ResTarget@38..60 - FuncCall@38..60 - Ident@38..60 "pg_advisory_unlock_all" - Ascii40@60..61 "(" - Ascii41@61..62 ")" - Ascii59@62..63 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_all", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 30..62, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@24.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@24.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@24.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@25.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@25.snap deleted file mode 100644 index 7c25e8c9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@25.snap +++ /dev/null @@ -1,26 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: BEGIN; ---- -Parse { - cst: SourceFile@0..6 - TransactionStmt@0..6 - BeginP@0..5 "BEGIN" - Ascii59@5..6 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtBegin, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 0..5, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@26.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@26.snap deleted file mode 100644 index 72576733..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@26.snap +++ /dev/null @@ -1,683 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- grabbing txn locks multiple times\n\nSELECT\n\tpg_advisory_xact_lock(1), pg_advisory_xact_lock(1),\n\tpg_advisory_xact_lock_shared(2), pg_advisory_xact_lock_shared(2),\n\tpg_advisory_xact_lock(1, 1), pg_advisory_xact_lock(1, 1),\n\tpg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..296 - SqlComment@0..36 "-- grabbing txn locks ..." - Newline@36..38 "\n\n" - SelectStmt@38..296 - Select@38..44 "SELECT" - Newline@44..45 "\n" - Newline@45..46 "\t" - ResTarget@46..69 - FuncCall@46..69 - Ident@46..67 "pg_advisory_xact_lock" - Ascii40@67..68 "(" - AConst@68..69 - Iconst@68..69 "1" - Ascii41@69..70 ")" - Ascii44@70..71 "," - Whitespace@71..72 " " - ResTarget@72..95 - FuncCall@72..95 - Ident@72..93 "pg_advisory_xact_lock" - Ascii40@93..94 "(" - AConst@94..95 - Iconst@94..95 "1" - Ascii41@95..96 ")" - Ascii44@96..97 "," - Newline@97..98 "\n" - Newline@98..99 "\t" - ResTarget@99..129 - FuncCall@99..129 - Ident@99..127 "pg_advisory_xact_lock ..." - Ascii40@127..128 "(" - AConst@128..129 - Iconst@128..129 "2" - Ascii41@129..130 ")" - Ascii44@130..131 "," - Whitespace@131..132 " " - ResTarget@132..162 - FuncCall@132..162 - Ident@132..160 "pg_advisory_xact_lock ..." - Ascii40@160..161 "(" - AConst@161..162 - Iconst@161..162 "2" - Ascii41@162..163 ")" - Ascii44@163..164 "," - Newline@164..165 "\n" - Newline@165..166 "\t" - ResTarget@166..192 - FuncCall@166..192 - Ident@166..187 "pg_advisory_xact_lock" - Ascii40@187..188 "(" - AConst@188..189 - Iconst@188..189 "1" - Ascii44@189..190 "," - Whitespace@190..191 " " - AConst@191..192 - Iconst@191..192 "1" - Ascii41@192..193 ")" - Ascii44@193..194 "," - Whitespace@194..195 " " - ResTarget@195..221 - FuncCall@195..221 - Ident@195..216 "pg_advisory_xact_lock" - Ascii40@216..217 "(" - AConst@217..218 - Iconst@217..218 "1" - Ascii44@218..219 "," - Whitespace@219..220 " " - AConst@220..221 - Iconst@220..221 "1" - Ascii41@221..222 ")" - Ascii44@222..223 "," - Newline@223..224 "\n" - Newline@224..225 "\t" - ResTarget@225..258 - FuncCall@225..258 - Ident@225..253 "pg_advisory_xact_lock ..." - Ascii40@253..254 "(" - AConst@254..255 - Iconst@254..255 "2" - Ascii44@255..256 "," - Whitespace@256..257 " " - AConst@257..258 - Iconst@257..258 "2" - Ascii41@258..259 ")" - Ascii44@259..260 "," - Whitespace@260..261 " " - ResTarget@261..294 - FuncCall@261..294 - Ident@261..289 "pg_advisory_xact_lock ..." - Ascii40@289..290 "(" - AConst@290..291 - Iconst@290..291 "2" - Ascii44@291..292 "," - Whitespace@292..293 " " - AConst@293..294 - Iconst@293..294 "2" - Ascii41@294..295 ")" - Ascii59@295..296 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 30, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 56, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 34, - }, - ), - ), - }, - ), - location: 34, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 90, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 61, - }, - ), - ), - }, - ), - location: 61, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 123, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 94, - }, - ), - ), - }, - ), - location: 94, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 150, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 153, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 128, - }, - ), - ), - }, - ), - location: 128, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 179, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 182, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 157, - }, - ), - ), - }, - ), - location: 157, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 216, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 219, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 187, - }, - ), - ), - }, - ), - location: 187, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_xact_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 252, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 255, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 223, - }, - ), - ), - }, - ), - location: 223, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 37..295, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@27.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@27.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@27.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@28.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@28.snap deleted file mode 100644 index d8b7e592..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@28.snap +++ /dev/null @@ -1,26 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: COMMIT; ---- -Parse { - cst: SourceFile@0..7 - TransactionStmt@0..7 - Commit@0..6 "COMMIT" - Ascii59@6..7 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtCommit, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 0..6, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@29.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@29.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@29.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@3.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@3.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@3.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@30.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@30.snap deleted file mode 100644 index bde9f42b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@30.snap +++ /dev/null @@ -1,683 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- grabbing session locks multiple times\n\nSELECT\n\tpg_advisory_lock(1), pg_advisory_lock(1),\n\tpg_advisory_lock_shared(2), pg_advisory_lock_shared(2),\n\tpg_advisory_lock(1, 1), pg_advisory_lock(1, 1),\n\tpg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..260 - SqlComment@0..40 "-- grabbing session l ..." - Newline@40..42 "\n\n" - SelectStmt@42..260 - Select@42..48 "SELECT" - Newline@48..49 "\n" - Newline@49..50 "\t" - ResTarget@50..68 - FuncCall@50..68 - Ident@50..66 "pg_advisory_lock" - Ascii40@66..67 "(" - AConst@67..68 - Iconst@67..68 "1" - Ascii41@68..69 ")" - Ascii44@69..70 "," - Whitespace@70..71 " " - ResTarget@71..89 - FuncCall@71..89 - Ident@71..87 "pg_advisory_lock" - Ascii40@87..88 "(" - AConst@88..89 - Iconst@88..89 "1" - Ascii41@89..90 ")" - Ascii44@90..91 "," - Newline@91..92 "\n" - Newline@92..93 "\t" - ResTarget@93..118 - FuncCall@93..118 - Ident@93..116 "pg_advisory_lock_shared" - Ascii40@116..117 "(" - AConst@117..118 - Iconst@117..118 "2" - Ascii41@118..119 ")" - Ascii44@119..120 "," - Whitespace@120..121 " " - ResTarget@121..146 - FuncCall@121..146 - Ident@121..144 "pg_advisory_lock_shared" - Ascii40@144..145 "(" - AConst@145..146 - Iconst@145..146 "2" - Ascii41@146..147 ")" - Ascii44@147..148 "," - Newline@148..149 "\n" - Newline@149..150 "\t" - ResTarget@150..171 - FuncCall@150..171 - Ident@150..166 "pg_advisory_lock" - Ascii40@166..167 "(" - AConst@167..168 - Iconst@167..168 "1" - Ascii44@168..169 "," - Whitespace@169..170 " " - AConst@170..171 - Iconst@170..171 "1" - Ascii41@171..172 ")" - Ascii44@172..173 "," - Whitespace@173..174 " " - ResTarget@174..195 - FuncCall@174..195 - Ident@174..190 "pg_advisory_lock" - Ascii40@190..191 "(" - AConst@191..192 - Iconst@191..192 "1" - Ascii44@192..193 "," - Whitespace@193..194 " " - AConst@194..195 - Iconst@194..195 "1" - Ascii41@195..196 ")" - Ascii44@196..197 "," - Newline@197..198 "\n" - Newline@198..199 "\t" - ResTarget@199..227 - FuncCall@199..227 - Ident@199..222 "pg_advisory_lock_shared" - Ascii40@222..223 "(" - AConst@223..224 - Iconst@223..224 "2" - Ascii44@224..225 "," - Whitespace@225..226 " " - AConst@226..227 - Iconst@226..227 "2" - Ascii41@227..228 ")" - Ascii44@228..229 "," - Whitespace@229..230 " " - ResTarget@230..258 - FuncCall@230..258 - Ident@230..253 "pg_advisory_lock_shared" - Ascii40@253..254 "(" - AConst@254..255 - Iconst@254..255 "2" - Ascii44@255..256 "," - Whitespace@256..257 " " - AConst@257..258 - Iconst@257..258 "2" - Ascii41@258..259 ")" - Ascii59@259..260 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 25, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 46, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 29, - }, - ), - ), - }, - ), - location: 29, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 75, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 51, - }, - ), - ), - }, - ), - location: 51, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 103, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 79, - }, - ), - ), - }, - ), - location: 79, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 125, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 128, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 108, - }, - ), - ), - }, - ), - location: 108, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 149, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 152, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 132, - }, - ), - ), - }, - ), - location: 132, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 181, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 184, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 157, - }, - ), - ), - }, - ), - location: 157, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 212, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 215, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 188, - }, - ), - ), - }, - ), - location: 188, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 41..259, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@31.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@31.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@31.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@32.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@32.snap deleted file mode 100644 index a94d5971..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@32.snap +++ /dev/null @@ -1,681 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT\n\tpg_advisory_unlock(1), pg_advisory_unlock(1),\n\tpg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2),\n\tpg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1),\n\tpg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..234 - SelectStmt@0..234 - Select@0..6 "SELECT" - Newline@6..7 "\n" - Newline@7..8 "\t" - ResTarget@8..28 - FuncCall@8..28 - Ident@8..26 "pg_advisory_unlock" - Ascii40@26..27 "(" - AConst@27..28 - Iconst@27..28 "1" - Ascii41@28..29 ")" - Ascii44@29..30 "," - Whitespace@30..31 " " - ResTarget@31..51 - FuncCall@31..51 - Ident@31..49 "pg_advisory_unlock" - Ascii40@49..50 "(" - AConst@50..51 - Iconst@50..51 "1" - Ascii41@51..52 ")" - Ascii44@52..53 "," - Newline@53..54 "\n" - Newline@54..55 "\t" - ResTarget@55..82 - FuncCall@55..82 - Ident@55..80 "pg_advisory_unlock_sh ..." - Ascii40@80..81 "(" - AConst@81..82 - Iconst@81..82 "2" - Ascii41@82..83 ")" - Ascii44@83..84 "," - Whitespace@84..85 " " - ResTarget@85..112 - FuncCall@85..112 - Ident@85..110 "pg_advisory_unlock_sh ..." - Ascii40@110..111 "(" - AConst@111..112 - Iconst@111..112 "2" - Ascii41@112..113 ")" - Ascii44@113..114 "," - Newline@114..115 "\n" - Newline@115..116 "\t" - ResTarget@116..139 - FuncCall@116..139 - Ident@116..134 "pg_advisory_unlock" - Ascii40@134..135 "(" - AConst@135..136 - Iconst@135..136 "1" - Ascii44@136..137 "," - Whitespace@137..138 " " - AConst@138..139 - Iconst@138..139 "1" - Ascii41@139..140 ")" - Ascii44@140..141 "," - Whitespace@141..142 " " - ResTarget@142..165 - FuncCall@142..165 - Ident@142..160 "pg_advisory_unlock" - Ascii40@160..161 "(" - AConst@161..162 - Iconst@161..162 "1" - Ascii44@162..163 "," - Whitespace@163..164 " " - AConst@164..165 - Iconst@164..165 "1" - Ascii41@165..166 ")" - Ascii44@166..167 "," - Newline@167..168 "\n" - Newline@168..169 "\t" - ResTarget@169..199 - FuncCall@169..199 - Ident@169..194 "pg_advisory_unlock_sh ..." - Ascii40@194..195 "(" - AConst@195..196 - Iconst@195..196 "2" - Ascii44@196..197 "," - Whitespace@197..198 " " - AConst@198..199 - Iconst@198..199 "2" - Ascii41@199..200 ")" - Ascii44@200..201 "," - Whitespace@201..202 " " - ResTarget@202..232 - FuncCall@202..232 - Ident@202..227 "pg_advisory_unlock_sh ..." - Ascii40@227..228 "(" - AConst@228..229 - Iconst@228..229 "2" - Ascii44@229..230 "," - Whitespace@230..231 " " - AConst@231..232 - Iconst@231..232 "2" - Ascii41@232..233 ")" - Ascii59@233..234 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 27, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 50, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 31, - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 81, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 55, - }, - ), - ), - }, - ), - location: 55, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 111, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 85, - }, - ), - ), - }, - ), - location: 85, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 135, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 138, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 116, - }, - ), - ), - }, - ), - location: 116, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 161, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 164, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 142, - }, - ), - ), - }, - ), - location: 142, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 195, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 198, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 169, - }, - ), - ), - }, - ), - location: 169, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 228, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 231, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 202, - }, - ), - ), - }, - ), - location: 202, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..233, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@33.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@33.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@33.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@34.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@34.snap deleted file mode 100644 index 6fa30add..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@34.snap +++ /dev/null @@ -1,683 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- .. and releasing them all at once\n\nSELECT\n\tpg_advisory_lock(1), pg_advisory_lock(1),\n\tpg_advisory_lock_shared(2), pg_advisory_lock_shared(2),\n\tpg_advisory_lock(1, 1), pg_advisory_lock(1, 1),\n\tpg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..256 - SqlComment@0..36 "-- .. and releasing t ..." - Newline@36..38 "\n\n" - SelectStmt@38..256 - Select@38..44 "SELECT" - Newline@44..45 "\n" - Newline@45..46 "\t" - ResTarget@46..64 - FuncCall@46..64 - Ident@46..62 "pg_advisory_lock" - Ascii40@62..63 "(" - AConst@63..64 - Iconst@63..64 "1" - Ascii41@64..65 ")" - Ascii44@65..66 "," - Whitespace@66..67 " " - ResTarget@67..85 - FuncCall@67..85 - Ident@67..83 "pg_advisory_lock" - Ascii40@83..84 "(" - AConst@84..85 - Iconst@84..85 "1" - Ascii41@85..86 ")" - Ascii44@86..87 "," - Newline@87..88 "\n" - Newline@88..89 "\t" - ResTarget@89..114 - FuncCall@89..114 - Ident@89..112 "pg_advisory_lock_shared" - Ascii40@112..113 "(" - AConst@113..114 - Iconst@113..114 "2" - Ascii41@114..115 ")" - Ascii44@115..116 "," - Whitespace@116..117 " " - ResTarget@117..142 - FuncCall@117..142 - Ident@117..140 "pg_advisory_lock_shared" - Ascii40@140..141 "(" - AConst@141..142 - Iconst@141..142 "2" - Ascii41@142..143 ")" - Ascii44@143..144 "," - Newline@144..145 "\n" - Newline@145..146 "\t" - ResTarget@146..167 - FuncCall@146..167 - Ident@146..162 "pg_advisory_lock" - Ascii40@162..163 "(" - AConst@163..164 - Iconst@163..164 "1" - Ascii44@164..165 "," - Whitespace@165..166 " " - AConst@166..167 - Iconst@166..167 "1" - Ascii41@167..168 ")" - Ascii44@168..169 "," - Whitespace@169..170 " " - ResTarget@170..191 - FuncCall@170..191 - Ident@170..186 "pg_advisory_lock" - Ascii40@186..187 "(" - AConst@187..188 - Iconst@187..188 "1" - Ascii44@188..189 "," - Whitespace@189..190 " " - AConst@190..191 - Iconst@190..191 "1" - Ascii41@191..192 ")" - Ascii44@192..193 "," - Newline@193..194 "\n" - Newline@194..195 "\t" - ResTarget@195..223 - FuncCall@195..223 - Ident@195..218 "pg_advisory_lock_shared" - Ascii40@218..219 "(" - AConst@219..220 - Iconst@219..220 "2" - Ascii44@220..221 "," - Whitespace@221..222 " " - AConst@222..223 - Iconst@222..223 "2" - Ascii41@223..224 ")" - Ascii44@224..225 "," - Whitespace@225..226 " " - ResTarget@226..254 - FuncCall@226..254 - Ident@226..249 "pg_advisory_lock_shared" - Ascii40@249..250 "(" - AConst@250..251 - Iconst@250..251 "2" - Ascii44@251..252 "," - Whitespace@252..253 " " - AConst@253..254 - Iconst@253..254 "2" - Ascii41@254..255 ")" - Ascii59@255..256 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 25, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 46, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 29, - }, - ), - ), - }, - ), - location: 29, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 75, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 51, - }, - ), - ), - }, - ), - location: 51, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 103, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 79, - }, - ), - ), - }, - ), - location: 79, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 125, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 128, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 108, - }, - ), - ), - }, - ), - location: 108, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 149, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 152, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 132, - }, - ), - ), - }, - ), - location: 132, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 181, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 184, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 157, - }, - ), - ), - }, - ), - location: 157, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_lock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 212, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 215, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 188, - }, - ), - ), - }, - ), - location: 188, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 37..255, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@35.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@35.snap deleted file mode 100644 index a05ebc50..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@35.snap +++ /dev/null @@ -1,487 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT locktype, classid, objid, objsubid, mode, granted\n\tFROM pg_locks WHERE locktype = 'advisory'\n\tORDER BY classid, objid, objsubid;" ---- -Parse { - cst: SourceFile@0..135 - SelectStmt@0..135 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..15 - ColumnRef@7..15 - Ident@7..15 "locktype" - Ascii44@15..16 "," - Whitespace@16..17 " " - ResTarget@17..24 - ColumnRef@17..24 - Ident@17..24 "classid" - Ascii44@24..25 "," - Whitespace@25..26 " " - ResTarget@26..31 - ColumnRef@26..31 - Ident@26..31 "objid" - Ascii44@31..32 "," - Whitespace@32..33 " " - ResTarget@33..41 - ColumnRef@33..41 - Ident@33..41 "objsubid" - Ascii44@41..42 "," - Whitespace@42..43 " " - ResTarget@43..47 - ColumnRef@43..47 - Mode@43..47 "mode" - Ascii44@47..48 "," - Whitespace@48..49 " " - ResTarget@49..56 - ColumnRef@49..56 - Granted@49..56 "granted" - Newline@56..57 "\n" - Newline@57..58 "\t" - From@58..62 "FROM" - Whitespace@62..63 " " - RangeVar@63..71 - Ident@63..71 "pg_locks" - Whitespace@71..72 " " - Where@72..77 "WHERE" - Whitespace@77..78 " " - AExpr@78..99 - ColumnRef@78..86 - Ident@78..86 "locktype" - Whitespace@86..87 " " - Ascii61@87..88 "=" - Whitespace@88..89 " " - AConst@89..99 - Sconst@89..99 "'advisory'" - Newline@99..100 "\n" - Newline@100..101 "\t" - SortBy@101..117 - Order@101..106 "ORDER" - Whitespace@106..107 " " - By@107..109 "BY" - Whitespace@109..110 " " - ColumnRef@110..117 - Ident@110..117 "classid" - Ascii44@117..118 "," - Whitespace@118..119 " " - SortBy@119..124 - ColumnRef@119..124 - Ident@119..124 "objid" - Ascii44@124..125 "," - Whitespace@125..126 " " - SortBy@126..134 - ColumnRef@126..134 - Ident@126..134 "objsubid" - Ascii59@134..135 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 17, - }, - ), - ), - }, - ), - location: 17, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 26, - }, - ), - ), - }, - ), - location: 26, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 33, - }, - ), - ), - }, - ), - location: 33, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "mode", - }, - ), - ), - }, - ], - location: 43, - }, - ), - ), - }, - ), - location: 43, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "granted", - }, - ), - ), - }, - ], - location: 49, - }, - ), - ), - }, - ), - location: 49, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 63, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 78, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 89, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 87, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [ - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "classid", - }, - ), - ), - }, - ], - location: 110, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objid", - }, - ), - ), - }, - ], - location: 119, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - Node { - node: Some( - SortBy( - SortBy { - node: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "objsubid", - }, - ), - ), - }, - ], - location: 126, - }, - ), - ), - }, - ), - sortby_dir: SortbyDefault, - sortby_nulls: SortbyNullsDefault, - use_op: [], - location: -1, - }, - ), - ), - }, - ], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..134, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@36.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@36.snap deleted file mode 100644 index 230ef053..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@36.snap +++ /dev/null @@ -1,90 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: SELECT pg_advisory_unlock_all(); ---- -Parse { - cst: SourceFile@0..32 - SelectStmt@0..32 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..29 - FuncCall@7..29 - Ident@7..29 "pg_advisory_unlock_all" - Ascii40@29..30 "(" - Ascii41@30..31 ")" - Ascii59@31..32 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_all", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..31, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@37.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@37.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@37.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@4.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@4.snap deleted file mode 100644 index 26eee436..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@4.snap +++ /dev/null @@ -1,92 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- pg_advisory_unlock_all() shouldn't release xact locks\nSELECT pg_advisory_unlock_all();" ---- -Parse { - cst: SourceFile@0..89 - SqlComment@0..56 "-- pg_advisory_unlock ..." - Newline@56..57 "\n" - SelectStmt@57..89 - Select@57..63 "SELECT" - Whitespace@63..64 " " - ResTarget@64..86 - FuncCall@64..86 - Ident@64..86 "pg_advisory_unlock_all" - Ascii40@86..87 "(" - Ascii41@87..88 ")" - Ascii59@88..89 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_all", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 56..88, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@5.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@5.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@5.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@6.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@6.snap deleted file mode 100644 index 249737fa..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@6.snap +++ /dev/null @@ -1,363 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- can't unlock xact locks\nSELECT\n\tpg_advisory_unlock(1), pg_advisory_unlock_shared(2),\n\tpg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2);" ---- -Parse { - cst: SourceFile@0..147 - SqlComment@0..26 "-- can't unlock xact ..." - Newline@26..27 "\n" - SelectStmt@27..147 - Select@27..33 "SELECT" - Newline@33..34 "\n" - Newline@34..35 "\t" - ResTarget@35..55 - FuncCall@35..55 - Ident@35..53 "pg_advisory_unlock" - Ascii40@53..54 "(" - AConst@54..55 - Iconst@54..55 "1" - Ascii41@55..56 ")" - Ascii44@56..57 "," - Whitespace@57..58 " " - ResTarget@58..85 - FuncCall@58..85 - Ident@58..83 "pg_advisory_unlock_sh ..." - Ascii40@83..84 "(" - AConst@84..85 - Iconst@84..85 "2" - Ascii41@85..86 ")" - Ascii44@86..87 "," - Newline@87..88 "\n" - Newline@88..89 "\t" - ResTarget@89..112 - FuncCall@89..112 - Ident@89..107 "pg_advisory_unlock" - Ascii40@107..108 "(" - AConst@108..109 - Iconst@108..109 "1" - Ascii44@109..110 "," - Whitespace@110..111 " " - AConst@111..112 - Iconst@111..112 "1" - Ascii41@112..113 ")" - Ascii44@113..114 "," - Whitespace@114..115 " " - ResTarget@115..145 - FuncCall@115..145 - Ident@115..140 "pg_advisory_unlock_sh ..." - Ascii40@140..141 "(" - AConst@141..142 - Iconst@141..142 "2" - Ascii44@142..143 "," - Whitespace@143..144 " " - AConst@144..145 - Iconst@144..145 "2" - Ascii41@145..146 ")" - Ascii59@146..147 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 27, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 8, - }, - ), - ), - }, - ), - location: 8, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 57, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 31, - }, - ), - ), - }, - ), - location: 31, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 81, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 84, - val: Some( - Ival( - Integer { - ival: 1, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 62, - }, - ), - ), - }, - ), - location: 62, - }, - ), - ), - }, - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "pg_advisory_unlock_shared", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 114, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 117, - val: Some( - Ival( - Integer { - ival: 2, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 88, - }, - ), - ), - }, - ), - location: 88, - }, - ), - ), - }, - ], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 26..146, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@7.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@7.snap deleted file mode 100644 index d113c943..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@7.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- automatically release xact locks at commit\nCOMMIT;" ---- -Parse { - cst: SourceFile@0..53 - SqlComment@0..45 "-- automatically rele ..." - Newline@45..46 "\n" - TransactionStmt@46..53 - Commit@46..52 "COMMIT" - Ascii59@52..53 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtCommit, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 45..52, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@8.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@8.snap deleted file mode 100644 index e02d19a3..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@8.snap +++ /dev/null @@ -1,186 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';" ---- -Parse { - cst: SourceFile@0..58 - SelectStmt@0..58 - Select@0..6 "SELECT" - Whitespace@6..7 " " - ResTarget@7..14 - FuncCall@7..14 - Ident@7..12 "count" - Ascii40@12..13 "(" - Ascii42@13..14 "*" - Ascii41@14..15 ")" - Whitespace@15..16 " " - From@16..20 "FROM" - Whitespace@20..21 " " - RangeVar@21..29 - Ident@21..29 "pg_locks" - Whitespace@29..30 " " - Where@30..35 "WHERE" - Whitespace@35..36 " " - AExpr@36..57 - ColumnRef@36..44 - Ident@36..44 "locktype" - Whitespace@44..45 " " - Ascii61@45..46 "=" - Whitespace@46..47 " " - AConst@47..57 - Sconst@47..57 "'advisory'" - Ascii59@57..58 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "count", - }, - ), - ), - }, - ], - args: [], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: true, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "pg_locks", - inh: true, - relpersistence: "p", - alias: None, - location: 21, - }, - ), - ), - }, - ], - where_clause: Some( - Node { - node: Some( - AExpr( - AExpr { - kind: AexprOp, - name: [ - Node { - node: Some( - String( - String { - sval: "=", - }, - ), - ), - }, - ], - lexpr: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - String( - String { - sval: "locktype", - }, - ), - ), - }, - ], - location: 36, - }, - ), - ), - }, - ), - rexpr: Some( - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 47, - val: Some( - Sval( - String { - sval: "advisory", - }, - ), - ), - }, - ), - ), - }, - ), - location: 45, - }, - ), - ), - }, - ), - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..57, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/advisory_lock@9.snap b/crates/parser/tests/snapshots/statements/valid/advisory_lock@9.snap deleted file mode 100644 index 7c25e8c9..00000000 --- a/crates/parser/tests/snapshots/statements/valid/advisory_lock@9.snap +++ /dev/null @@ -1,26 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: BEGIN; ---- -Parse { - cst: SourceFile@0..6 - TransactionStmt@0..6 - BeginP@0..5 "BEGIN" - Ascii59@5..6 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: TransactionStmt( - TransactionStmt { - kind: TransStmtBegin, - options: [], - savepoint_name: "", - gid: "", - chain: false, - }, - ), - range: 0..5, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@1.snap b/crates/parser/tests/snapshots/statements/valid/lseg@1.snap deleted file mode 100644 index 23e17490..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@1.snap +++ /dev/null @@ -1,114 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "--\n-- LSEG\n-- Line segments\n--\n\n--DROP TABLE LSEG_TBL;\nCREATE TABLE LSEG_TBL (s lseg);" ---- -Parse { - cst: SourceFile@0..86 - SqlComment@0..2 "--" - Newline@2..3 "\n" - SqlComment@3..10 "-- LSEG" - Newline@10..11 "\n" - SqlComment@11..27 "-- Line segments" - Newline@27..28 "\n" - SqlComment@28..30 "--" - Newline@30..32 "\n\n" - SqlComment@32..54 "--DROP TABLE LSEG_TBL;" - Newline@54..55 "\n" - CreateStmt@55..86 - Create@55..61 "CREATE" - Whitespace@61..62 " " - Table@62..67 "TABLE" - Whitespace@67..68 " " - RangeVar@68..76 - Ident@68..76 "LSEG_TBL" - Whitespace@76..77 " " - Ascii40@77..78 "(" - ColumnDef@78..84 - Ident@78..79 "s" - Whitespace@79..80 " " - TypeName@80..84 - Ident@80..84 "lseg" - Ascii41@84..85 ")" - Ascii59@85..86 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: CreateStmt( - CreateStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 13, - }, - ), - table_elts: [ - Node { - node: Some( - ColumnDef( - ColumnDef { - colname: "s", - type_name: Some( - TypeName { - names: [ - Node { - node: Some( - String( - String { - sval: "lseg", - }, - ), - ), - }, - ], - type_oid: 0, - setof: false, - pct_type: false, - typmods: [], - typemod: -1, - array_bounds: [], - location: 25, - }, - ), - compression: "", - inhcount: 0, - is_local: true, - is_not_null: false, - is_from_type: false, - storage: "", - raw_default: None, - cooked_default: None, - identity: "", - identity_sequence: None, - generated: "", - coll_clause: None, - coll_oid: 0, - constraints: [], - fdwoptions: [], - location: 23, - }, - ), - ), - }, - ], - inh_relations: [], - partbound: None, - partspec: None, - of_typename: None, - constraints: [], - options: [], - oncommit: OncommitNoop, - tablespacename: "", - access_method: "", - if_not_exists: false, - }, - ), - range: 54..85, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@10.snap b/crates/parser/tests/snapshots/statements/valid/lseg@10.snap deleted file mode 100644 index 4e0fa4f1..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@10.snap +++ /dev/null @@ -1,113 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- NaN\n\n-- bad values for parser testing\nINSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)');" ---- -Parse { - cst: SourceFile@0..90 - SqlComment@0..6 "-- NaN" - Newline@6..8 "\n\n" - SqlComment@8..40 "-- bad values for par ..." - Newline@40..41 "\n" - InsertStmt@41..90 - Insert@41..47 "INSERT" - Whitespace@47..48 " " - Into@48..52 "INTO" - Whitespace@52..53 " " - RangeVar@53..61 - Ident@53..61 "LSEG_TBL" - Whitespace@61..62 " " - SelectStmt@62..88 - Values@62..68 "VALUES" - Whitespace@68..69 " " - Ascii40@69..70 "(" - List@70..88 - AConst@70..88 - Sconst@70..88 "'(3asdf,2 ,3,4r2)'" - Ascii41@88..89 ")" - Ascii59@89..90 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "(3asdf,2 ,3,4r2)", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 40..89, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@11.snap b/crates/parser/tests/snapshots/statements/valid/lseg@11.snap deleted file mode 100644 index dc2de0f4..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@11.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4');" ---- -Parse { - cst: SourceFile@0..42 - InsertStmt@0..42 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..40 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..40 - AConst@29..40 - Sconst@29..40 "'[1,2,3, 4'" - Ascii41@40..41 ")" - Ascii59@41..42 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[1,2,3, 4", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..41, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@12.snap b/crates/parser/tests/snapshots/statements/valid/lseg@12.snap deleted file mode 100644 index 57cd5e38..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@12.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]');" ---- -Parse { - cst: SourceFile@0..45 - InsertStmt@0..45 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..43 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..43 - AConst@29..43 - Sconst@29..43 "'[(,2),(3,4)]'" - Ascii41@43..44 ")" - Ascii59@44..45 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(,2),(3,4)]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..44, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@13.snap b/crates/parser/tests/snapshots/statements/valid/lseg@13.snap deleted file mode 100644 index 8b73208c..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@13.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)');" ---- -Parse { - cst: SourceFile@0..45 - InsertStmt@0..45 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..43 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..43 - AConst@29..43 - Sconst@29..43 "'[(1,2),(3,4)'" - Ascii41@43..44 ")" - Ascii59@44..45 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(1,2),(3,4)", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..44, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@14.snap b/crates/parser/tests/snapshots/statements/valid/lseg@14.snap deleted file mode 100644 index 2a8668a7..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@14.snap +++ /dev/null @@ -1,99 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: select * from LSEG_TBL; ---- -Parse { - cst: SourceFile@0..23 - SelectStmt@0..23 - Select@0..6 "select" - Whitespace@6..7 " " - ResTarget@7..8 - ColumnRef@7..8 - AStar@7..8 - Ascii42@7..8 "*" - Whitespace@8..9 " " - From@9..13 "from" - Whitespace@13..14 " " - RangeVar@14..22 - Ident@14..22 "LSEG_TBL" - Ascii59@22..23 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [ - Node { - node: Some( - ResTarget( - ResTarget { - name: "", - indirection: [], - val: Some( - Node { - node: Some( - ColumnRef( - ColumnRef { - fields: [ - Node { - node: Some( - AStar( - AStar, - ), - ), - }, - ], - location: 7, - }, - ), - ), - }, - ), - location: 7, - }, - ), - ), - }, - ], - from_clause: [ - Node { - node: Some( - RangeVar( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 14, - }, - ), - ), - }, - ], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - range: 0..22, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@2.snap b/crates/parser/tests/snapshots/statements/valid/lseg@2.snap deleted file mode 100644 index 54bb116a..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@2.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]');" ---- -Parse { - cst: SourceFile@0..46 - InsertStmt@0..46 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..44 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..44 - AConst@29..44 - Sconst@29..44 "'[(1,2),(3,4)]'" - Ascii41@44..45 ")" - Ascii59@45..46 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(1,2),(3,4)]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@3.snap b/crates/parser/tests/snapshots/statements/valid/lseg@3.snap deleted file mode 100644 index b3772276..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@3.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)');" ---- -Parse { - cst: SourceFile@0..44 - InsertStmt@0..44 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..42 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..42 - AConst@29..42 - Sconst@29..42 "'(0,0),(6,6)'" - Ascii41@42..43 ")" - Ascii59@43..44 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "(0,0),(6,6)", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..43, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@4.snap b/crates/parser/tests/snapshots/statements/valid/lseg@4.snap deleted file mode 100644 index 2b7200b5..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@4.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4');" ---- -Parse { - cst: SourceFile@0..46 - InsertStmt@0..46 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..44 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..44 - AConst@29..44 - Sconst@29..44 "'10,-10 ,-3,-4'" - Ascii41@44..45 ")" - Ascii59@45..46 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "10,-10 ,-3,-4", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..45, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@5.snap b/crates/parser/tests/snapshots/statements/valid/lseg@5.snap deleted file mode 100644 index 78c14eb2..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@5.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]');" ---- -Parse { - cst: SourceFile@0..53 - InsertStmt@0..53 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..51 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..51 - AConst@29..51 - Sconst@29..51 "'[-1e6,2e2,3e5, -4e1]'" - Ascii41@51..52 ")" - Ascii59@52..53 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[-1e6,2e2,3e5, -4e1]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..52, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@6.snap b/crates/parser/tests/snapshots/statements/valid/lseg@6.snap deleted file mode 100644 index c5974449..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@6.snap +++ /dev/null @@ -1,273 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44)));" ---- -Parse { - cst: SourceFile@0..64 - InsertStmt@0..64 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..60 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..60 - FuncCall@29..60 - Ident@29..33 "lseg" - Ascii40@33..34 "(" - FuncCall@34..46 - Ident@34..39 "point" - Ascii40@39..40 "(" - AConst@40..42 - Iconst@40..42 "11" - Ascii44@42..43 "," - Whitespace@43..44 " " - AConst@44..46 - Iconst@44..46 "22" - Ascii41@46..47 ")" - Ascii44@47..48 "," - Whitespace@48..49 " " - FuncCall@49..60 - Ident@49..54 "point" - Ascii40@54..55 "(" - AConst@55..57 - Iconst@55..57 "33" - Ascii44@57..58 "," - AConst@58..60 - Iconst@58..60 "44" - Ascii41@60..61 ")" - Ascii41@61..62 ")" - Ascii41@62..63 ")" - Ascii59@63..64 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "lseg", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "point", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 40, - val: Some( - Ival( - Integer { - ival: 11, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 44, - val: Some( - Ival( - Integer { - ival: 22, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 34, - }, - ), - ), - }, - Node { - node: Some( - FuncCall( - FuncCall { - funcname: [ - Node { - node: Some( - String( - String { - sval: "point", - }, - ), - ), - }, - ], - args: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 55, - val: Some( - Ival( - Integer { - ival: 33, - }, - ), - ), - }, - ), - ), - }, - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 58, - val: Some( - Ival( - Integer { - ival: 44, - }, - ), - ), - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 49, - }, - ), - ), - }, - ], - agg_order: [], - agg_filter: None, - over: None, - agg_within_group: false, - agg_star: false, - agg_distinct: false, - func_variadic: false, - funcformat: CoerceExplicitCall, - location: 29, - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..63, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@7.snap b/crates/parser/tests/snapshots/statements/valid/lseg@7.snap deleted file mode 100644 index 12a61e7b..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@7.snap +++ /dev/null @@ -1,109 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]');" ---- -Parse { - cst: SourceFile@0..50 - InsertStmt@0..50 - Insert@0..6 "INSERT" - Whitespace@6..7 " " - Into@7..11 "INTO" - Whitespace@11..12 " " - RangeVar@12..20 - Ident@12..20 "LSEG_TBL" - Whitespace@20..21 " " - SelectStmt@21..48 - Values@21..27 "VALUES" - Whitespace@27..28 " " - Ascii40@28..29 "(" - List@29..48 - AConst@29..48 - Sconst@29..48 "'[(-10,2),(-10,3)]'" - Ascii41@48..49 ")" - Ascii59@49..50 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(-10,2),(-10,3)]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 0..49, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@8.snap b/crates/parser/tests/snapshots/statements/valid/lseg@8.snap deleted file mode 100644 index c4a7ec1d..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@8.snap +++ /dev/null @@ -1,111 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- vertical\nINSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]');" ---- -Parse { - cst: SourceFile@0..63 - SqlComment@0..11 "-- vertical" - Newline@11..12 "\n" - InsertStmt@12..63 - Insert@12..18 "INSERT" - Whitespace@18..19 " " - Into@19..23 "INTO" - Whitespace@23..24 " " - RangeVar@24..32 - Ident@24..32 "LSEG_TBL" - Whitespace@32..33 " " - SelectStmt@33..61 - Values@33..39 "VALUES" - Whitespace@39..40 " " - Ascii40@40..41 "(" - List@41..61 - AConst@41..61 - Sconst@41..61 "'[(0,-20),(30,-20)]'" - Ascii41@61..62 ")" - Ascii59@62..63 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(0,-20),(30,-20)]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 11..62, - }, - ], -} diff --git a/crates/parser/tests/snapshots/statements/valid/lseg@9.snap b/crates/parser/tests/snapshots/statements/valid/lseg@9.snap deleted file mode 100644 index 671a8bee..00000000 --- a/crates/parser/tests/snapshots/statements/valid/lseg@9.snap +++ /dev/null @@ -1,111 +0,0 @@ ---- -source: crates/parser/tests/statement_parser_test.rs -description: "-- horizontal\nINSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]');" ---- -Parse { - cst: SourceFile@0..65 - SqlComment@0..13 "-- horizontal" - Newline@13..14 "\n" - InsertStmt@14..65 - Insert@14..20 "INSERT" - Whitespace@20..21 " " - Into@21..25 "INTO" - Whitespace@25..26 " " - RangeVar@26..34 - Ident@26..34 "LSEG_TBL" - Whitespace@34..35 " " - SelectStmt@35..63 - Values@35..41 "VALUES" - Whitespace@41..42 " " - Ascii40@42..43 "(" - List@43..63 - AConst@43..63 - Sconst@43..63 "'[(NaN,1),(NaN,90)]'" - Ascii41@63..64 ")" - Ascii59@64..65 ";" - , - errors: [], - stmts: [ - RawStmt { - stmt: InsertStmt( - InsertStmt { - relation: Some( - RangeVar { - catalogname: "", - schemaname: "", - relname: "lseg_tbl", - inh: true, - relpersistence: "p", - alias: None, - location: 12, - }, - ), - cols: [], - select_stmt: Some( - Node { - node: Some( - SelectStmt( - SelectStmt { - distinct_clause: [], - into_clause: None, - target_list: [], - from_clause: [], - where_clause: None, - group_clause: [], - group_distinct: false, - having_clause: None, - window_clause: [], - values_lists: [ - Node { - node: Some( - List( - List { - items: [ - Node { - node: Some( - AConst( - AConst { - isnull: false, - location: 29, - val: Some( - Sval( - String { - sval: "[(NaN,1),(NaN,90)]", - }, - ), - ), - }, - ), - ), - }, - ], - }, - ), - ), - }, - ], - sort_clause: [], - limit_offset: None, - limit_count: None, - limit_option: Default, - locking_clause: [], - with_clause: None, - op: SetopNone, - all: false, - larg: None, - rarg: None, - }, - ), - ), - }, - ), - on_conflict_clause: None, - returning_list: [], - with_clause: None, - r#override: OverridingNotSet, - }, - ), - range: 13..64, - }, - ], -} diff --git a/crates/pg_base_db/Cargo.toml b/crates/pg_base_db/Cargo.toml new file mode 100644 index 00000000..24e2bed5 --- /dev/null +++ b/crates/pg_base_db/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pg_base_db" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +line_index.workspace = true + +pg_statement_splitter.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_base_db/src/change.rs b/crates/pg_base_db/src/change.rs new file mode 100644 index 00000000..26a926ff --- /dev/null +++ b/crates/pg_base_db/src/change.rs @@ -0,0 +1,564 @@ +use std::ops::Sub; + +use line_index::LineIndex; +use text_size::{TextLen, TextRange, TextSize}; + +use crate::document::{Document, StatementRef}; + +#[derive(Debug)] +pub enum StatementChange { + Added(StatementRef), + Deleted(StatementRef), + Modified(ChangedStatement), +} + +impl StatementChange { + pub fn statement(&self) -> &StatementRef { + match self { + StatementChange::Added(stmt) => stmt, + StatementChange::Deleted(stmt) => stmt, + StatementChange::Modified(stmt) => &stmt.statement, + } + } +} + +#[derive(Debug)] +pub struct ChangedStatement { + /// The now "old" statement ref + pub statement: StatementRef, + /// The range in which the text changed + pub range: TextRange, + /// The new text + pub text: String, +} + +impl ChangedStatement { + pub fn new_statement(&self) -> StatementRef { + StatementRef { + idx: self.statement.idx, + text: apply_text_change(&self.statement.text, Some(self.range), &self.text), + document_url: self.statement.document_url.clone(), + } + } +} + +fn apply_text_change(text: &String, range: Option, change_text: &String) -> String { + if range.is_none() { + return change_text.clone(); + } + + let range = range.unwrap(); + let start = usize::from(range.start()); + let end = usize::from(range.end()); + + let mut new_text = String::new(); + new_text.push_str(&text[..start]); + new_text.push_str(&change_text); + new_text.push_str(&text[end..]); + + new_text +} + +#[derive(Debug)] +pub struct DocumentChange { + pub version: i32, + pub changes: Vec, + + changed_statements: Vec, + + applied: bool, +} + +#[derive(Debug, Clone)] +pub struct Change { + /// The range of the file that changed. If `None`, the whole file changed. + pub range: Option, + pub text: String, +} + +impl Change { + pub fn diff_size(&self) -> TextSize { + match self.range { + Some(range) => { + let range_length: usize = range.len().into(); + let text_length = self.text.chars().count(); + let diff = (text_length as i64 - range_length as i64).abs(); + TextSize::from(u32::try_from(diff).unwrap()) + } + None => TextSize::from(u32::try_from(self.text.chars().count()).unwrap()), + } + } + + pub fn is_addition(&self) -> bool { + self.range.is_some() && self.text.len() > self.range.unwrap().len().into() + } + + pub fn is_deletion(&self) -> bool { + self.range.is_some() && self.text.len() < self.range.unwrap().len().into() + } + + pub fn apply_to_text(&self, text: &String) -> String { + if self.range.is_none() { + return self.text.clone(); + } + + let range = self.range.unwrap(); + let start = usize::from(range.start()); + let end = usize::from(range.end()); + + let mut new_text = String::new(); + new_text.push_str(&text[..start]); + new_text.push_str(&self.text); + new_text.push_str(&text[end..]); + + new_text + } + + pub fn apply(&self, doc: &mut Document) -> Vec { + let mut changed_statements: Vec = Vec::new(); + + if self.range.is_none() { + // whole file changed + changed_statements.extend( + doc.drain_statements() + .into_iter() + .map(|s| StatementChange::Deleted(s)), + ); + // TODO also use errors returned by extract sql statement ranges + doc.statement_ranges = pg_statement_splitter::split(&self.text) + .ranges + .iter() + .map(|r| r.clone()) + .collect(); + doc.text = self.text.clone(); + doc.line_index = LineIndex::new(&doc.text); + + changed_statements.extend( + doc.statement_refs() + .iter() + .map(|stmt| StatementChange::Added(stmt.to_owned())), + ); + } else if let Some(changed_stmt_pos) = doc + .statement_ranges + .iter() + .position(|r| r.contains_range(self.range.unwrap())) + { + // change within a single statement + doc.statement_ranges + .iter_mut() + .enumerate() + .skip_while(|(_, r)| self.range.unwrap().end() > r.end()) + .for_each(|(pos, r)| { + if pos == changed_stmt_pos { + // only this ones ref is different, the rest do not have any text + // changes + changed_statements.push(StatementChange::Modified(ChangedStatement { + statement: StatementRef { + idx: pos, + text: doc.text[r.clone()].to_string(), + document_url: doc.url.clone(), + }, + // change must be relative to statement + range: self.range.unwrap().sub(r.start()), + text: self.text.clone(), + })); + + // if addition, expand the range + // if deletion, shrink the range + if self.is_addition() { + *r = TextRange::new( + r.start(), + r.end() + TextSize::from(self.diff_size()), + ); + } else if self.is_deletion() { + *r = TextRange::new( + r.start(), + r.end() - TextSize::from(self.diff_size()), + ); + } + } else if self.is_addition() { + *r += self.diff_size(); + } else if self.is_deletion() { + *r -= self.diff_size(); + } + }); + + doc.text = self.apply_to_text(&doc.text); + doc.line_index = LineIndex::new(&doc.text); + } else { + // change across stmts + + let mut min = self.range.unwrap().start(); + let mut max = self.range.unwrap().end(); + + for (idx, r) in doc + .statement_ranges + .iter() + .enumerate() + .skip_while(|(_, r)| { + // skip until first changed stmt + self.range.unwrap().start() > r.end() + }) + .take_while(|(_, r)| { + // take until after last changed stmt + self.range.unwrap().end() >= r.end() + }) + { + changed_statements.push(StatementChange::Deleted(StatementRef { + idx, + text: doc.text[r.clone()].to_string(), + document_url: doc.url.clone(), + })); + + if r.start() < min { + min = r.start(); + } + if r.end() > max { + max = r.end(); + } + } + + doc.text = self.apply_to_text(&doc.text); + doc.line_index = LineIndex::new(&doc.text); + + if doc.text.text_len() < max { + max = doc.text.text_len(); + } + + // get text from min(first_stmt_start, change_start) to max(last_stmt_end, change_end) + let extracted_text = doc + .text + .as_str() + .get(usize::from(min)..usize::from(max)) + .unwrap(); + + doc.statement_ranges.drain( + changed_statements + .iter() + .min_by_key(|c| c.statement().idx) + .unwrap() + .statement() + .idx + ..changed_statements + .iter() + .max_by_key(|c| c.statement().idx) + .unwrap() + .statement() + .idx + + 1, + ); + + for range in pg_statement_splitter::split(extracted_text).ranges { + match doc + .statement_ranges + .binary_search_by(|r| r.start().cmp(&range.start())) + { + Ok(_) => {} + Err(pos) => { + doc.statement_ranges.insert(pos, range); + changed_statements.push(StatementChange::Added(StatementRef { + idx: pos, + text: extracted_text[range].to_string(), + document_url: doc.url.clone(), + })); + } + } + } + } + + changed_statements + } +} + +impl DocumentChange { + pub fn new(version: i32, changes: Vec) -> DocumentChange { + DocumentChange { + version, + changes, + changed_statements: Vec::new(), + applied: false, + } + } + + pub fn apply(&mut self, doc: &mut Document) { + assert!(!self.applied, "DocumentChange already applied"); + // TODO: optimize this by searching for the last change without a range and start applying + // from there + self.changed_statements + .extend(self.changes.iter().flat_map(|c| c.apply(doc))); + + doc.version = self.version; + self.applied = true; + } + + pub fn collect_statement_changes(&mut self) -> Vec { + assert!(self.applied, "DocumentChange not yet applied"); + self.changed_statements.drain(..).collect() + } +} + +#[cfg(test)] +mod tests { + use text_size::{TextRange, TextSize}; + + use crate::{change::Change, document::StatementRef, Document, DocumentChange, PgLspPath}; + + #[test] + fn test_document_apply_changes() { + let input = "select id from users;\nselect * from contacts;"; + + let mut d = Document::new(PgLspPath::new("test.sql"), Some(input.to_string())); + + assert_eq!(d.statement_ranges.len(), 2); + + let mut change = DocumentChange::new( + 1, + vec![Change { + text: ",test from users\nselect 1;".to_string(), + range: Some(TextRange::new(9.into(), 45.into())), + }], + ); + + change.apply(&mut d); + let changed = change.collect_statement_changes(); + + assert_eq!(changed.len(), 4); + assert_eq!( + changed[0].statement().to_owned(), + StatementRef { + document_url: PgLspPath::new("test.sql"), + text: "select id from users;".to_string(), + idx: 0 + } + ); + assert_eq!( + changed[1].statement().to_owned(), + StatementRef { + document_url: PgLspPath::new("test.sql"), + text: "select * from contacts;".to_string(), + idx: 1 + } + ); + + assert_eq!("select id,test from users\nselect 1;", d.text); + assert_eq!(d.statement_ranges.len(), 2); + + for r in &pg_statement_splitter::split(&d.text).ranges { + assert_eq!( + d.statement_ranges.iter().position(|x| r == x).is_some(), + true, + "should have stmt with range {:#?}", + r + ); + } + + assert_eq!(d.statement_ranges[0], TextRange::new(0.into(), 26.into())); + assert_eq!(d.statement_ranges[1], TextRange::new(26.into(), 35.into())); + } + + #[test] + fn test_document_apply_changes_at_end_of_statement() { + let input = "select id from\nselect * from contacts;"; + + let mut d = Document::new(PgLspPath::new("test.sql"), Some(input.to_string())); + + assert_eq!(d.statement_ranges.len(), 2); + + let stmt_1_range = d.statement_ranges[0].clone(); + let stmt_2_range = d.statement_ranges[1].clone(); + + let update_text = " contacts;"; + + let update_range = TextRange::new(14.into(), 14.into()); + + let update_text_len = u32::try_from(update_text.chars().count()).unwrap(); + let update_addition = update_text_len - u32::from(update_range.len()); + + let mut change = DocumentChange::new( + 1, + vec![Change { + text: update_text.to_string(), + range: Some(update_range), + }], + ); + + change.apply(&mut d); + + assert_eq!("select id from contacts;\nselect * from contacts;", d.text); + assert_eq!(d.statement_ranges.len(), 2); + assert_eq!(d.statement_ranges[0].start(), stmt_1_range.start()); + assert_eq!( + u32::from(d.statement_ranges[0].end()), + u32::from(stmt_1_range.end()) + update_addition + ); + assert_eq!( + u32::from(d.statement_ranges[1].start()), + u32::from(stmt_2_range.start()) + update_addition + ); + assert_eq!( + u32::from(d.statement_ranges[1].end()), + u32::from(stmt_2_range.end()) + update_addition + ); + } + + #[test] + fn test_document_apply_changes_replacement() { + let path = PgLspPath::new("test.sql"); + + let mut doc = Document::new(path, None); + + let mut c = DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select 1;\nselect 2;".to_string(), + }], + ); + + c.apply(&mut doc); + + assert_eq!(doc.statement_ref(0).text, "select 1;".to_string()); + assert_eq!(doc.statement_ref(1).text, "select 2;".to_string()); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + + let mut c = DocumentChange::new( + 2, + vec![Change { + range: Some(TextRange::new(7.into(), 8.into())), + text: "".to_string(), + }], + ); + + c.apply(&mut doc); + + assert_eq!(doc.text, "select ;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!(doc.statement_ref(0).text, "select ;".to_string()); + assert_eq!(doc.statement_ref(1).text, "select 2;".to_string()); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(8)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(9), TextSize::new(18)) + ); + + let mut c = DocumentChange::new( + 3, + vec![Change { + range: Some(TextRange::new(7.into(), 7.into())), + text: "!".to_string(), + }], + ); + + c.apply(&mut doc); + + assert_eq!(doc.text, "select !;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + + let mut c = DocumentChange::new( + 4, + vec![Change { + range: Some(TextRange::new(7.into(), 8.into())), + text: "".to_string(), + }], + ); + + c.apply(&mut doc); + + assert_eq!(doc.text, "select ;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(8)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(9), TextSize::new(18)) + ); + + let mut c = DocumentChange::new( + 5, + vec![Change { + range: Some(TextRange::new(7.into(), 7.into())), + text: "1".to_string(), + }], + ); + c.apply(&mut doc); + + assert_eq!(doc.text, "select 1;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + } + + #[test] + fn test_document_apply_changes_within_statement() { + let input = "select id from users;\nselect * from contacts;"; + + let mut d = Document::new(PgLspPath::new("test.sql"), Some(input.to_string())); + + assert_eq!(d.statement_ranges.len(), 2); + + let stmt_1_range = d.statement_ranges[0].clone(); + let stmt_2_range = d.statement_ranges[1].clone(); + + let update_text = ",test"; + + let update_range = TextRange::new(9.into(), 10.into()); + + let update_text_len = u32::try_from(update_text.chars().count()).unwrap(); + let update_addition = update_text_len - u32::from(update_range.len()); + + let mut change = DocumentChange::new( + 1, + vec![Change { + text: update_text.to_string(), + range: Some(update_range), + }], + ); + + change.apply(&mut d); + + assert_eq!( + "select id,test from users;\nselect * from contacts;", + d.text + ); + assert_eq!(d.statement_ranges.len(), 2); + assert_eq!(d.statement_ranges[0].start(), stmt_1_range.start()); + assert_eq!( + u32::from(d.statement_ranges[0].end()), + u32::from(stmt_1_range.end()) + update_addition + ); + assert_eq!( + u32::from(d.statement_ranges[1].start()), + u32::from(stmt_2_range.start()) + update_addition + ); + assert_eq!( + u32::from(d.statement_ranges[1].end()), + u32::from(stmt_2_range.end()) + update_addition + ); + } +} diff --git a/crates/pg_base_db/src/document.rs b/crates/pg_base_db/src/document.rs new file mode 100644 index 00000000..a9838833 --- /dev/null +++ b/crates/pg_base_db/src/document.rs @@ -0,0 +1,192 @@ +use std::{hash::Hash, hash::Hasher, ops::RangeBounds, usize}; + +use line_index::LineIndex; +use text_size::{TextRange, TextSize}; + +use crate::PgLspPath; + +extern crate test; + +/// Represents a sql source file, and contains a list of statements represented by their ranges +pub struct Document { + /// The url of the document + pub url: PgLspPath, + /// The text of the document + pub text: String, + /// The version of the document + pub version: i32, + /// List of statements sorted by range.start() + pub statement_ranges: Vec, + /// Line index for the document + pub line_index: LineIndex, +} + +impl Hash for Document { + fn hash(&self, state: &mut H) { + self.url.hash(state); + } +} + +/// Represents a reference to a sql statement. This is the primary data structure that is used by higher-level crates to save and retrieve information about a statement. +/// This needs to be optimised by removing the text from the struct and making it a reference to the text in the document. +/// +/// Note that the ref must include all information needed to uniquely identify the statement, so that it can be used as a key in a hashmap. +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub struct StatementRef { + pub document_url: PgLspPath, + // TODO use string interner for text + pub text: String, + pub idx: usize, +} + +impl Document { + /// Create a new document + pub fn new(url: PgLspPath, text: Option) -> Document { + Document { + version: 0, + line_index: LineIndex::new(&text.as_ref().unwrap_or(&"".to_string())), + // TODO: use errors returned by split + statement_ranges: text.as_ref().map_or_else( + || Vec::new(), + |f| { + pg_statement_splitter::split(&f) + .ranges + .iter() + .map(|range| range.clone()) + .collect() + }, + ), + text: text.unwrap_or("".to_string()), + url, + } + } + + /// Returns the statement at the given offset + pub fn statement_at_offset(&self, offset: &TextSize) -> Option { + self.statement_ranges + .iter() + .position(|r| r.contains(offset)) + .map(|idx| self.statement_ref(idx)) + } + + /// Returns the statements at the given range + pub fn statements_at_range(&self, range: &TextRange) -> Vec { + self.statement_ranges + .iter() + .enumerate() + .filter(|(_, r)| { + range.contains_range(r.to_owned().to_owned()) || r.contains_range(range.to_owned()) + }) + .map(|(idx, _)| self.statement_ref(idx)) + .collect() + } + + /// Returns the statement at the given offset with its range in the document + pub fn statement_at_offset_with_range( + &self, + offset: &TextSize, + ) -> Option<(TextRange, StatementRef)> { + self.statement_ranges + .iter() + .position(|r| r.contains(offset)) + .map(|idx| self.statement_ref_with_range(idx)) + } + + /// Drains the statements from the document + pub(crate) fn drain_statements(&mut self) -> Vec { + self.statement_ranges + .drain(..) + .enumerate() + .map(|(idx, range)| StatementRef { + document_url: self.url.clone(), + text: self.text[range.clone()].to_string(), + idx, + }) + .collect() + } + + /// Returns all statements with their ranges in the document + pub fn statement_refs_with_range(&self) -> Vec<(TextRange, StatementRef)> { + self.statement_ranges + .iter() + .enumerate() + .map(|(idx, range)| { + ( + range.clone(), + StatementRef { + document_url: self.url.clone(), + text: self.text[range.clone()].to_string(), + idx, + }, + ) + }) + .collect() + } + + /// Returns all statements in the document + pub fn statement_refs(&self) -> Vec { + self.statement_ranges + .iter() + .enumerate() + .map(|(idx, range)| StatementRef { + document_url: self.url.clone(), + text: self.text[range.clone()].to_string(), + idx, + }) + .collect() + } + + /// Returns the statement with the given index, throws an error if the index is out of bounds + pub fn statement_ref(&self, pos: usize) -> StatementRef { + self.statement_ranges + .get(pos) + .map(|range| StatementRef { + document_url: self.url.clone(), + text: self.text[range.clone()].to_string(), + idx: pos, + }) + .unwrap() + } + + /// Returns the statement with the given index and its range in the document + pub fn statement_ref_with_range(&self, pos: usize) -> (TextRange, StatementRef) { + self.statement_ranges + .get(pos) + .map(|range| { + ( + range.clone(), + StatementRef { + document_url: self.url.clone(), + text: self.text[range.clone()].to_string(), + idx: pos, + }, + ) + }) + .unwrap() + } +} + +#[cfg(test)] +mod tests { + + use text_size::{TextRange, TextSize}; + + use crate::{Document, PgLspPath}; + + #[test] + fn test_statements_at_range() { + let url = PgLspPath::new("test.sql"); + + let doc = Document::new( + url, + Some("select unknown from contact;\n\nselect 12345;\n\nalter table test drop column id;\n" + .to_string()), + ); + + let x = doc.statements_at_range(&TextRange::new(TextSize::from(2), TextSize::from(5))); + + assert_eq!(x.len(), 1); + + assert_eq!(x[0].text, "select unknown from contact;"); + } +} diff --git a/crates/pg_base_db/src/lib.rs b/crates/pg_base_db/src/lib.rs new file mode 100644 index 00000000..a01f83d2 --- /dev/null +++ b/crates/pg_base_db/src/lib.rs @@ -0,0 +1,22 @@ +//! # pg_base_db +//! +//! This crate implements the basic data structures and implements efficient change management. The idea is to make sure we only recompute what is necessary when a change occurs, and this is done by cutting a sql source into statements, and then applying the changes to individual statements. This way, we can avoid re-parsing the entire sql source when a change occurs. +//! +//! The main data structures are: +//! - `Document`: Represents a sql source file, and contains a list of statements represented by their ranges +//! - `StatementRef`: Represents a reference to a sql statement. This is the primary data structure that is used by higher-level crates to save and retrieve information about a statement. +//! - `DocumentChange`: Contains a list of individual `Change`s, and represents a change to a sql source file. This is used to update a `Document` with a new version of the sql source. +//! - `StatementChange` and `ChangedStatement` are results of applying the change and represent references to the changed statements, including information about the changes that were applied. This is used to invalidate caches and recompute information about the changed statements in higher-level crates. +//! +//! I am not yet 100% happy with this, because when we create a `StatementRef`, the text is cloned from `Document` and included in the Hash. This must be improved by leaving the text in the `Document`, and making the `StatementRef` and actual reference to the text in the `Document`. This will make the `StatementRef` smaller and faster to compare. +//! Additionally, the errors returned by the `pg_statement_splitter::split` are not exposed yet. This must be done to show syntax errors to the user. + +#![feature(extract_if, test)] + +mod change; +mod document; +mod path; + +pub use change::{Change, ChangedStatement, DocumentChange, StatementChange}; +pub use document::{Document, StatementRef}; +pub use path::PgLspPath; diff --git a/crates/pg_base_db/src/path.rs b/crates/pg_base_db/src/path.rs new file mode 100644 index 00000000..994aaa80 --- /dev/null +++ b/crates/pg_base_db/src/path.rs @@ -0,0 +1,22 @@ +use std::{ops::Deref, path::PathBuf}; + +#[derive(Debug, Clone, Eq, Hash, PartialEq)] +pub struct PgLspPath { + path: PathBuf, +} + +impl Deref for PgLspPath { + type Target = PathBuf; + + fn deref(&self) -> &Self::Target { + &self.path + } +} + +impl PgLspPath { + pub fn new(path_to_file: impl Into) -> Self { + Self { + path: path_to_file.into(), + } + } +} diff --git a/crates/pg_commands/Cargo.toml b/crates/pg_commands/Cargo.toml new file mode 100644 index 00000000..1ab7bbf8 --- /dev/null +++ b/crates/pg_commands/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pg_commands" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } +async-std = "1.12.0" +anyhow = "1.0.62" + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_commands/src/command.rs b/crates/pg_commands/src/command.rs new file mode 100644 index 00000000..9449efb6 --- /dev/null +++ b/crates/pg_commands/src/command.rs @@ -0,0 +1,32 @@ +pub enum CommandType { + ExecuteStatement, +} + +impl CommandType { + pub const ALL: [CommandType; 1] = [CommandType::ExecuteStatement]; + + pub fn id(&self) -> &str { + match self { + CommandType::ExecuteStatement => "executeStatement", + } + } + + pub fn label(&self) -> &str { + match self { + CommandType::ExecuteStatement => "Execute Statement", + } + } + + pub fn from_id(s: &str) -> Option { + match s { + "executeStatement" => Some(CommandType::ExecuteStatement), + _ => None, + } + } +} + +pub trait Command { + type ExecuteStatement; + + fn command_type() -> CommandType; +} diff --git a/crates/pg_commands/src/execute_statement.rs b/crates/pg_commands/src/execute_statement.rs new file mode 100644 index 00000000..74e9d544 --- /dev/null +++ b/crates/pg_commands/src/execute_statement.rs @@ -0,0 +1,47 @@ +use sqlx::{postgres::PgQueryResult, Executor, PgPool}; + +use crate::command::{Command, CommandType}; + +pub struct ExecuteStatementCommand { + statement: String, +} + +impl ExecuteStatementCommand { + pub fn new(statement: String) -> Self { + Self { statement } + } + + pub async fn run(&self, conn: Option) -> anyhow::Result { + if let Some(conn) = conn { + match conn.execute(self.statement.as_str()).await { + Ok(res) => Ok(res), + Err(e) => { + return Err(anyhow::anyhow!(e.to_string())); + } + } + } else { + return Err(anyhow::anyhow!("No connection to database".to_string())); + } + } + + pub fn trim_statement(stmt: String, max_length: usize) -> String { + let len = stmt.len(); + if len <= max_length { + return stmt; + } + + let half = max_length / 2; + let start = &stmt[..half]; + let end = &stmt[len - half + (max_length % 2)..]; + + format!("{}...{}", start, end) + } +} + +impl Command for ExecuteStatementCommand { + type ExecuteStatement = ExecuteStatementCommand; + + fn command_type() -> CommandType { + CommandType::ExecuteStatement + } +} diff --git a/crates/pg_commands/src/lib.rs b/crates/pg_commands/src/lib.rs new file mode 100644 index 00000000..8a58fb11 --- /dev/null +++ b/crates/pg_commands/src/lib.rs @@ -0,0 +1,5 @@ +pub mod command; +pub mod execute_statement; + +pub use command::*; +pub use execute_statement::*; diff --git a/crates/pg_completions/Cargo.toml b/crates/pg_completions/Cargo.toml new file mode 100644 index 00000000..5e414a23 --- /dev/null +++ b/crates/pg_completions/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "pg_completions" +version = "0.0.0" +edition = "2021" + +[dependencies] +async-std = "1.12.0" +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } + +text-size = "1.1.1" + +tree-sitter.workspace = true +tree_sitter_sql.workspace = true +pg_schema_cache.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_completions/src/builder.rs b/crates/pg_completions/src/builder.rs new file mode 100644 index 00000000..4075050c --- /dev/null +++ b/crates/pg_completions/src/builder.rs @@ -0,0 +1,29 @@ +use crate::{CompletionItem, CompletionResult}; + +pub struct CompletionBuilder<'a> { + pub items: Vec>, +} + +pub struct CompletionConfig {} + +impl<'a> From<&'a CompletionConfig> for CompletionBuilder<'a> { + fn from(_config: &CompletionConfig) -> Self { + Self { items: Vec::new() } + } +} + +impl<'a> CompletionBuilder<'a> { + pub fn finish(mut self) -> CompletionResult<'a> { + self.items.sort_by(|a, b| { + b.preselect + .cmp(&a.preselect) + .then_with(|| b.score.cmp(&a.score)) + .then_with(|| a.data.label().cmp(b.data.label())) + }); + + self.items.dedup_by(|a, b| a.data.label() == b.data.label()); + self.items.truncate(crate::LIMIT); + let Self { items, .. } = self; + CompletionResult { items } + } +} diff --git a/crates/pg_completions/src/lib.rs b/crates/pg_completions/src/lib.rs new file mode 100644 index 00000000..6b0b19b4 --- /dev/null +++ b/crates/pg_completions/src/lib.rs @@ -0,0 +1,128 @@ +mod builder; +mod providers; + +pub use providers::CompletionProviderParams; +use text_size::{TextRange, TextSize}; + +pub const LIMIT: usize = 50; + +#[derive(Debug)] +pub struct CompletionParams<'a> { + pub position: TextSize, + pub schema: &'a pg_schema_cache::SchemaCache, + pub text: &'a str, + pub tree: Option<&'a tree_sitter::Tree>, +} + +#[derive(Debug, Default)] +pub struct CompletionResult<'a> { + pub items: Vec>, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct CompletionItem<'a> { + pub score: i32, + pub range: TextRange, + pub preselect: bool, + pub data: CompletionItemData<'a>, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum CompletionItemData<'a> { + Table(&'a pg_schema_cache::Table), +} + +impl<'a> CompletionItemData<'a> { + pub fn label(&self) -> &'a str { + match self { + CompletionItemData::Table(t) => t.name.as_str(), + } + } +} + +impl<'a> CompletionItem<'a> { + pub fn new_simple(score: i32, range: TextRange, data: CompletionItemData<'a>) -> Self { + Self { + score, + range, + preselect: false, + data, + } + } +} + +pub fn complete<'a>(params: &'a CompletionParams<'a>) -> CompletionResult<'a> { + let mut builder = builder::CompletionBuilder::from(&builder::CompletionConfig {}); + + let params = CompletionProviderParams::from(params); + + providers::complete_tables(params, &mut builder); + + builder.finish() +} + +#[cfg(test)] +mod tests { + use async_std::task::block_on; + use pg_schema_cache::SchemaCache; + use sqlx::PgPool; + + use crate::{complete, CompletionParams}; + + #[test] + fn test_complete() { + let input = "select id from c;"; + + let conn_string = std::env::var("DB_CONNECTION_STRING").unwrap(); + + let pool = block_on(PgPool::connect(conn_string.as_str())).unwrap(); + + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(tree_sitter_sql::language()) + .expect("Error loading sql language"); + + let tree = parser.parse(input, None).unwrap(); + + let schema_cache = block_on(SchemaCache::load(&pool)); + + let p = CompletionParams { + position: 15.into(), + schema: &schema_cache, + text: input, + tree: Some(&tree), + }; + + let result = complete(&p); + + assert!(result.items.len() > 0); + } + + #[test] + fn test_complete_two() { + let input = "select id, name, test1231234123, unknown from co;"; + + let conn_string = std::env::var("DB_CONNECTION_STRING").unwrap(); + + let pool = block_on(PgPool::connect(conn_string.as_str())).unwrap(); + + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(tree_sitter_sql::language()) + .expect("Error loading sql language"); + + let tree = parser.parse(input, None).unwrap(); + let schema_cache = block_on(SchemaCache::load(&pool)); + + let p = CompletionParams { + position: 47.into(), + schema: &schema_cache, + text: input, + tree: Some(&tree), + }; + + let result = complete(&p); + + assert!(result.items.len() > 0); + } +} diff --git a/crates/pg_completions/src/providers.rs b/crates/pg_completions/src/providers.rs new file mode 100644 index 00000000..355e0ea0 --- /dev/null +++ b/crates/pg_completions/src/providers.rs @@ -0,0 +1,47 @@ +mod tables; + +pub use tables::complete_tables; + +use crate::CompletionParams; + +#[derive(Debug)] +pub struct CompletionProviderParams<'a> { + pub ts_node: Option>, + pub schema: &'a pg_schema_cache::SchemaCache, + pub source: &'a str, +} + +impl<'a> From<&'a CompletionParams<'a>> for CompletionProviderParams<'a> { + fn from(params: &'a CompletionParams) -> Self { + let ts_node = if let Some(tree) = params.tree { + let node = tree.root_node().named_descendant_for_byte_range( + usize::from(params.position), + usize::from(params.position), + ); + + if let Some(mut n) = node { + let node_range = n.range(); + + while let Some(parent) = n.parent() { + if parent.range() != node_range { + break; + } + + n = parent; + } + + Some(n) + } else { + None + } + } else { + None + }; + + Self { + ts_node, + schema: params.schema, + source: params.text, + } + } +} diff --git a/crates/pg_completions/src/providers/tables.rs b/crates/pg_completions/src/providers/tables.rs new file mode 100644 index 00000000..74a52c7e --- /dev/null +++ b/crates/pg_completions/src/providers/tables.rs @@ -0,0 +1,31 @@ +use text_size::{TextRange, TextSize}; + +use crate::{builder::CompletionBuilder, CompletionItem, CompletionItemData}; + +use super::CompletionProviderParams; + +// todo unify this in a type resolver crate +pub fn complete_tables<'a>( + params: CompletionProviderParams<'a>, + builder: &mut CompletionBuilder<'a>, +) { + if let Some(ts) = params.ts_node { + let range = TextRange::new( + TextSize::try_from(ts.start_byte()).unwrap(), + TextSize::try_from(ts.end_byte()).unwrap(), + ); + match ts.kind() { + "relation" => { + // todo better search + params.schema.tables.iter().for_each(|table| { + builder.items.push(CompletionItem::new_simple( + 1, + range, + CompletionItemData::Table(table), + )); + }); + } + _ => {} + } + } +} diff --git a/crates/pg_diagnostics/Cargo.toml b/crates/pg_diagnostics/Cargo.toml new file mode 100644 index 00000000..9dc96750 --- /dev/null +++ b/crates/pg_diagnostics/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pg_diagnostics" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_diagnostics/src/lib.rs b/crates/pg_diagnostics/src/lib.rs new file mode 100644 index 00000000..a1391f85 --- /dev/null +++ b/crates/pg_diagnostics/src/lib.rs @@ -0,0 +1,27 @@ +use std::fmt::Debug; +use text_size::TextRange; + +#[derive(Debug, PartialEq, Eq)] +pub struct Diagnostic { + pub message: String, + pub description: Option, + pub severity: Severity, + pub source: String, + pub range: TextRange, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +/// The severity to associate to a diagnostic. +pub enum Severity { + /// Reports a hint. + Hint, + /// Reports an information. + #[default] + Information, + /// Reports a warning. + Warning, + /// Reports an error. + Error, + /// Reports a crash. + Fatal, +} diff --git a/crates/pg_hover/Cargo.toml b/crates/pg_hover/Cargo.toml new file mode 100644 index 00000000..bdbe4d06 --- /dev/null +++ b/crates/pg_hover/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "pg_hover" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +pg_query_ext.workspace = true +pg_schema_cache.workspace = true +pg_syntax.workspace = true +tree-sitter.workspace = true +tree_sitter_sql.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_hover/src/lib.rs b/crates/pg_hover/src/lib.rs new file mode 100644 index 00000000..dd283ad2 --- /dev/null +++ b/crates/pg_hover/src/lib.rs @@ -0,0 +1,59 @@ +//! # pg_hover +//! +//! This crate implements the hover feature. Essentially, it takes a position in a sql statement, and checks what node is located at that position. If the node is a valid hover result type, it resolves the type from the schema cache and returns it. The consumer of this crate is responsible for rendering the data. +//! +//! Note that we have two ways of resolving the hover result. We first try to resolve it from the enriched AST, and if that fails, we try to resolve it from the tree-sitter CST. This is because the enriched AST is more accurate, but the tree-sitter CST is more reliable. + +mod resolve; + +use pg_schema_cache::SchemaCache; +use resolve::Hoverable; +use text_size::TextRange; + +pub struct HoverParams<'a> { + pub position: text_size::TextSize, + pub source: &'a str, + pub enriched_ast: Option<&'a pg_syntax::AST>, + pub tree: Option<&'a tree_sitter::Tree>, + pub schema_cache: SchemaCache, +} + +#[derive(Debug)] +pub struct HoverResult { + pub range: Option, + pub content: String, +} + +pub fn hover(params: HoverParams) -> Option { + let elem = if params.enriched_ast.is_some() { + resolve::resolve_from_enriched_ast(params.position, params.enriched_ast.unwrap()) + } else if params.tree.is_some() { + resolve::resolve_from_tree_sitter(params.position, params.tree.unwrap(), ¶ms.source) + } else { + None + }; + + if elem.is_none() { + return None; + } + + match elem.unwrap() { + Hoverable::Relation(r) => { + let table = params.schema_cache.find_table(&r.name, r.schema.as_deref()); + + table.map(|t| { + let mut content = t.name.to_owned(); + + if t.comment.is_some() { + content.push_str("\n"); + content.push_str(t.comment.as_ref().unwrap()); + } + + return HoverResult { + range: Some(r.range), + content, + }; + }) + } + } +} diff --git a/crates/pg_hover/src/resolve.rs b/crates/pg_hover/src/resolve.rs new file mode 100644 index 00000000..a7eb8466 --- /dev/null +++ b/crates/pg_hover/src/resolve.rs @@ -0,0 +1,123 @@ +use text_size::{TextRange, TextSize}; +use tree_sitter::Tree; + +#[derive(Debug, Eq, PartialEq)] +pub struct HoverableRelation { + pub name: String, + pub schema: Option, + pub range: TextRange, +} + +#[derive(Debug, Eq, PartialEq)] +pub struct HoverableColumn { + pub name: String, + pub table: Option, + pub schema: Option, + pub range: TextRange, +} + +#[derive(Debug, Eq, PartialEq)] +pub enum Hoverable { + Relation(HoverableRelation), +} + +pub fn resolve_from_enriched_ast(pos: TextSize, ast: &pg_syntax::AST) -> Option { + let node = ast.covering_node(TextRange::empty(pos))?; + + match node.node { + pg_query_ext::NodeEnum::RangeVar(ref range_var) => { + Some(Hoverable::Relation(HoverableRelation { + range: node.range(), + name: range_var.relname.clone(), + schema: if range_var.schemaname.is_empty() { + None + } else { + Some(range_var.schemaname.clone()) + }, + })) + } + _ => None, + } +} + +pub fn resolve_from_tree_sitter(pos: TextSize, tree: &Tree, source: &str) -> Option { + let mut node = tree + .root_node() + .named_descendant_for_byte_range(usize::from(pos), usize::from(pos))?; + + let node_range = node.range(); + + while let Some(parent) = node.parent() { + if parent.range() != node_range { + break; + } + node = parent; + } + + match node.kind() { + "relation" => Some(Hoverable::Relation(HoverableRelation { + range: TextRange::new( + TextSize::try_from(node.range().start_byte).unwrap(), + TextSize::try_from(node.range().end_byte).unwrap(), + ), + name: node.utf8_text(source.as_bytes()).unwrap().to_string(), + schema: None, + })), + _ => None, + } +} + +#[cfg(test)] +mod tests { + use text_size::{TextRange, TextSize}; + + use super::{Hoverable, HoverableRelation}; + + #[test] + fn test_resolve_from_enriched_ast() { + let input = "select id from contact;"; + let position = TextSize::new(15); + + let root = pg_query_ext::parse(input).unwrap(); + let ast = pg_syntax::parse_syntax(input, &root).ast; + + let hover = super::resolve_from_enriched_ast(position, &ast); + + assert!(hover.is_some()); + + assert_eq!( + hover.unwrap(), + Hoverable::Relation(HoverableRelation { + range: TextRange::new(TextSize::new(15), TextSize::new(22)), + name: "contact".to_string(), + schema: None, + }) + ); + } + + #[test] + fn test_resolve_from_tree_sitter() { + let input = "select id from contact;"; + let position = TextSize::new(15); + + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(tree_sitter_sql::language()) + .expect("Error loading sql language"); + + let tree = parser.parse(input, None).unwrap(); + + let hover = super::resolve_from_tree_sitter(position, &tree, input); + + assert!(hover.is_some()); + + assert_eq!( + hover.unwrap(), + Hoverable::Relation(HoverableRelation { + range: TextRange::new(TextSize::new(15), TextSize::new(22)), + name: "contact".to_string(), + schema: None, + }) + ); + } +} diff --git a/crates/pg_inlay_hints/Cargo.toml b/crates/pg_inlay_hints/Cargo.toml new file mode 100644 index 00000000..dd3d4358 --- /dev/null +++ b/crates/pg_inlay_hints/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "pg_inlay_hints" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +pg_query_ext.workspace = true +pg_schema_cache.workspace = true +pg_type_resolver.workspace = true +pg_syntax.workspace = true +tree-sitter.workspace = true +tree_sitter_sql.workspace = true +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } + +[dev-dependencies] +async-std = "1.12.0" + +[lib] +doctest = false + +[features] diff --git a/crates/pg_inlay_hints/README.md b/crates/pg_inlay_hints/README.md new file mode 100644 index 00000000..0b7589aa --- /dev/null +++ b/crates/pg_inlay_hints/README.md @@ -0,0 +1 @@ +- [] Support named args for functions diff --git a/crates/pg_inlay_hints/src/functions_args.rs b/crates/pg_inlay_hints/src/functions_args.rs new file mode 100644 index 00000000..84623a17 --- /dev/null +++ b/crates/pg_inlay_hints/src/functions_args.rs @@ -0,0 +1,128 @@ +use pg_query_ext::ChildrenIterator; +use text_size::TextSize; + +use crate::{ + inlay_hint::{InlayHint, InlayHintContent, InlayHintsResolver}, + InlayHintsParams, +}; + +#[derive(Debug, PartialEq, Eq)] +pub struct FunctionArgHint { + pub name: Option, + pub type_name: String, +} + +impl InlayHintsResolver for FunctionArgHint { + fn find_all(params: InlayHintsParams) -> Vec { + if params.ast.is_none() { + return vec![]; + } + + // args of a function have a correct location in the AST + // so we can make it even easier based off the plain root node + let root = params.ast.unwrap(); + + ChildrenIterator::new(root.to_owned()) + .filter_map(|n| match n { + pg_query_ext::NodeEnum::FuncCall(source_fn) => { + if let Some(schema_fn) = pg_type_resolver::resolve_func_call( + source_fn.as_ref(), + ¶ms.schema_cache, + ) { + Some(resolve_func_arg_hint( + source_fn.as_ref(), + schema_fn, + ¶ms.schema_cache, + )) + } else { + None + } + } + _ => None, + }) + .flatten() + .collect() + } +} + +fn resolve_func_arg_hint( + source_fn: &pg_query_ext::protobuf::FuncCall, + schema_fn: &pg_schema_cache::Function, + schema_cache: &pg_schema_cache::SchemaCache, +) -> Vec { + let mut hints = vec![]; + + // todo support named args + for (func_arg, schema_arg) in source_fn.args.iter().zip(schema_fn.args.args.iter()) { + hints.push(InlayHint { + offset: TextSize::try_from( + pg_query_ext::get_location(func_arg.node.as_ref().unwrap()) + .expect("function arg to have a location"), + ) + .unwrap(), + content: InlayHintContent::FunctionArg(FunctionArgHint { + name: if schema_arg.name == "" { + None + } else { + Some(schema_arg.name.clone()) + }, + type_name: schema_cache + .types + .iter() + .find(|t| t.id == schema_arg.type_id) + .unwrap() + .name + .clone(), + }), + }); + } + + hints +} + +#[cfg(test)] +mod tests { + use async_std::task::block_on; + use pg_schema_cache::SchemaCache; + use sqlx::PgPool; + + use crate::{ + functions_args::FunctionArgHint, + inlay_hint::{InlayHint, InlayHintContent, InlayHintsParams, InlayHintsResolver}, + }; + + #[test] + fn test_function_args() { + let input = "select lower('TEST')"; + + let conn_string = std::env::var("DB_CONNECTION_STRING").unwrap(); + + let pool = block_on(PgPool::connect(conn_string.as_str())).unwrap(); + + let root = pg_query_ext::parse(input).unwrap(); + + let res = pg_syntax::parse_syntax(input, &root); + + let schema_cache = block_on(SchemaCache::load(&pool)); + + let hints = FunctionArgHint::find_all(InlayHintsParams { + ast: Some(&root), + tree: None, + schema_cache: &schema_cache, + enriched_ast: Some(&res.ast), + cst: Some(&res.cst), + }); + + assert_eq!(hints.len(), 1); + assert_eq!( + hints[0], + InlayHint { + offset: 13.into(), + content: InlayHintContent::FunctionArg(FunctionArgHint { + name: None, + type_name: "text".to_string(), + }), + } + ); + } +} diff --git a/crates/pg_inlay_hints/src/inlay_hint.rs b/crates/pg_inlay_hints/src/inlay_hint.rs new file mode 100644 index 00000000..1e5bb091 --- /dev/null +++ b/crates/pg_inlay_hints/src/inlay_hint.rs @@ -0,0 +1,27 @@ +use pg_schema_cache::SchemaCache; +use text_size::TextSize; + +use crate::functions_args::FunctionArgHint; + +pub struct InlayHintsParams<'a> { + pub ast: Option<&'a pg_query_ext::NodeEnum>, + pub enriched_ast: Option<&'a pg_syntax::AST>, + pub tree: Option<&'a tree_sitter::Tree>, + pub cst: Option<&'a pg_syntax::CST>, + pub schema_cache: &'a SchemaCache, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum InlayHintContent { + FunctionArg(FunctionArgHint), +} + +#[derive(Debug, PartialEq, Eq)] +pub struct InlayHint { + pub offset: TextSize, + pub content: InlayHintContent, +} + +pub trait InlayHintsResolver { + fn find_all(params: InlayHintsParams) -> Vec; +} diff --git a/crates/pg_inlay_hints/src/lib.rs b/crates/pg_inlay_hints/src/lib.rs new file mode 100644 index 00000000..ce26a68b --- /dev/null +++ b/crates/pg_inlay_hints/src/lib.rs @@ -0,0 +1,15 @@ +mod functions_args; +mod inlay_hint; + +use inlay_hint::InlayHintsResolver; + +use crate::functions_args::FunctionArgHint; +pub use crate::inlay_hint::{InlayHint, InlayHintContent, InlayHintsParams}; + +pub fn inlay_hints(params: InlayHintsParams) -> Vec { + let mut hints = vec![]; + + hints.extend(FunctionArgHint::find_all(params)); + + hints +} diff --git a/crates/pg_lexer/Cargo.toml b/crates/pg_lexer/Cargo.toml new file mode 100644 index 00000000..4d06d3d3 --- /dev/null +++ b/crates/pg_lexer/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "pg_lexer" +version = "0.0.0" +edition = "2021" + +[dependencies] +regex = "1.9.1" + +pg_query = "0.8" +pg_lexer_codegen.workspace = true + +text-size = "1.1.1" +cstree = { version = "0.12.0", features = ["derive"] } + +[dev-dependencies] +insta = "1.31.0" + +[lib] +doctest = false + diff --git a/crates/pg_lexer/src/codegen.rs b/crates/pg_lexer/src/codegen.rs new file mode 100644 index 00000000..8f91ca0e --- /dev/null +++ b/crates/pg_lexer/src/codegen.rs @@ -0,0 +1,3 @@ +use pg_lexer_codegen::lexer_codegen; + +lexer_codegen!(); diff --git a/crates/parser/src/lexer.rs b/crates/pg_lexer/src/lib.rs similarity index 96% rename from crates/parser/src/lexer.rs rename to crates/pg_lexer/src/lib.rs index 0d180b6c..ece57fb3 100644 --- a/crates/parser/src/lexer.rs +++ b/crates/pg_lexer/src/lib.rs @@ -1,11 +1,11 @@ -use std::{collections::VecDeque, sync::LazyLock}; +mod codegen; use pg_query::protobuf::{KeywordKind, ScanToken}; use regex::Regex; +use std::{collections::VecDeque, sync::LazyLock}; +use text_size::{TextRange, TextSize}; -use cstree::text::{TextRange, TextSize}; - -use crate::codegen::SyntaxKind; +pub use crate::codegen::SyntaxKind; #[derive(Debug, Clone, PartialEq, Eq)] pub enum TokenType { @@ -52,6 +52,13 @@ impl Token { } } +pub static WHITESPACE_TOKENS: &[SyntaxKind] = &[ + SyntaxKind::Whitespace, + SyntaxKind::Tab, + SyntaxKind::Newline, + SyntaxKind::SqlComment, +]; + static PATTERN_LEXER: LazyLock = LazyLock::new(|| Regex::new(r"(?P +)|(?P\n+)|(?P\t+)").unwrap()); @@ -170,14 +177,8 @@ pub fn lex(text: &str) -> Vec { mod tests { use super::*; - fn init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - #[test] fn test_lexer() { - init(); - let input = "select 1; \n -- some comment \n select 2"; let tokens = lex(input); diff --git a/crates/pg_lexer_codegen/Cargo.toml b/crates/pg_lexer_codegen/Cargo.toml new file mode 100644 index 00000000..6376af93 --- /dev/null +++ b/crates/pg_lexer_codegen/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pg_lexer_codegen" +version = "0.0.0" +edition = "2021" + +[dependencies] +proc-macro2 = "1.0.66" +quote = "1.0.33" +pg_query_proto_parser.workspace = true + +[lib] +doctest = false +proc-macro = true + diff --git a/crates/pg_lexer_codegen/src/lib.rs b/crates/pg_lexer_codegen/src/lib.rs new file mode 100644 index 00000000..c041a29a --- /dev/null +++ b/crates/pg_lexer_codegen/src/lib.rs @@ -0,0 +1,30 @@ +mod syntax_kind; + +use pg_query_proto_parser::ProtoParser; +use quote::quote; +use std::{env, path, path::Path}; + +#[proc_macro] +pub fn lexer_codegen(_item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let parser = ProtoParser::new(&proto_file_path()); + let proto_file = parser.parse(); + + let syntax_kind = syntax_kind::syntax_kind_mod(&proto_file); + + quote! { + use pg_query::{protobuf, protobuf::ScanToken, protobuf::Token, NodeEnum, NodeRef}; + use cstree::Syntax; + + #syntax_kind + } + .into() +} + +fn proto_file_path() -> path::PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(2) + .unwrap() + .join("libpg_query/protobuf/pg_query.proto") + .to_path_buf() +} diff --git a/crates/codegen/src/syntax_kind.rs b/crates/pg_lexer_codegen/src/syntax_kind.rs similarity index 100% rename from crates/codegen/src/syntax_kind.rs rename to crates/pg_lexer_codegen/src/syntax_kind.rs diff --git a/crates/pg_lint/Cargo.toml b/crates/pg_lint/Cargo.toml new file mode 100644 index 00000000..37ce0de0 --- /dev/null +++ b/crates/pg_lint/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "pg_lint" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +pg_base_db.workspace = true +pg_query_ext.workspace = true +pg_syntax.workspace = true +serde_plain = "1.0" +serde = "1.0.195" +lazy_static = "1.4.0" +serde_json = "1.0" + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_lint/src/lib.rs b/crates/pg_lint/src/lib.rs new file mode 100644 index 00000000..a9fb9b35 --- /dev/null +++ b/crates/pg_lint/src/lib.rs @@ -0,0 +1,44 @@ +use lazy_static::lazy_static; +use text_size::TextSize; +pub use violations::{RuleViolation, RuleViolationKind, ViolationMessage}; + +use crate::rules::ban_drop_column::ban_drop_column; + +mod rules; +mod violations; + +pub struct LinterParams<'a> { + pub ast: &'a pg_query_ext::NodeEnum, + pub enriched_ast: Option<&'a pg_syntax::AST>, +} + +#[derive(Clone)] +pub struct LintRule { + pub name: RuleViolationKind, + func: fn(&LinterParams) -> Vec, + pub messages: Vec, +} + +lazy_static! { + pub static ref RULES: Vec = vec![LintRule { + name: RuleViolationKind::BanDropColumn, + func: ban_drop_column, + messages: vec![ViolationMessage::Note( + "Dropping a column may break existing clients.".into() + ),], + }]; +} + +pub fn check_sql(params: LinterParams) -> Vec { + let mut errs = vec![]; + for rule in RULES.iter() { + errs.extend((rule.func)(¶ms)); + } + + errs.sort_by_key(|v| match v.range { + Some(r) => r.start(), + None => TextSize::new(0), + }); + + errs +} diff --git a/crates/pg_lint/src/rules/ban_drop_column.rs b/crates/pg_lint/src/rules/ban_drop_column.rs new file mode 100644 index 00000000..42301ba2 --- /dev/null +++ b/crates/pg_lint/src/rules/ban_drop_column.rs @@ -0,0 +1,43 @@ +use crate::{ + violations::{RuleViolation, RuleViolationKind}, + LinterParams, +}; + +pub fn ban_drop_column(params: &LinterParams) -> Vec { + let mut errs: Vec = vec![]; + + if let Some(enriched_ast) = params.enriched_ast { + if let pg_query_ext::NodeEnum::AlterTableStmt(_) = &enriched_ast.root_node().node { + for node in enriched_ast.iter_nodes() { + if let pg_query_ext::NodeEnum::AlterTableCmd(cmd) = &node.node { + if cmd.subtype() == pg_query_ext::protobuf::AlterTableType::AtDropColumn { + errs.push(RuleViolation::new( + RuleViolationKind::BanDropColumn, + Some(node.range()), + None, + )); + } + } + } + } + } else { + match ¶ms.ast { + pg_query_ext::NodeEnum::AlterTableStmt(stmt) => { + for cmd in &stmt.cmds { + if let Some(pg_query_ext::NodeEnum::AlterTableCmd(cmd)) = &cmd.node { + if cmd.subtype() == pg_query_ext::protobuf::AlterTableType::AtDropColumn { + errs.push(RuleViolation::new( + RuleViolationKind::BanDropColumn, + None, + None, + )); + } + } + } + } + _ => {} + } + } + + errs +} diff --git a/crates/pg_lint/src/rules/mod.rs b/crates/pg_lint/src/rules/mod.rs new file mode 100644 index 00000000..a396405a --- /dev/null +++ b/crates/pg_lint/src/rules/mod.rs @@ -0,0 +1 @@ +pub mod ban_drop_column; diff --git a/crates/pg_lint/src/violations.rs b/crates/pg_lint/src/violations.rs new file mode 100644 index 00000000..a3f74322 --- /dev/null +++ b/crates/pg_lint/src/violations.rs @@ -0,0 +1,79 @@ +use std::str::FromStr; + +use crate::RULES; +use serde::{Deserialize, Serialize}; +use text_size::TextRange; + +#[derive(Debug, PartialEq, Clone, Serialize, Hash, Eq, Deserialize)] +pub enum RuleViolationKind { + #[serde(rename = "ban-drop-column")] + BanDropColumn, +} + +impl std::fmt::Display for RuleViolationKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + serde_plain::to_string(self).map_err(|_| std::fmt::Error)? + ) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnknownRuleName { + val: String, +} + +impl std::fmt::Display for UnknownRuleName { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "invalid rule name {}", self.val) + } +} + +impl std::str::FromStr for RuleViolationKind { + type Err = UnknownRuleName; + fn from_str(s: &str) -> Result { + serde_plain::from_str(s).map_err(|_| UnknownRuleName { val: s.to_string() }) + } +} + +impl std::convert::TryFrom<&str> for RuleViolationKind { + type Error = UnknownRuleName; + fn try_from(s: &str) -> Result { + RuleViolationKind::from_str(s) + } +} + +#[derive(Debug, PartialEq, Serialize, Clone)] +pub enum ViolationMessage { + Note(String), + Help(String), +} + +#[derive(Debug, PartialEq)] +pub struct RuleViolation { + pub kind: RuleViolationKind, + pub range: Option, + pub messages: Vec, +} + +impl RuleViolation { + pub fn new( + kind: RuleViolationKind, + range: Option, + messages: Option>, + ) -> Self { + let messages = messages.unwrap_or_else(|| { + RULES + .iter() + .find(|r| r.name == kind) + .map_or_else(Vec::new, |x| x.messages.clone()) + }); + Self { + kind, + range, + messages, + } + } +} diff --git a/crates/pg_lsp/Cargo.toml b/crates/pg_lsp/Cargo.toml new file mode 100644 index 00000000..122e3ccd --- /dev/null +++ b/crates/pg_lsp/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "pg_lsp" +version = "0.0.0" +edition = "2021" + +[[bin]] +name = "pglsp" +path = "src/main.rs" +test = false + +[dependencies] +lsp-server = "0.7.6" +crossbeam-channel = "0.5.12" +async-channel = "2.3.1" +lsp-types = "0.95.0" +serde = "1.0.195" +serde_json = "1.0.114" +anyhow = "1.0.81" +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } +async-std = "1.12.0" +threadpool = "1.8.1" +dashmap = "5.5.3" +text-size = "1.1.1" + +line_index.workspace = true + +pg_hover.workspace = true +pg_completions.workspace = true +pg_inlay_hints.workspace = true +pg_commands.workspace = true +pg_base_db.workspace = true +pg_schema_cache.workspace = true +pg_workspace.workspace = true +pg_diagnostics.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_lsp/src/client.rs b/crates/pg_lsp/src/client.rs new file mode 100644 index 00000000..85ff5a61 --- /dev/null +++ b/crates/pg_lsp/src/client.rs @@ -0,0 +1,121 @@ +pub mod client_flags; + +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicI32, Ordering}, + Arc, Mutex, + }, +}; + +use anyhow::{bail, Result}; +use crossbeam_channel::Sender; +use lsp_server::{ErrorCode, Message, Request, RequestId, Response}; +use lsp_types::{notification::ShowMessage, MessageType, ShowMessageParams}; +use serde::{de::DeserializeOwned, Serialize}; + +use crate::server::options::Options; + +#[derive(Debug)] +struct RawClient { + sender: Sender, + next_id: AtomicI32, + pending: Mutex>>, +} + +#[derive(Debug, Clone)] +pub struct LspClient { + raw: Arc, +} + +impl LspClient { + pub fn new(sender: Sender) -> Self { + let raw = Arc::new(RawClient { + sender, + next_id: AtomicI32::new(1), + pending: Default::default(), + }); + + Self { raw } + } + + pub fn send_notification(&self, params: N::Params) -> Result<()> + where + N: lsp_types::notification::Notification, + N::Params: Serialize, + { + self.raw + .sender + .send(lsp_server::Notification::new(N::METHOD.to_string(), params).into())?; + Ok(()) + } + + pub fn send_request(&self, params: R::Params) -> Result + where + R: lsp_types::request::Request, + R::Params: Serialize, + R::Result: DeserializeOwned, + { + let id = RequestId::from(self.raw.next_id.fetch_add(1, Ordering::SeqCst)); + + let (tx, rx) = crossbeam_channel::bounded(1); + self.raw.pending.lock().unwrap().insert(id.clone(), tx); + + self.raw + .sender + .send(Request::new(id, R::METHOD.to_string(), params).into())?; + + let response = rx.recv()?; + let result = match response.error { + Some(error) => bail!(error.message), + None => response.result.unwrap_or_default(), + }; + + Ok(serde_json::from_value(result)?) + } + + pub fn send_response(&self, response: lsp_server::Response) -> Result<()> { + self.raw.sender.send(response.into())?; + Ok(()) + } + + pub fn send_error(&self, id: RequestId, code: ErrorCode, message: String) -> Result<()> { + self.send_response(lsp_server::Response::new_err(id, code as i32, message))?; + Ok(()) + } + + pub fn recv_response(&self, response: lsp_server::Response) -> Result<()> { + let tx = self + .raw + .pending + .lock() + .unwrap() + .remove(&response.id) + .expect("response with known request id received"); + + tx.send(response)?; + Ok(()) + } + + pub fn parse_options(&self, mut value: serde_json::Value) -> Result { + // if there are multiple servers, we need to extract the options for pglsp first + let options = match value.get_mut("pglsp") { + Some(section) => section.take(), + None => value, + }; + + let options = match serde_json::from_value(options) { + Ok(new_options) => new_options, + Err(why) => { + let message = format!( + "The texlab configuration is invalid; using the default settings instead.\nDetails: {why}" + ); + let typ = MessageType::WARNING; + self.send_notification::(ShowMessageParams { message, typ })?; + None + } + }; + + Ok(options.unwrap_or_default()) + } +} diff --git a/crates/pg_lsp/src/client/client_flags.rs b/crates/pg_lsp/src/client/client_flags.rs new file mode 100644 index 00000000..8fca812d --- /dev/null +++ b/crates/pg_lsp/src/client/client_flags.rs @@ -0,0 +1,10 @@ +/// Contains information about the client's capabilities. +/// This is used to determine which features the server can use. +#[derive(Debug, Clone)] +pub struct ClientFlags { + /// If `true`, the server can pull the configuration from the client. + pub configuration_pull: bool, + + /// If `true`, the client notifies the server when the configuration changes. + pub configuration_push: bool, +} diff --git a/crates/pg_lsp/src/lib.rs b/crates/pg_lsp/src/lib.rs new file mode 100644 index 00000000..ac95c913 --- /dev/null +++ b/crates/pg_lsp/src/lib.rs @@ -0,0 +1,3 @@ +mod client; +pub mod server; +mod utils; diff --git a/crates/pg_lsp/src/main.rs b/crates/pg_lsp/src/main.rs new file mode 100644 index 00000000..eb5eddb6 --- /dev/null +++ b/crates/pg_lsp/src/main.rs @@ -0,0 +1,10 @@ +use lsp_server::Connection; +use pg_lsp::server::Server; + +fn main() -> anyhow::Result<()> { + let (connection, threads) = Connection::stdio(); + Server::init(connection)?; + threads.join()?; + + Ok(()) +} diff --git a/crates/pg_lsp/src/server.rs b/crates/pg_lsp/src/server.rs new file mode 100644 index 00000000..927d7f16 --- /dev/null +++ b/crates/pg_lsp/src/server.rs @@ -0,0 +1,891 @@ +mod debouncer; +mod dispatch; +pub mod options; + +use async_std::task::{self}; +use crossbeam_channel::{unbounded, Receiver, Sender}; +use lsp_server::{Connection, ErrorCode, Message, RequestId}; +use lsp_types::{ + notification::{ + DidChangeConfiguration, DidChangeTextDocument, DidCloseTextDocument, DidOpenTextDocument, + DidSaveTextDocument, Notification as _, PublishDiagnostics, ShowMessage, + }, + request::{ + CodeActionRequest, Completion, ExecuteCommand, HoverRequest, InlayHintRequest, + RegisterCapability, WorkspaceConfiguration, + }, + CompletionList, CompletionOptions, ConfigurationItem, ConfigurationParams, + DidChangeConfigurationParams, DidChangeTextDocumentParams, DidCloseTextDocumentParams, + DidOpenTextDocumentParams, DidSaveTextDocumentParams, ExecuteCommandOptions, + ExecuteCommandParams, HoverProviderCapability, InitializeParams, InitializeResult, + PublishDiagnosticsParams, Registration, RegistrationParams, SaveOptions, ServerCapabilities, + ServerInfo, ShowMessageParams, TextDocumentSyncCapability, TextDocumentSyncKind, + TextDocumentSyncOptions, TextDocumentSyncSaveOptions, +}; +use pg_base_db::{Change, DocumentChange}; +use pg_commands::{Command, CommandType, ExecuteStatementCommand}; +use pg_completions::CompletionParams; +use pg_hover::HoverParams; +use pg_schema_cache::SchemaCache; +use pg_workspace::Workspace; +use serde::{de::DeserializeOwned, Serialize}; +use std::{collections::HashSet, sync::Arc, time::Duration}; +use text_size::TextSize; +use threadpool::ThreadPool; + +use crate::{ + client::{client_flags::ClientFlags, LspClient}, + utils::{file_path, from_proto, line_index_ext::LineIndexExt, normalize_uri, to_proto}, +}; + +use self::{debouncer::EventDebouncer, options::Options}; +use sqlx::{ + postgres::{PgListener, PgPool}, + Executor, +}; + +#[derive(Debug)] +enum InternalMessage { + PublishDiagnostics(lsp_types::Url), + SetOptions(Options), + RefreshSchemaCache, + SetSchemaCache(SchemaCache), +} + +#[derive(Debug)] +struct DbConnection { + pub pool: PgPool, + connection_string: String, +} + +impl DbConnection { + pub async fn new(connection_string: &str) -> Result { + let pool = PgPool::connect(connection_string).await?; + Ok(Self { + pool, + connection_string: connection_string.to_owned(), + }) + } +} + +pub struct Server { + connection: Arc, + client: LspClient, + internal_tx: Sender, + internal_rx: Receiver, + pool: Arc, + client_flags: Arc, + ide: Arc, + db_conn: Option, + compute_debouncer: EventDebouncer>, +} + +impl Server { + pub fn init(connection: Connection) -> anyhow::Result<()> { + let client = LspClient::new(connection.sender.clone()); + + let (internal_tx, internal_rx) = unbounded(); + + let (id, params) = connection.initialize_start()?; + let params: InitializeParams = serde_json::from_value(params)?; + + let result = InitializeResult { + capabilities: Self::capabilities(), + server_info: Some(ServerInfo { + name: "Postgres LSP".to_owned(), + version: Some(env!("CARGO_PKG_VERSION").to_owned()), + }), + }; + + connection.initialize_finish(id, serde_json::to_value(result)?)?; + + let client_flags = Arc::new(from_proto::client_flags(params.capabilities)); + + let pool = Arc::new(threadpool::Builder::new().build()); + + let ide = Arc::new(Workspace::new()); + + let cloned_tx = internal_tx.clone(); + let cloned_ide = ide.clone(); + let cloned_pool = pool.clone(); + let cloned_client = client.clone(); + + let server = Self { + connection: Arc::new(connection), + internal_rx, + internal_tx, + client, + client_flags, + db_conn: None, + ide, + compute_debouncer: EventDebouncer::new( + Duration::from_millis(500), + move |conn: Option| { + let inner_cloned_ide = cloned_ide.clone(); + let inner_cloned_tx = cloned_tx.clone(); + let inner_cloned_client = cloned_client.clone(); + cloned_pool.execute(move || { + inner_cloned_client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("Computing debounced {}", conn.is_some()), + }) + .unwrap(); + let r = + async_std::task::block_on(conn.as_ref().unwrap().execute("SELECT 1")); + inner_cloned_client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("res {:?}", r.unwrap()), + }) + .unwrap(); + + let changed = inner_cloned_ide.compute(conn); + + let urls = HashSet::<&str>::from_iter( + changed.iter().map(|f| f.document_url.to_str().unwrap()), + ); + for url in urls.iter() { + inner_cloned_tx + .send(InternalMessage::PublishDiagnostics( + lsp_types::Url::from_file_path(url).unwrap(), + )) + .unwrap(); + } + }); + }, + ), + pool, + }; + + server.run()?; + Ok(()) + } + + fn compute_now(&self) { + let conn = self.db_conn.as_ref().map(|p| p.pool.clone()); + let cloned_ide = self.ide.clone(); + let cloned_tx = self.internal_tx.clone(); + let client = self.client.clone(); + + self.compute_debouncer.clear(); + + self.pool.execute(move || { + client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("Computing now {}", conn.is_some()), + }) + .unwrap(); + + if conn.is_some() { + client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("pool closed {}", conn.as_ref().unwrap().is_closed()), + }) + .unwrap(); + + let r = async_std::task::block_on(conn.as_ref().unwrap().execute("SELECT 1")); + client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("res {:?}", r.unwrap()), + }) + .unwrap(); + } + let changed = cloned_ide.compute(conn); + let urls = HashSet::<&str>::from_iter( + changed.iter().map(|f| f.document_url.to_str().unwrap()), + ); + + for url in urls { + cloned_tx + .send(InternalMessage::PublishDiagnostics( + lsp_types::Url::from_file_path(url).unwrap(), + )) + .unwrap(); + } + }); + } + + fn start_listening(&self) { + if self.db_conn.is_none() { + return; + } + + let pool = self.db_conn.as_ref().unwrap().pool.clone(); + let tx = self.internal_tx.clone(); + + task::spawn(async move { + let mut listener = PgListener::connect_with(&pool).await.unwrap(); + listener + .listen_all(["postgres_lsp", "pgrst"]) + .await + .unwrap(); + + loop { + match listener.recv().await { + Ok(notification) => { + if notification.payload().to_string() == "reload schema" { + tx.send(InternalMessage::RefreshSchemaCache).unwrap(); + } + } + Err(e) => { + eprintln!("Listener error: {}", e); + break; + } + } + } + }); + } + + async fn update_db_connection(&mut self, connection_string: Option) { + if connection_string == self.db_conn.as_ref().map(|c| c.connection_string.clone()) { + return; + } + if let Some(conn) = self.db_conn.take() { + conn.pool.close().await; + } + + if connection_string.is_none() { + return; + } + + let new_conn = DbConnection::new(connection_string.unwrap().as_str()).await; + + if new_conn.is_err() { + return; + } + + self.db_conn = Some(new_conn.unwrap()); + + self.client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: "Connection to database established".to_string(), + }) + .unwrap(); + + self.refresh_schema_cache(); + + self.start_listening(); + } + + fn update_options(&mut self, options: Options) { + async_std::task::block_on(self.update_db_connection(options.db_connection_string)); + } + + fn capabilities() -> ServerCapabilities { + ServerCapabilities { + text_document_sync: Some(TextDocumentSyncCapability::Options( + TextDocumentSyncOptions { + open_close: Some(true), + change: Some(TextDocumentSyncKind::INCREMENTAL), + will_save: None, + will_save_wait_until: None, + save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions { + include_text: Some(false), + })), + }, + )), + hover_provider: Some(HoverProviderCapability::Simple(true)), + execute_command_provider: Some(ExecuteCommandOptions { + commands: CommandType::ALL + .iter() + .map(|c| c.id().to_string()) + .collect(), + ..Default::default() + }), + inlay_hint_provider: Some(lsp_types::OneOf::Left(true)), + code_action_provider: Some(lsp_types::CodeActionProviderCapability::Simple(true)), + completion_provider: Some(CompletionOptions::default()), + ..ServerCapabilities::default() + } + } + + // TODO allow option url and publish diagnostics for all files + fn publish_diagnostics(&self, uri: lsp_types::Url) -> anyhow::Result<()> { + let mut url = uri.clone(); + normalize_uri(&mut url); + + let path = file_path(&url); + + let doc = self.ide.documents.get(&path); + + if doc.is_none() { + return Ok(()); + } + + let diagnostics: Vec = self + .ide + .diagnostics(&path) + .iter() + .map(|d| to_proto::diagnostic(&doc.as_ref().unwrap(), d)) + .collect(); + + self.client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("diagnostics {}", diagnostics.len()), + }) + .unwrap(); + + let params = PublishDiagnosticsParams { + uri, + diagnostics, + version: None, + }; + + self.client + .send_notification::(params)?; + + Ok(()) + } + + fn did_open(&self, params: DidOpenTextDocumentParams) -> anyhow::Result<()> { + let mut uri = params.text_document.uri; + + normalize_uri(&mut uri); + + let path = file_path(&uri); + + self.ide.apply_change( + path, + DocumentChange::new( + params.text_document.version, + vec![Change { + range: None, + text: params.text_document.text, + }], + ), + ); + + self.compute_now(); + + Ok(()) + } + + fn did_change(&self, params: DidChangeTextDocumentParams) -> anyhow::Result<()> { + let mut uri = params.text_document.uri; + normalize_uri(&mut uri); + + let path = file_path(&uri); + + let document = self.ide.documents.get(&path); + + if document.is_none() { + return Ok(()); + } + + let changes = from_proto::content_changes(&document.unwrap(), params.content_changes); + + self.ide.apply_change( + path, + DocumentChange::new(params.text_document.version, changes), + ); + + let conn = self.db_conn.as_ref().map(|p| p.pool.clone()); + self.compute_debouncer.put(conn); + + Ok(()) + } + + fn did_save(&self, params: DidSaveTextDocumentParams) -> anyhow::Result<()> { + let mut uri = params.text_document.uri; + normalize_uri(&mut uri); + + self.publish_diagnostics(uri)?; + + self.compute_now(); + + Ok(()) + } + + fn did_close(&self, params: DidCloseTextDocumentParams) -> anyhow::Result<()> { + // this just means that the document is no longer open in the client + // if we would listen to fs events, we would use this to overwrite the files owner to be + // "server" instead of "client". for now we will ignore this notification since we dont + // need to watch files that are not open. + + let mut uri = params.text_document.uri; + normalize_uri(&mut uri); + let path = file_path(&uri); + + self.ide.remove_document(path); + + Ok(()) + } + + fn code_actions( + &self, + id: RequestId, + params: lsp_types::CodeActionParams, + ) -> anyhow::Result<()> { + let db_conn = self.db_conn.as_ref().map(|p| p.pool.clone()); + self.run_query(id, move |ide| { + let mut actions = Vec::::new(); + + if db_conn.is_none() { + return actions; + } + + let mut uri = params.text_document.uri; + normalize_uri(&mut uri); + let path = file_path(&uri); + + let doc = ide.documents.get(&path); + + if doc.is_none() { + return actions; + } + + let doc = doc.unwrap(); + + let range = doc.line_index.offset_lsp_range(params.range).unwrap(); + + actions.extend(doc.statements_at_range(&range).iter().map(|stmt| { + let cmd = ExecuteStatementCommand::command_type(); + let title = format!( + "Execute '{}'", + ExecuteStatementCommand::trim_statement(stmt.text.clone(), 50) + ); + lsp_types::CodeAction { + title: title.clone(), + kind: None, + edit: None, + command: Some(lsp_types::Command { + title, + command: format!("pglsp.{}", cmd.id()), + arguments: Some(vec![serde_json::to_value(stmt.text.clone()).unwrap()]), + }), + diagnostics: None, + is_preferred: None, + disabled: None, + data: None, + } + })); + + actions + }); + + Ok(()) + } + + fn inlay_hint( + &self, + id: RequestId, + mut params: lsp_types::InlayHintParams, + ) -> anyhow::Result<()> { + normalize_uri(&mut params.text_document.uri); + + let c = self.client.clone(); + + self.run_query(id, move |ide| { + let path = file_path(¶ms.text_document.uri); + + let doc = ide.documents.get(&path); + + if doc.is_none() { + return Vec::new(); + } + + let doc = doc.unwrap(); + + let range = doc.line_index.offset_lsp_range(params.range).unwrap(); + + let schema_cache = ide.schema_cache.read().unwrap(); + + c.send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: "querying inlay hints".to_string(), + }) + .unwrap(); + + doc.statements_at_range(&range) + .iter() + .flat_map(|stmt| { + ::pg_inlay_hints::inlay_hints(::pg_inlay_hints::InlayHintsParams { + ast: ide.pg_query.ast(&stmt).as_ref().map(|x| x.as_ref()), + enriched_ast: ide + .pg_query + .enriched_ast(&stmt) + .as_ref() + .map(|x| x.as_ref()), + tree: ide.tree_sitter.tree(&stmt).as_ref().map(|x| x.as_ref()), + cst: ide.pg_query.cst(&stmt).as_ref().map(|x| x.as_ref()), + schema_cache: &schema_cache, + }) + }) + .map(|hint| lsp_types::InlayHint { + position: doc.line_index.line_col_lsp(hint.offset).unwrap(), + label: match hint.content { + pg_inlay_hints::InlayHintContent::FunctionArg(arg) => { + lsp_types::InlayHintLabel::String(match arg.name { + Some(name) => format!("{} ({})", name, arg.type_name), + None => arg.type_name.clone(), + }) + } + }, + kind: match hint.content { + pg_inlay_hints::InlayHintContent::FunctionArg(_) => { + Some(lsp_types::InlayHintKind::PARAMETER) + } + }, + text_edits: None, + tooltip: None, + padding_left: None, + padding_right: None, + data: None, + }) + .collect() + }); + + Ok(()) + } + + fn completion( + &self, + id: RequestId, + mut params: lsp_types::CompletionParams, + ) -> anyhow::Result<()> { + normalize_uri(&mut params.text_document_position.text_document.uri); + + self.run_query(id, move |ide| { + let path = file_path(¶ms.text_document_position.text_document.uri); + + let doc = ide.documents.get(&path)?; + + let pos = doc + .line_index + .offset_lsp(params.text_document_position.position) + .unwrap(); + + let (range, stmt) = doc.statement_at_offset_with_range(&pos)?; + + let schema = ide.schema_cache.read().unwrap(); + + Some(CompletionList { + is_incomplete: false, + items: pg_completions::complete(&CompletionParams { + position: pos - range.start() - TextSize::from(1), + text: stmt.text.as_str(), + tree: ide.tree_sitter.tree(&stmt).as_ref().map(|x| x.as_ref()), + schema: &schema, + }) + .items + .iter() + .map(|i| lsp_types::CompletionItem { + // TODO: add more data + label: i.data.label().to_string(), + label_details: None, + kind: Some(lsp_types::CompletionItemKind::CLASS), + detail: None, + documentation: None, + deprecated: None, + preselect: None, + sort_text: None, + filter_text: None, + insert_text: None, + insert_text_format: None, + insert_text_mode: None, + text_edit: None, + additional_text_edits: None, + commit_characters: None, + data: None, + tags: None, + command: None, + }) + .collect(), + }) + }); + + Ok(()) + } + + fn hover(&self, id: RequestId, mut params: lsp_types::HoverParams) -> anyhow::Result<()> { + normalize_uri(&mut params.text_document_position_params.text_document.uri); + + self.run_query(id, move |ide| { + let path = file_path(¶ms.text_document_position_params.text_document.uri); + let doc = ide.documents.get(&path)?; + + let pos = doc + .line_index + .offset_lsp(params.text_document_position_params.position) + .unwrap(); + + let (range, stmt) = doc.statement_at_offset_with_range(&pos)?; + + ::pg_hover::hover(HoverParams { + position: pos - range.start(), + source: stmt.text.as_str(), + enriched_ast: ide + .pg_query + .enriched_ast(&stmt) + .as_ref() + .map(|x| x.as_ref()), + tree: ide.tree_sitter.tree(&stmt).as_ref().map(|x| x.as_ref()), + schema_cache: ide.schema_cache.read().unwrap().clone(), + }) + .map(|hover| lsp_types::Hover { + contents: lsp_types::HoverContents::Scalar(lsp_types::MarkedString::String( + hover.content, + )), + range: Some(doc.line_index.line_col_lsp_range(range).unwrap()), + }) + }); + + Ok(()) + } + + fn execute_command(&self, id: RequestId, params: ExecuteCommandParams) -> anyhow::Result<()> { + match CommandType::from_id(params.command.replace("pglsp.", "").as_str()) { + Some(CommandType::ExecuteStatement) => { + let stmt = self.parse_command_params::(params.arguments)?; + + let command = ExecuteStatementCommand::new(stmt); + + let conn = self.db_conn.as_ref().map(|p| p.pool.clone()); + + let client = self.client.clone(); + + self.run_fallible(id, move || { + // todo return the rows and do something with them + // maybe store them and add the table to the hover output? + let res = async_std::task::block_on(command.run(conn))?; + + // todo if its a ddl statement, recompute schema cache + + client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: format!("Success! Affected rows: {}", res.rows_affected()), + }) + .unwrap(); + + Ok(()) + }); + } + None => { + self.client + .send_error( + id, + ErrorCode::InvalidParams, + format!("Unknown command: {}", params.command), + ) + .unwrap(); + } + }; + + Ok(()) + } + + fn run_fallible(&self, id: RequestId, query: Q) + where + R: Serialize, + Q: FnOnce() -> anyhow::Result + Send + 'static, + { + let client = self.client.clone(); + self.pool.execute(move || match query() { + Ok(result) => { + let response = lsp_server::Response::new_ok(id, result); + client.send_response(response).unwrap(); + } + Err(why) => { + client + .send_error(id, ErrorCode::InternalError, why.to_string()) + .unwrap(); + } + }); + } + + fn parse_command_params( + &self, + params: Vec, + ) -> anyhow::Result { + if params.is_empty() { + anyhow::bail!("No argument provided!"); + } + + let value = params.into_iter().next().unwrap(); + let value = serde_json::from_value(value)?; + Ok(value) + } + + fn run_query(&self, id: RequestId, query: Q) + where + R: Serialize, + Q: FnOnce(&Workspace) -> R + Send + 'static, + { + let client = self.client.clone(); + let ide = Arc::clone(&self.ide); + + self.pool.execute(move || { + let response = lsp_server::Response::new_ok(id, query(&ide)); + client.send_response(response).unwrap(); + }); + } + + fn refresh_schema_cache(&self) { + if self.db_conn.is_none() { + return; + } + + let tx = self.internal_tx.clone(); + let conn = self.db_conn.as_ref().unwrap().pool.clone(); + let client = self.client.clone(); + + async_std::task::spawn(async move { + client + .send_notification::(ShowMessageParams { + typ: lsp_types::MessageType::INFO, + message: "Refreshing schema cache...".to_string(), + }) + .unwrap(); + let schema_cache = SchemaCache::load(&conn).await; + tx.send(InternalMessage::SetSchemaCache(schema_cache)) + .unwrap(); + }); + } + + fn did_change_configuration( + &mut self, + params: DidChangeConfigurationParams, + ) -> anyhow::Result<()> { + if self.client_flags.configuration_pull { + self.pull_options(); + } else { + let options = self.client.parse_options(params.settings)?; + self.update_options(options); + } + + Ok(()) + } + + fn process_messages(&mut self) -> anyhow::Result<()> { + loop { + crossbeam_channel::select! { + recv(&self.connection.receiver) -> msg => { + match msg? { + Message::Request(request) => { + if self.connection.handle_shutdown(&request)? { + return Ok(()); + } + + if let Some(response) = dispatch::RequestDispatcher::new(request) + .on::(|id, params| self.inlay_hint(id, params))? + .on::(|id, params| self.hover(id, params))? + .on::(|id, params| self.execute_command(id, params))? + .on::(|id, params| { + self.completion(id, params) + })? + .on::(|id, params| { + self.code_actions(id, params) + })? + .default() + { + self.client.send_response(response)?; + } + } + Message::Notification(notification) => { + dispatch::NotificationDispatcher::new(notification) + .on::(|params| { + self.did_change_configuration(params) + })? + .on::(|params| self.did_close(params))? + .on::(|params| self.did_open(params))? + .on::(|params| self.did_change(params))? + .on::(|params| self.did_save(params))? + .on::(|params| self.did_close(params))? + .default(); + } + Message::Response(response) => { + self.client.recv_response(response)?; + } + }; + }, + recv(&self.internal_rx) -> msg => { + match msg? { + InternalMessage::SetSchemaCache(c) => { + self.ide.set_schema_cache(c); + self.compute_now(); + } + InternalMessage::RefreshSchemaCache => { + self.refresh_schema_cache(); + } + InternalMessage::PublishDiagnostics(uri) => { + self.publish_diagnostics(uri)?; + } + InternalMessage::SetOptions(options) => { + self.update_options(options); + } + }; + } + }; + } + } + + fn pull_options(&mut self) { + if !self.client_flags.configuration_pull { + return; + } + + let params = ConfigurationParams { + items: vec![ConfigurationItem { + section: Some("postgres_lsp".to_string()), + scope_uri: None, + }], + }; + + let client = self.client.clone(); + let sender = self.internal_tx.clone(); + self.pool.execute(move || { + match client.send_request::(params) { + Ok(mut json) => { + let options = client + .parse_options(json.pop().expect("invalid configuration request")) + .unwrap(); + + sender.send(InternalMessage::SetOptions(options)).unwrap(); + } + Err(_why) => { + // log::error!("Retrieving configuration failed: {}", why); + } + }; + }); + } + + fn register_configuration(&mut self) { + if self.client_flags.configuration_push { + let registration = Registration { + id: "pull-config".to_string(), + method: DidChangeConfiguration::METHOD.to_string(), + register_options: None, + }; + + let params = RegistrationParams { + registrations: vec![registration], + }; + + let client = self.client.clone(); + self.pool.execute(move || { + if let Err(_why) = client.send_request::(params) { + // log::error!( + // "Failed to register \"{}\" notification: {}", + // DidChangeConfiguration::METHOD, + // why + // ); + } + }); + } + } + + pub fn run(mut self) -> anyhow::Result<()> { + self.register_configuration(); + self.pull_options(); + self.process_messages()?; + self.pool.join(); + Ok(()) + } +} diff --git a/crates/pg_lsp/src/server/debouncer/buffer.rs b/crates/pg_lsp/src/server/debouncer/buffer.rs new file mode 100644 index 00000000..6fa0574e --- /dev/null +++ b/crates/pg_lsp/src/server/debouncer/buffer.rs @@ -0,0 +1,92 @@ +use std::collections::VecDeque; +use std::time::{Duration, Instant}; + +#[derive(Debug)] +struct Event { + item: T, + release_at: Instant, +} + +/// Current state of the debouncing buffer returned from [Get::get()]: +/// +/// - `Ready(T)` when the event is ready to be delivered after the timeout +/// (moves data out of the buffer) +/// - `Wait(Duration)` indicates how much time is left until `Ready` +/// - `Empty` means the buffer is empty +#[derive(Debug, PartialEq, Eq)] +pub enum State { + Ready(T), + Wait(Duration), + Empty, +} + +/// Common interface for getting events out of debouncing buffers. +pub trait Get: Sized { + type Data; + + /// Attemtps to get the next element out of a buffer. If an element is + /// [State::Ready] it's removed from the buffer. + fn get(&mut self) -> State; +} + +/// Debouncing buffer with a common delay for all events. Accepts events via +/// [EventBuffer::put()] which tracks the time of events and de-duplicates them +/// against the current buffer content. Subsequent call to [EventBuffer::get +/// ()] which returns the [State] of the buffer. +pub struct EventBuffer { + delay: Duration, + events: VecDeque>, +} + +impl EventBuffer { + pub fn new(delay: Duration) -> EventBuffer { + EventBuffer { + delay, + events: VecDeque::new(), + } + } + + pub fn put(&mut self, item: T) { + let time = Instant::now(); + self.events.retain(|e| e.release_at <= time); + self.events.push_back(Event { + item, + release_at: time + self.delay, + }); + } + + pub fn clear(&mut self) { + self.events.clear(); + } +} + +impl Get for EventBuffer { + type Data = T; + + fn get(&mut self) -> State { + let time = Instant::now(); + match self.events.get(0) { + None => State::Empty, + Some(e) if e.release_at > time => State::Wait(e.release_at - time), + Some(_) => State::Ready(self.events.pop_front().unwrap().item), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::thread::sleep; + use std::time::Duration; + + #[test] + fn wait() { + let mut debouncer = EventBuffer::new(Duration::from_millis(20)); + debouncer.put(1); + assert!(matches!(debouncer.get(), State::Wait(_))); + sleep(Duration::from_millis(10)); + assert!(matches!(debouncer.get(), State::Wait(_))); + sleep(Duration::from_millis(10)); + assert!(matches!(debouncer.get(), State::Ready(_))); + } +} diff --git a/crates/pg_lsp/src/server/debouncer/mod.rs b/crates/pg_lsp/src/server/debouncer/mod.rs new file mode 100644 index 00000000..c0c42899 --- /dev/null +++ b/crates/pg_lsp/src/server/debouncer/mod.rs @@ -0,0 +1,7 @@ +//! Data structures and helpers for *debouncing* a stream of events: removing +//! duplicate events occurring closely in time. + +pub mod buffer; +pub mod thread; + +pub use thread::EventDebouncer; diff --git a/crates/pg_lsp/src/server/debouncer/thread.rs b/crates/pg_lsp/src/server/debouncer/thread.rs new file mode 100644 index 00000000..1aa85939 --- /dev/null +++ b/crates/pg_lsp/src/server/debouncer/thread.rs @@ -0,0 +1,96 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; +use std::thread::{self, JoinHandle}; +use std::time::Duration; + +use super::buffer::{EventBuffer, Get, State}; + +struct DebouncerThread { + mutex: Arc>, + thread: JoinHandle<()>, + stopped: Arc, +} + +impl DebouncerThread { + fn new(buffer: B, mut f: F) -> Self + where + B: Get + Send + 'static, + F: FnMut(B::Data) + Send + 'static, + { + let mutex = Arc::new(Mutex::new(buffer)); + let stopped = Arc::new(AtomicBool::new(false)); + let thread = thread::spawn({ + let mutex = mutex.clone(); + let stopped = stopped.clone(); + move || { + while !stopped.load(Ordering::Relaxed) { + let state = mutex.lock().unwrap().get(); + match state { + State::Empty => thread::park(), + State::Wait(duration) => thread::sleep(duration), + State::Ready(data) => f(data), + } + } + } + }); + Self { + mutex, + thread, + stopped, + } + } + + fn stop(self) -> JoinHandle<()> { + self.stopped.store(true, Ordering::Relaxed); + self.thread + } +} + +/// Threaded debouncer wrapping [EventBuffer]. Accepts a common delay and a +/// callback function which is going to be called by a background thread with +/// debounced events. +pub struct EventDebouncer(DebouncerThread>); + +impl EventDebouncer { + pub fn new(delay: Duration, f: F) -> Self + where + F: FnMut(T) + Send + 'static, + T: Send + 'static, + { + Self(DebouncerThread::new(EventBuffer::new(delay), f)) + } + + pub fn put(&self, data: T) { + self.0.mutex.lock().unwrap().put(data); + self.0.thread.thread().unpark(); + } + + pub fn clear(&self) { + self.0.mutex.lock().unwrap().clear(); + } + + /// Signals the debouncer thread to quit and returns a + /// [std::thread::JoinHandle] which can be `.join()`ed in the consumer + /// thread. The common idiom is: `debouncer.stop().join().unwrap();` + pub fn stop(self) -> JoinHandle<()> { + self.0.stop() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::mpsc::channel; + + #[test] + fn event_debouncer() { + let (tx, rx) = channel(); + let debouncer = EventDebouncer::new(Duration::from_millis(10), move |s| { + tx.send(s).unwrap(); + }); + debouncer.put(String::from("Test1")); + debouncer.put(String::from("Test2")); + thread::sleep(Duration::from_millis(20)); + assert!(rx.try_iter().eq([String::from("Test2")])); + } +} diff --git a/crates/pg_lsp/src/server/dispatch.rs b/crates/pg_lsp/src/server/dispatch.rs new file mode 100644 index 00000000..d8c3dc7f --- /dev/null +++ b/crates/pg_lsp/src/server/dispatch.rs @@ -0,0 +1,86 @@ +use anyhow::Result; +use lsp_server::{ErrorCode, Notification, Request, RequestId, Response}; +use serde::de::DeserializeOwned; + +pub struct NotificationDispatcher { + not: Option, +} + +impl NotificationDispatcher { + pub fn new(not: Notification) -> Self { + Self { not: Some(not) } + } + + pub fn on(mut self, handler: F) -> Result + where + N: lsp_types::notification::Notification, + N::Params: DeserializeOwned, + F: FnOnce(N::Params) -> Result<()>, + { + if let Some(not) = self.not { + match not.extract::(N::METHOD) { + Ok(params) => { + handler(params)?; + self.not = None; + } + Err(lsp_server::ExtractError::MethodMismatch(not)) => { + self.not = Some(not); + } + Err(lsp_server::ExtractError::JsonError { .. }) => { + self.not = None; + } + }; + } + Ok(self) + } + + pub fn default(self) { + if let Some(_not) = &self.not { + // log::warn!("Unknown notification: {}", not.method); + } + } +} + +pub struct RequestDispatcher { + req: Option, +} + +impl RequestDispatcher { + pub fn new(req: Request) -> Self { + Self { req: Some(req) } + } + + pub fn on(mut self, handler: F) -> Result + where + R: lsp_types::request::Request, + R::Params: DeserializeOwned, + F: FnOnce(RequestId, R::Params) -> Result<()>, + { + if let Some(req) = self.req { + match req.extract::(R::METHOD) { + Ok((id, params)) => { + handler(id, params)?; + self.req = None; + } + Err(lsp_server::ExtractError::MethodMismatch(req)) => { + self.req = Some(req); + } + Err(lsp_server::ExtractError::JsonError { .. }) => { + self.req = None; + } + } + } + Ok(self) + } + + pub fn default(self) -> Option { + self.req.map(|req| { + // log::warn!("Unknown request: {}", req.method); + Response::new_err( + req.id, + ErrorCode::MethodNotFound as i32, + "method not found".to_string(), + ) + }) + } +} diff --git a/crates/pg_lsp/src/server/options.rs b/crates/pg_lsp/src/server/options.rs new file mode 100644 index 00000000..a9d89c7e --- /dev/null +++ b/crates/pg_lsp/src/server/options.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(default)] +pub struct Options { + pub db_connection_string: Option, +} diff --git a/crates/pg_lsp/src/utils.rs b/crates/pg_lsp/src/utils.rs new file mode 100644 index 00000000..b176bda2 --- /dev/null +++ b/crates/pg_lsp/src/utils.rs @@ -0,0 +1,77 @@ +pub mod from_proto; +pub mod line_index_ext; +pub mod to_proto; + +use std::path::PathBuf; + +use lsp_types; +use pg_base_db::PgLspPath; + +/// Convert a `lsp_types::Url` to a `PgLspPath`. +pub(crate) fn file_path(url: &lsp_types::Url) -> PgLspPath { + let path_to_file = match url.to_file_path() { + Err(_) => { + // If we can't create a path, it's probably because the file doesn't exist. + // It can be a newly created file that it's not on disk + PathBuf::from(url.path()) + } + Ok(path) => path, + }; + + PgLspPath::new(path_to_file) +} + +pub fn normalize_uri(uri: &mut lsp_types::Url) { + if let Some(mut segments) = uri.path_segments() { + if let Some(mut path) = segments.next().and_then(fix_drive_letter) { + for segment in segments { + path.push('/'); + path.push_str(segment); + } + + uri.set_path(&path); + } + } + + uri.set_fragment(None); +} + +fn fix_drive_letter(text: &str) -> Option { + if !text.is_ascii() { + return None; + } + + match &text[1..] { + ":" => Some(text.to_ascii_uppercase()), + "%3A" | "%3a" => Some(format!("{}:", text[0..1].to_ascii_uppercase())), + _ => None, + } +} + +#[cfg(test)] +mod tests { + use lsp_types::Url; + + use super::normalize_uri; + + #[test] + fn test_lowercase_drive_letter() { + let mut uri = Url::parse("file://c:/foo/bar.txt").unwrap(); + normalize_uri(&mut uri); + assert_eq!(uri.as_str(), "file:///C:/foo/bar.txt"); + } + + #[test] + fn test_uppercase_drive_letter() { + let mut uri = Url::parse("file://C:/foo/bar.txt").unwrap(); + normalize_uri(&mut uri); + assert_eq!(uri.as_str(), "file:///C:/foo/bar.txt"); + } + + #[test] + fn test_fragment() { + let mut uri = Url::parse("foo:///bar/baz.txt#qux").unwrap(); + normalize_uri(&mut uri); + assert_eq!(uri.as_str(), "foo:///bar/baz.txt"); + } +} diff --git a/crates/pg_lsp/src/utils/from_proto.rs b/crates/pg_lsp/src/utils/from_proto.rs new file mode 100644 index 00000000..47708be7 --- /dev/null +++ b/crates/pg_lsp/src/utils/from_proto.rs @@ -0,0 +1,39 @@ +use crate::client::client_flags::ClientFlags; + +use super::line_index_ext::LineIndexExt; +use pg_base_db::{Change, Document}; + +pub fn content_changes( + document: &Document, + changes: Vec, +) -> Vec { + changes + .iter() + .map(|change| Change { + range: change + .range + .map(|range| document.line_index.offset_lsp_range(range).unwrap()), + text: change.text.clone(), + }) + .collect() +} + +pub fn client_flags(capabilities: lsp_types::ClientCapabilities) -> ClientFlags { + let configuration_pull = capabilities + .workspace + .as_ref() + .and_then(|cap| cap.configuration) + .unwrap_or(false); + + let configuration_push = capabilities + .workspace + .as_ref() + .and_then(|cap| cap.did_change_configuration) + .and_then(|cap| cap.dynamic_registration) + .unwrap_or(false); + + ClientFlags { + configuration_pull, + configuration_push, + } +} diff --git a/crates/pg_lsp/src/utils/line_index_ext.rs b/crates/pg_lsp/src/utils/line_index_ext.rs new file mode 100644 index 00000000..6928326c --- /dev/null +++ b/crates/pg_lsp/src/utils/line_index_ext.rs @@ -0,0 +1,77 @@ +use line_index::{LineCol, LineColUtf16, LineIndex}; +use lsp_types::{Position, Range}; +use text_size::{TextRange, TextSize}; + +pub trait LineIndexExt { + fn offset_lsp(&self, line_col: Position) -> Option; + + fn offset_lsp_range(&self, line_col: Range) -> Option; + + fn line_col_lsp(&self, offset: TextSize) -> Option; + + fn line_col_lsp_range(&self, offset: TextRange) -> Option; +} + +impl LineIndexExt for LineIndex { + fn offset_lsp(&self, line_col: Position) -> Option { + let line_col = LineColUtf16 { + line: line_col.line, + col: line_col.character, + }; + + let line_col = self.to_utf8(line_col)?; + self.offset(line_col) + } + + fn offset_lsp_range(&self, line_col: Range) -> Option { + let start = self.offset_lsp(line_col.start)?; + let end = self.offset_lsp(line_col.end)?; + Some(TextRange::new(start, end)) + } + + fn line_col_lsp(&self, offset: TextSize) -> Option { + let line_col = self.line_col(offset); + let line_col = self.to_utf16(line_col)?; + Some(Position::new(line_col.line, line_col.col)) + } + + fn line_col_lsp_range(&self, offset: TextRange) -> Option { + let start = self.line_col_lsp(offset.start())?; + let mut end = self.line_col_lsp(offset.end())?; + if end.line != start.line && end.character == 0 { + // Prefer keeping multi-line ranges on the same line + let line_end = self.offset(LineCol { + line: end.line, + col: 0, + })?; + + end = self.line_col_lsp(line_end - TextSize::from(1))?; + } + + Some(Range::new(start, end)) + } +} + +#[cfg(test)] +mod tests { + use pg_base_db::{Document, PgLspPath}; + use text_size::{TextRange, TextSize}; + + use crate::utils::line_index_ext::LineIndexExt; + + #[test] + fn test_line_col_lsp_range() { + let url = PgLspPath::new("test.sql"); + + let d = Document::new( + url, + Some("select 1 from contact;\nselect 1;\nalter table test drop column id;".to_string()), + ); + + println!( + "{:#?}", + d.line_index + .line_col_lsp_range(TextRange::new(TextSize::new(52), TextSize::new(66))) + ); + } +} diff --git a/crates/pg_lsp/src/utils/to_proto.rs b/crates/pg_lsp/src/utils/to_proto.rs new file mode 100644 index 00000000..f06f80f8 --- /dev/null +++ b/crates/pg_lsp/src/utils/to_proto.rs @@ -0,0 +1,25 @@ +use pg_base_db::Document; +use pg_diagnostics::Diagnostic; + +use super::line_index_ext::LineIndexExt; + +pub fn diagnostic(document: &Document, diagnostic: &Diagnostic) -> lsp_types::Diagnostic { + let severity = match diagnostic.severity { + pg_diagnostics::Severity::Error => lsp_types::DiagnosticSeverity::ERROR, + pg_diagnostics::Severity::Warning => lsp_types::DiagnosticSeverity::WARNING, + pg_diagnostics::Severity::Information => lsp_types::DiagnosticSeverity::INFORMATION, + pg_diagnostics::Severity::Hint => lsp_types::DiagnosticSeverity::HINT, + pg_diagnostics::Severity::Fatal => lsp_types::DiagnosticSeverity::ERROR, + }; + + let range = document + .line_index + .line_col_lsp_range(diagnostic.range) + .unwrap(); + + lsp_types::Diagnostic { + severity: Some(severity), + source: Some(diagnostic.source.clone()), + ..lsp_types::Diagnostic::new_simple(range, diagnostic.message.clone()) + } +} diff --git a/crates/pg_query_ext/Cargo.toml b/crates/pg_query_ext/Cargo.toml new file mode 100644 index 00000000..a169947b --- /dev/null +++ b/crates/pg_query_ext/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pg_query_ext" +version = "0.0.0" +edition = "2021" + +[dependencies] +pg_query = "0.8" +petgraph = "0.6.4" + +pg_query_ext_codegen.workspace = true +pg_lexer.workspace = true + +[lib] +doctest = false diff --git a/crates/pg_query_ext/src/codegen.rs b/crates/pg_query_ext/src/codegen.rs new file mode 100644 index 00000000..a11526a8 --- /dev/null +++ b/crates/pg_query_ext/src/codegen.rs @@ -0,0 +1 @@ +pg_query_ext_codegen::codegen!(); diff --git a/crates/pg_query_ext/src/lib.rs b/crates/pg_query_ext/src/lib.rs new file mode 100644 index 00000000..92a9bc8c --- /dev/null +++ b/crates/pg_query_ext/src/lib.rs @@ -0,0 +1,32 @@ +//! Postgres Statement Parser +//! +//! Simple wrapper crate for `pg_query` to expose types and a function to get the root node for an +//! SQL statement. +//! +//! It also host any "extensions" to the `pg_query` crate that are not yet contributed upstream. +//! Extensions include +//! - `get_location` to get the location of a node +//! - `get_node_properties` to get the properties of a node +//! - `get_nodes` to get all the nodes in the AST as a petgraph tree +//! - `ChildrenIterator` to iterate over the children of a node +mod codegen; + +pub use pg_query::protobuf; +pub use pg_query::{Error, NodeEnum, Result}; + +pub use codegen::{ + get_location, get_node_properties, get_nodes, ChildrenIterator, Node, TokenProperty, +}; + +pub fn parse(sql: &str) -> Result { + pg_query::parse(sql).map(|parsed| { + parsed + .protobuf + .nodes() + .iter() + .find(|n| n.1 == 1) + .unwrap() + .0 + .to_enum() + }) +} diff --git a/crates/codegen/Cargo.toml b/crates/pg_query_ext_codegen/Cargo.toml similarity index 61% rename from crates/codegen/Cargo.toml rename to crates/pg_query_ext_codegen/Cargo.toml index 86b06851..55a8fa7d 100644 --- a/crates/codegen/Cargo.toml +++ b/crates/pg_query_ext_codegen/Cargo.toml @@ -1,13 +1,12 @@ [package] -name = "codegen" +name = "pg_query_ext_codegen" version = "0.0.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] proc-macro2 = "1.0.66" quote = "1.0.33" + pg_query_proto_parser.workspace = true [lib] diff --git a/crates/codegen/src/get_location.rs b/crates/pg_query_ext_codegen/src/get_location.rs similarity index 100% rename from crates/codegen/src/get_location.rs rename to crates/pg_query_ext_codegen/src/get_location.rs diff --git a/crates/codegen/src/get_node_properties.rs b/crates/pg_query_ext_codegen/src/get_node_properties.rs similarity index 99% rename from crates/codegen/src/get_node_properties.rs rename to crates/pg_query_ext_codegen/src/get_node_properties.rs index e16a090e..df7cca6b 100644 --- a/crates/codegen/src/get_node_properties.rs +++ b/crates/pg_query_ext_codegen/src/get_node_properties.rs @@ -315,9 +315,9 @@ fn custom_handlers(node: &Node) -> TokenStream { tokens.push(TokenProperty::from(Token::Table)); }, "AlterTableCmd" => quote! { - tokens.push(TokenProperty::from(Token::Alter)); match n.subtype() { protobuf::AlterTableType::AtColumnDefault => { + tokens.push(TokenProperty::from(Token::Alter)); tokens.push(TokenProperty::from(Token::Column)); tokens.push(TokenProperty::from(Token::Set)); tokens.push(TokenProperty::from(Token::Default)); @@ -328,6 +328,10 @@ fn custom_handlers(node: &Node) -> TokenStream { tokens.push(TokenProperty::from(Token::Column)); tokens.push(TokenProperty::from(Token::TypeP)); }, + protobuf::AlterTableType::AtDropColumn => { + tokens.push(TokenProperty::from(Token::Drop)); + tokens.push(TokenProperty::from(Token::Column)); + }, _ => panic!("Unknown AlterTableCmd {:#?}", n.subtype()), } }, diff --git a/crates/codegen/src/get_nodes.rs b/crates/pg_query_ext_codegen/src/get_nodes.rs similarity index 95% rename from crates/codegen/src/get_nodes.rs rename to crates/pg_query_ext_codegen/src/get_nodes.rs index 73574f44..bf317440 100644 --- a/crates/codegen/src/get_nodes.rs +++ b/crates/pg_query_ext_codegen/src/get_nodes.rs @@ -11,7 +11,7 @@ pub fn get_nodes_mod(proto_file: &ProtoFile) -> proc_macro2::TokenStream { quote! { #[derive(Debug, Clone)] pub struct Node { - pub kind: SyntaxKind, + pub inner: NodeEnum, pub depth: usize, pub properties: Vec, pub location: Option, @@ -19,19 +19,19 @@ pub fn get_nodes_mod(proto_file: &ProtoFile) -> proc_macro2::TokenStream { /// Returns all children of the node, recursively /// location is resolved manually - pub fn get_nodes(node: &NodeEnum, at_depth: usize) -> StableGraph { + pub fn get_nodes(node: &NodeEnum) -> StableGraph { let mut g = StableGraph::::new(); let root_node_idx = g.add_node(Node { - kind: SyntaxKind::from(node), - depth: at_depth, + inner: node.to_owned(), + depth: 0, properties: get_node_properties(node, None), location: get_location(node), }); // Parent node idx, Node, depth let mut stack: VecDeque<(NodeIndex, NodeEnum, usize)> = - VecDeque::from(vec![(root_node_idx, node.to_owned(), at_depth)]); + VecDeque::from(vec![(root_node_idx, node.to_owned(), 0)]); while !stack.is_empty() { let (parent_idx, node, depth) = stack.pop_front().unwrap(); let current_depth = depth + 1; @@ -48,10 +48,10 @@ pub fn get_nodes_mod(proto_file: &ProtoFile) -> proc_macro2::TokenStream { g[parent_idx].properties.extend(get_node_properties(&c, Some(&node))); } else { let node_idx = g.add_node(Node { - kind: SyntaxKind::from(&c), depth: current_depth, properties: get_node_properties(&c, Some(&node)), location: get_location(&c), + inner: c.to_owned(), }); g.add_edge(parent_idx, node_idx, ()); stack.push_back((node_idx, c.to_owned(), current_depth)); diff --git a/crates/codegen/src/parser.rs b/crates/pg_query_ext_codegen/src/lib.rs similarity index 69% rename from crates/codegen/src/parser.rs rename to crates/pg_query_ext_codegen/src/lib.rs index 775a1ae0..16e87d7a 100644 --- a/crates/codegen/src/parser.rs +++ b/crates/pg_query_ext_codegen/src/lib.rs @@ -1,37 +1,41 @@ +mod get_location; +mod get_node_properties; +mod get_nodes; +mod node_iterator; + +use get_location::get_location_mod; +use get_node_properties::get_node_properties_mod; +use get_nodes::get_nodes_mod; +use node_iterator::node_iterator_mod; use pg_query_proto_parser::ProtoParser; use quote::quote; use std::{env, path, path::Path}; -use crate::{ - get_location::get_location_mod, get_node_properties::get_node_properties_mod, - get_nodes::get_nodes_mod, syntax_kind::syntax_kind_mod, -}; - -pub fn parser_mod(_item: proc_macro2::TokenStream) -> proc_macro2::TokenStream { +#[proc_macro] +pub fn codegen(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { let parser = ProtoParser::new(&proto_file_path()); let proto_file = parser.parse(); - let syntax_kind = syntax_kind_mod(&proto_file); let get_location = get_location_mod(&proto_file); let get_node_properties = get_node_properties_mod(&proto_file); let get_nodes = get_nodes_mod(&proto_file); + let iterator = node_iterator_mod(&proto_file); quote! { + use pg_lexer::SyntaxKind; use std::collections::VecDeque; - use log::{debug}; use pg_query::{protobuf, protobuf::ScanToken, protobuf::Token, NodeEnum, NodeRef}; - use cstree::text::{TextRange, TextSize}; - use cstree::Syntax; use std::cmp::{min, Ordering}; use std::fmt::{Display, Formatter}; use petgraph::stable_graph::{StableGraph}; use petgraph::graph::{NodeIndex}; - #syntax_kind #get_location #get_node_properties #get_nodes + #iterator } + .into() } fn proto_file_path() -> path::PathBuf { diff --git a/crates/pg_query_ext_codegen/src/node_iterator.rs b/crates/pg_query_ext_codegen/src/node_iterator.rs new file mode 100644 index 00000000..ce8721e1 --- /dev/null +++ b/crates/pg_query_ext_codegen/src/node_iterator.rs @@ -0,0 +1,123 @@ +use pg_query_proto_parser::{FieldType, Node, ProtoFile}; +use proc_macro2::{Ident, TokenStream}; +use quote::{format_ident, quote}; + +pub fn node_iterator_mod(proto_file: &ProtoFile) -> proc_macro2::TokenStream { + let manual_node_names = manual_node_names(); + + let node_identifiers = node_identifiers(&proto_file.nodes, &manual_node_names); + let node_handlers = node_handlers(&proto_file.nodes, &manual_node_names); + + quote! { + #[derive(Debug, Clone)] + pub struct ChildrenIterator { + stack: VecDeque<(NodeEnum, usize)>, + nodes: Vec, + } + + impl ChildrenIterator { + pub fn new(root: NodeEnum) -> Self { + Self { + stack: VecDeque::from(vec![(root, 0)]), + nodes: Vec::new(), + } + } + } + + impl Iterator for ChildrenIterator { + type Item = NodeEnum; + + fn next(&mut self) -> Option { + if self.stack.is_empty() { + return None; + } + + let (node, depth) = self.stack.pop_front().unwrap(); + + let current_depth = depth + 1; + + match &node { + // `AConst` is the only node with a `one of` property, so we handle it manually + // if you need to handle other nodes manually, add them to the `manual_node_names` function below + NodeEnum::AConst(n) => { + // if n.val.is_some() { + // let new_node = match n.val.as_ref().unwrap() { + // pg_query::protobuf::a_const::Val::Ival(v) => Box::new(NodeEnum::Integer(v.clone())), + // pg_query::protobuf::a_const::Val::Fval(v) => Box::new(NodeEnum::Float(v.clone())), + // pg_query::protobuf::a_const::Val::Boolval(v) => Box::new(NodeEnum::Boolean(v.clone())), + // pg_query::protobuf::a_const::Val::Sval(v) => Box::new(NodeEnum::String(v.clone())), + // pg_query::protobuf::a_const::Val::Bsval(v) => Box::new(NodeEnum::BitString(v.clone())), + // }; + // self.stack.push_back((&new_node, current_depth)); + // self.boxed_nodes.push(new_node); + // } + } + #(NodeEnum::#node_identifiers(n) => {#node_handlers}),*, + }; + + Some(node) + } + } + } +} + +fn manual_node_names() -> Vec<&'static str> { + vec!["AConst"] +} + +fn node_identifiers(nodes: &[Node], exclude_nodes: &[&str]) -> Vec { + nodes + .iter() + .filter(|node| !exclude_nodes.contains(&node.name.as_str())) + .map(|node| format_ident!("{}", &node.name)) + .collect() +} + +fn node_handlers(nodes: &[Node], exclude_nodes: &[&str]) -> Vec { + nodes + .iter() + .filter(|node| !exclude_nodes.contains(&node.name.as_str())) + .map(|node| { + let property_handlers = property_handlers(&node); + quote! { + #(#property_handlers)* + } + }) + .collect() +} + +fn property_handlers(node: &Node) -> Vec { + node.fields + .iter() + .filter_map(|field| { + let field_name = format_ident!("{}", field.name.as_str()); + if field.field_type == FieldType::Node && field.repeated { + Some(quote! { + n.#field_name + .iter() + .for_each(|x| if x.node.is_some() { + self.stack.push_back((x.node.as_ref().unwrap().to_owned(), current_depth)); + }); + }) + } else if field.field_type == FieldType::Node && field.is_one_of == false { + if field.node_name == Some("Node".to_owned()) { + Some(quote! { + if n.#field_name.is_some() { + self.stack.push_back((n.#field_name.to_owned().unwrap().node.unwrap(), current_depth)); + } + }) + } else { + let enum_variant_name = + format_ident!("{}", field.enum_variant_name.as_ref().unwrap().as_str()); + Some(quote! { + if n.#field_name.is_some() { + self.stack.push_back((NodeEnum::#enum_variant_name(n.#field_name.to_owned().unwrap()), current_depth)); + } + }) + } + } else { + None + } + }) + .collect() +} diff --git a/crates/schema_cache/Cargo.toml b/crates/pg_schema_cache/Cargo.toml similarity index 76% rename from crates/schema_cache/Cargo.toml rename to crates/pg_schema_cache/Cargo.toml index 68b497ae..9086bb98 100644 --- a/crates/schema_cache/Cargo.toml +++ b/crates/pg_schema_cache/Cargo.toml @@ -1,11 +1,13 @@ [package] -name = "schema_cache" +name = "pg_schema_cache" version = "0.0.0" edition = "2021" [dependencies] sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } async-std = { version = "1.12.0" } +serde = "1.0.195" +serde_json = "1.0.114" [lib] doctest = false diff --git a/crates/pg_schema_cache/src/functions.rs b/crates/pg_schema_cache/src/functions.rs new file mode 100644 index 00000000..29c97e4f --- /dev/null +++ b/crates/pg_schema_cache/src/functions.rs @@ -0,0 +1,189 @@ +use serde::{Deserialize, Serialize}; +use sqlx::types::JsonValue; +use sqlx::PgPool; + +use crate::schema_cache::SchemaCacheItem; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum Behavior { + Immutable, + Stable, + Volatile, +} + +impl Default for Behavior { + fn default() -> Self { + Behavior::Volatile + } +} + +impl From> for Behavior { + fn from(s: Option) -> Self { + match s { + Some(s) => match s.as_str() { + "IMMUTABLE" => Behavior::Immutable, + "STABLE" => Behavior::Stable, + "VOLATILE" => Behavior::Volatile, + _ => panic!("Invalid behavior"), + }, + None => Behavior::Volatile, + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct FunctionArg { + pub mode: String, + pub name: String, + pub type_id: i64, + pub has_default: Option, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct FunctionArgs { + pub args: Vec, +} + +impl From> for FunctionArgs { + fn from(s: Option) -> Self { + let args: Vec = + serde_json::from_value(s.unwrap_or(JsonValue::Array(vec![]))).unwrap(); + FunctionArgs { args } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct Function { + pub id: Option, + pub schema: Option, + pub name: Option, + pub language: Option, + pub definition: Option, + pub complete_statement: Option, + pub args: FunctionArgs, + pub argument_types: Option, + pub identity_argument_types: Option, + pub return_type_id: Option, + pub return_type: Option, + pub return_type_relation_id: Option, + pub is_set_returning_function: bool, + pub behavior: Behavior, + pub security_definer: bool, +} + +impl SchemaCacheItem for Function { + type Item = Function; + + async fn load(pool: &PgPool) -> Vec { + sqlx::query_as!( + Function, + r#" +with functions as ( + select + *, + -- proargmodes is null when all arg modes are IN + coalesce( + p.proargmodes, + array_fill('i'::text, array[cardinality(coalesce(p.proallargtypes, p.proargtypes))]) + ) as arg_modes, + -- proargnames is null when all args are unnamed + coalesce( + p.proargnames, + array_fill(''::text, array[cardinality(coalesce(p.proallargtypes, p.proargtypes))]) + ) as arg_names, + -- proallargtypes is null when all arg modes are IN + coalesce(p.proallargtypes, p.proargtypes) as arg_types, + array_cat( + array_fill(false, array[pronargs - pronargdefaults]), + array_fill(true, array[pronargdefaults])) as arg_has_defaults + from + pg_proc as p + where + p.prokind = 'f' +) +select + f.oid::int8 as id, + n.nspname as schema, + f.proname as name, + l.lanname as language, + case + when l.lanname = 'internal' then '' + else f.prosrc + end as definition, + case + when l.lanname = 'internal' then f.prosrc + else pg_get_functiondef(f.oid) + end as complete_statement, + coalesce(f_args.args, '[]') as args, + pg_get_function_arguments(f.oid) as argument_types, + pg_get_function_identity_arguments(f.oid) as identity_argument_types, + f.prorettype::int8 as return_type_id, + pg_get_function_result(f.oid) as return_type, + nullif(rt.typrelid::int8, 0) as return_type_relation_id, + f.proretset as is_set_returning_function, + case + when f.provolatile = 'i' then 'IMMUTABLE' + when f.provolatile = 's' then 'STABLE' + when f.provolatile = 'v' then 'VOLATILE' + end as behavior, + f.prosecdef as security_definer +from + functions f + left join pg_namespace n on f.pronamespace = n.oid + left join pg_language l on f.prolang = l.oid + left join pg_type rt on rt.oid = f.prorettype + left join ( + select + oid, + jsonb_object_agg(param, value) filter (where param is not null) as config_params + from + ( + select + oid, + (string_to_array(unnest(proconfig), '='))[1] as param, + (string_to_array(unnest(proconfig), '='))[2] as value + from + functions + ) as t + group by + oid + ) f_config on f_config.oid = f.oid + left join ( + select + oid, + jsonb_agg(jsonb_build_object( + 'mode', t2.mode, + 'name', name, + 'type_id', type_id, + 'has_default', has_default + )) as args + from + ( + select + oid, + unnest(arg_modes) as mode, + unnest(arg_names) as name, + unnest(arg_types)::int8 as type_id, + unnest(arg_has_defaults) as has_default + from + functions + ) as t1, + lateral ( + select + case + when t1.mode = 'i' then 'in' + when t1.mode = 'o' then 'out' + when t1.mode = 'b' then 'inout' + when t1.mode = 'v' then 'variadic' + else 'table' + end as mode + ) as t2 + group by + t1.oid + ) f_args on f_args.oid = f.oid"# + ) + .fetch_all(pool) + .await + .unwrap() + } +} diff --git a/crates/schema_cache/src/lib.rs b/crates/pg_schema_cache/src/lib.rs similarity index 80% rename from crates/schema_cache/src/lib.rs rename to crates/pg_schema_cache/src/lib.rs index bcf13ed1..f1e020a5 100644 --- a/crates/schema_cache/src/lib.rs +++ b/crates/pg_schema_cache/src/lib.rs @@ -3,13 +3,17 @@ #![allow(dead_code)] #![feature(future_join)] +mod functions; mod schema_cache; mod schemas; mod tables; +mod types; use sqlx::postgres::PgPool; +pub use functions::{Behavior, Function, FunctionArg, FunctionArgs}; pub use schema_cache::SchemaCache; +pub use tables::{ReplicaIdentity, Table}; #[derive(Debug, Clone)] struct SchemaCacheManager { diff --git a/crates/pg_schema_cache/src/schema_cache.rs b/crates/pg_schema_cache/src/schema_cache.rs new file mode 100644 index 00000000..639393a2 --- /dev/null +++ b/crates/pg_schema_cache/src/schema_cache.rs @@ -0,0 +1,90 @@ +use std::future::join; + +use sqlx::postgres::PgPool; + +use crate::functions::Function; +use crate::schemas::Schema; +use crate::tables::Table; +use crate::types::PostgresType; + +#[derive(Debug, Clone, Default)] +pub struct SchemaCache { + pub schemas: Vec, + pub tables: Vec, + pub functions: Vec, + pub types: Vec, +} + +impl SchemaCache { + pub fn new() -> SchemaCache { + SchemaCache::default() + } + + pub async fn load(pool: &PgPool) -> SchemaCache { + let (schemas, tables, functions, types) = join!( + Schema::load(pool), + Table::load(pool), + Function::load(pool), + PostgresType::load(pool) + ) + .await; + + SchemaCache { + schemas, + tables, + functions, + types, + } + } + + /// Applies an AST node to the repository + /// + /// For example, alter table add column will add the column to the table if it does not exist + /// yet + pub fn mutate(&mut self) { + unimplemented!(); + } + + pub fn find_table(&self, name: &str, schema: Option<&str>) -> Option<&Table> { + self.tables + .iter() + .find(|t| t.name == name && schema.is_none() || Some(t.schema.as_str()) == schema) + } + + pub fn find_type(&self, name: &str, schema: Option<&str>) -> Option<&PostgresType> { + self.types + .iter() + .find(|t| t.name == name && schema.is_none() || Some(t.schema.as_str()) == schema) + } + + pub fn find_types(&self, name: &str, schema: Option<&str>) -> Vec<&PostgresType> { + self.types + .iter() + .filter(|t| t.name == name && schema.is_none() || Some(t.schema.as_str()) == schema) + .collect() + } +} + +pub trait SchemaCacheItem { + type Item; + + async fn load(pool: &PgPool) -> Vec; +} + +#[cfg(test)] +mod tests { + use sqlx::PgPool; + + use crate::SchemaCache; + + #[test] + fn test_schema_cache() { + let conn_string = std::env::var("DB_CONNECTION_STRING").unwrap(); + + let pool = async_std::task::block_on(PgPool::connect(conn_string.as_str())).unwrap(); + + async_std::task::block_on(SchemaCache::load(&pool)); + + assert!(true); + } +} diff --git a/crates/schema_cache/src/schemas.rs b/crates/pg_schema_cache/src/schemas.rs similarity index 100% rename from crates/schema_cache/src/schemas.rs rename to crates/pg_schema_cache/src/schemas.rs diff --git a/crates/schema_cache/src/tables.rs b/crates/pg_schema_cache/src/tables.rs similarity index 84% rename from crates/schema_cache/src/tables.rs rename to crates/pg_schema_cache/src/tables.rs index b0a3786f..8ca9ce3c 100644 --- a/crates/schema_cache/src/tables.rs +++ b/crates/pg_schema_cache/src/tables.rs @@ -2,7 +2,7 @@ use sqlx::PgPool; use crate::schema_cache::SchemaCacheItem; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ReplicaIdentity { Default, Index, @@ -28,19 +28,19 @@ impl From for ReplicaIdentity { } } -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct Table { - id: i64, - schema: String, - name: String, - rls_enabled: bool, - rls_forced: bool, - replica_identity: ReplicaIdentity, - bytes: i64, - size: String, - live_rows_estimate: i64, - dead_rows_estimate: i64, - comment: Option, + pub id: i64, + pub schema: String, + pub name: String, + pub rls_enabled: bool, + pub rls_forced: bool, + pub replica_identity: ReplicaIdentity, + pub bytes: i64, + pub size: String, + pub live_rows_estimate: i64, + pub dead_rows_estimate: i64, + pub comment: Option, } impl SchemaCacheItem for Table { diff --git a/crates/pg_schema_cache/src/types.rs b/crates/pg_schema_cache/src/types.rs new file mode 100644 index 00000000..fd113604 --- /dev/null +++ b/crates/pg_schema_cache/src/types.rs @@ -0,0 +1,108 @@ +use serde::Deserialize; +use sqlx::types::JsonValue; +use sqlx::PgPool; + +use crate::schema_cache::SchemaCacheItem; + +#[derive(Debug, Clone, Default)] +pub struct TypeAttributes { + attrs: Vec, +} + +#[derive(Debug, Clone, Default, Deserialize)] +pub struct PostgresTypeAttribute { + name: String, + type_id: i64, +} + +impl From> for TypeAttributes { + fn from(s: Option) -> Self { + let values: Vec = + serde_json::from_value(s.unwrap_or(JsonValue::Array(vec![]))).unwrap(); + TypeAttributes { attrs: values } + } +} + +#[derive(Debug, Clone, Default)] +pub struct Enums { + pub values: Vec, +} + +impl From> for Enums { + fn from(s: Option) -> Self { + let values: Vec = + serde_json::from_value(s.unwrap_or(JsonValue::Array(vec![]))).unwrap(); + Enums { values } + } +} + +#[derive(Debug, Clone, Default)] +pub struct PostgresType { + pub id: i64, + pub name: String, + pub schema: String, + pub format: String, + pub enums: Enums, + pub attributes: TypeAttributes, + pub comment: Option, +} + +impl SchemaCacheItem for PostgresType { + type Item = PostgresType; + + async fn load(pool: &PgPool) -> Vec { + sqlx::query_as!( + PostgresType, + r#"select + t.oid::int8 as "id!", + t.typname as name, + n.nspname as "schema!", + format_type (t.oid, null) as "format!", + coalesce(t_enums.enums, '[]') as enums, + coalesce(t_attributes.attributes, '[]') as attributes, + obj_description (t.oid, 'pg_type') as comment +from + pg_type t + left join pg_namespace n on n.oid = t.typnamespace + left join ( + select + enumtypid, + jsonb_agg(enumlabel order by enumsortorder) as enums + from + pg_enum + group by + enumtypid + ) as t_enums on t_enums.enumtypid = t.oid + left join ( + select + oid, + jsonb_agg( + jsonb_build_object('name', a.attname, 'type_id', a.atttypid::int8) + order by a.attnum asc + ) as attributes + from + pg_class c + join pg_attribute a on a.attrelid = c.oid + where + c.relkind = 'c' and not a.attisdropped + group by + c.oid + ) as t_attributes on t_attributes.oid = t.typrelid +where + ( + t.typrelid = 0 + or ( + select + c.relkind = 'c' + from + pg_class c + where + c.oid = t.typrelid + ) + )"# + ) + .fetch_all(pool) + .await + .unwrap() + } +} diff --git a/crates/pg_statement_splitter/Cargo.toml b/crates/pg_statement_splitter/Cargo.toml new file mode 100644 index 00000000..15a30680 --- /dev/null +++ b/crates/pg_statement_splitter/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "pg_statement_splitter" +version = "0.0.0" +edition = "2021" + +[dependencies] +pg_lexer.workspace = true +text-size = "1.1.1" + +[dev-dependencies] +pg_query = "0.8" + diff --git a/crates/parser/src/parse/statement_start.rs b/crates/pg_statement_splitter/src/is_at_stmt_start.rs similarity index 98% rename from crates/parser/src/parse/statement_start.rs rename to crates/pg_statement_splitter/src/is_at_stmt_start.rs index 05c2076c..ec1b83ea 100644 --- a/crates/parser/src/parse/statement_start.rs +++ b/crates/pg_statement_splitter/src/is_at_stmt_start.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use std::sync::LazyLock; -use crate::codegen::SyntaxKind; -use crate::Parser; +use super::Parser; +use pg_lexer::SyntaxKind; pub enum SyntaxToken { Required(SyntaxKind), @@ -245,10 +245,12 @@ pub static STATEMENT_START_TOKEN_MAPS: LazyLock Parse { + let mut parser = Parser::new(lex(sql)); + + while !parser.eof() { + match is_at_stmt_start(&mut parser) { + Some(stmt) => { + parser.start_stmt(); + + // advance over all start tokens of the statement + for i in 0..STATEMENT_START_TOKEN_MAPS.len() { + parser.eat_whitespace(); + let token = parser.nth(0, false); + if let Some(result) = STATEMENT_START_TOKEN_MAPS[i].get(&token.kind) { + let is_in_results = result + .iter() + .find(|x| match x { + TokenStatement::EoS(y) | TokenStatement::Any(y) => y == &stmt, + }) + .is_some(); + if i == 0 && !is_in_results { + panic!("Expected statement start"); + } else if is_in_results { + parser.expect(token.kind); + } else { + break; + } + } + } + + // move until the end of the statement, or until the next statement start + let mut is_sub_stmt = 0; + let mut is_sub_trx = 0; + let mut ignore_next_non_whitespace = false; + while !parser.at(SyntaxKind::Ascii59) && !parser.eof() { + match parser.nth(0, false).kind { + SyntaxKind::All => { + // ALL is never a statement start, but needs to be skipped when combining queries + // (e.g. UNION ALL) + parser.advance(); + } + SyntaxKind::BeginP => { + // BEGIN, consume until END + is_sub_trx += 1; + parser.advance(); + } + SyntaxKind::EndP => { + is_sub_trx -= 1; + parser.advance(); + } + // opening brackets "(", consume until closing bracket ")" + SyntaxKind::Ascii40 => { + is_sub_stmt += 1; + parser.advance(); + } + SyntaxKind::Ascii41 => { + is_sub_stmt -= 1; + parser.advance(); + } + SyntaxKind::As + | SyntaxKind::Union + | SyntaxKind::Intersect + | SyntaxKind::Except => { + // ignore the next non-whitespace token + ignore_next_non_whitespace = true; + parser.advance(); + } + _ => { + // if another stmt FIRST is encountered, break + // ignore if parsing sub stmt + if ignore_next_non_whitespace == false + && is_sub_stmt == 0 + && is_sub_trx == 0 + && is_at_stmt_start(&mut parser).is_some() + { + break; + } else { + if ignore_next_non_whitespace == true && !parser.at_whitespace() { + ignore_next_non_whitespace = false; + } + parser.advance(); + } + } + } + } + + parser.expect(SyntaxKind::Ascii59); + + parser.close_stmt(); + } + None => { + parser.advance(); + } + } + } + + parser.finish() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_splitter() { + let input = "select 1 from contact;\nselect 1;\nalter table test drop column id;"; + + let res = split(input); + assert_eq!(res.ranges.len(), 3); + assert_eq!("select 1 from contact;", input[res.ranges[0]].to_string()); + assert_eq!("select 1;", input[res.ranges[1]].to_string()); + assert_eq!( + "alter table test drop column id;", + input[res.ranges[2]].to_string() + ); + } +} diff --git a/crates/pg_statement_splitter/src/parser.rs b/crates/pg_statement_splitter/src/parser.rs new file mode 100644 index 00000000..1b3d0f8b --- /dev/null +++ b/crates/pg_statement_splitter/src/parser.rs @@ -0,0 +1,196 @@ +use std::cmp::min; + +use pg_lexer::{SyntaxKind, Token, TokenType, WHITESPACE_TOKENS}; +use text_size::{TextRange, TextSize}; + +use crate::syntax_error::SyntaxError; + +/// Main parser that exposes the `cstree` api, and collects errors and statements +pub struct Parser { + /// The ranges of the statements + ranges: Vec<(usize, usize)>, + /// The syntax errors accumulated during parsing + errors: Vec, + /// The start of the current statement, if any + current_stmt_start: Option, + /// The tokens to parse + pub tokens: Vec, + /// The current position in the token stream + pub pos: usize, + /// index from which whitespace tokens are buffered + pub whitespace_token_buffer: Option, + + eof_token: Token, +} + +/// Result of Building +#[derive(Debug)] +pub struct Parse { + /// The ranges of the errors + pub ranges: Vec, + /// The syntax errors accumulated during parsing + pub errors: Vec, +} + +impl Parser { + pub fn new(tokens: Vec) -> Self { + Self { + eof_token: Token::eof(usize::from(tokens.last().unwrap().span.end())), + ranges: Vec::new(), + errors: Vec::new(), + current_stmt_start: None, + tokens, + pos: 0, + whitespace_token_buffer: None, + } + } + + pub fn finish(self) -> Parse { + Parse { + ranges: self + .ranges + .iter() + .map(|(start, end)| { + let from = self.tokens.get(*start); + let to = self.tokens.get(end - 1); + // get text range from token range + let text_start = from.unwrap().span.start(); + let text_end = to.unwrap().span.end(); + + TextRange::new( + TextSize::try_from(text_start).unwrap(), + TextSize::try_from(text_end).unwrap(), + ) + }) + .collect(), + errors: self.errors, + } + } + + pub fn start_stmt(&mut self) { + assert!(self.current_stmt_start.is_none()); + self.current_stmt_start = Some(self.pos); + } + + pub fn close_stmt(&mut self) { + assert!(self.current_stmt_start.is_some()); + self.ranges + .push((self.current_stmt_start.take().unwrap(), self.pos)); + } + + /// collects an SyntaxError with an `error` message at `pos` + pub fn error_at_pos(&mut self, error: String, pos: usize) { + self.errors.push(SyntaxError::new_at_offset( + error, + self.tokens + .get(min(self.tokens.len() - 1, pos)) + .unwrap() + .span + .start(), + )); + } + + /// applies token and advances + pub fn advance(&mut self) { + assert!(!self.eof()); + if self.nth(0, false).kind == SyntaxKind::Whitespace { + if self.whitespace_token_buffer.is_none() { + self.whitespace_token_buffer = Some(self.pos); + } + } else { + self.flush_token_buffer(); + } + self.pos += 1; + } + + /// flush token buffer and applies all tokens + pub fn flush_token_buffer(&mut self) { + if self.whitespace_token_buffer.is_none() { + return; + } + while self.whitespace_token_buffer.unwrap() < self.pos { + self.whitespace_token_buffer = Some(self.whitespace_token_buffer.unwrap() + 1); + } + self.whitespace_token_buffer = None; + } + + pub fn eat(&mut self, kind: SyntaxKind) -> bool { + if self.at(kind) { + self.advance(); + true + } else { + false + } + } + + pub fn at_whitespace(&self) -> bool { + self.nth(0, false).kind == SyntaxKind::Whitespace + } + + pub fn eat_whitespace(&mut self) { + while self.nth(0, false).token_type == TokenType::Whitespace { + self.advance(); + } + } + + pub fn eof(&self) -> bool { + self.pos == self.tokens.len() + } + + /// lookahead method. + /// + /// if `ignore_whitespace` is true, it will skip all whitespace tokens + pub fn nth(&self, lookahead: usize, ignore_whitespace: bool) -> &Token { + if ignore_whitespace { + let mut idx = 0; + let mut non_whitespace_token_ctr = 0; + loop { + match self.tokens.get(self.pos + idx) { + Some(token) => { + if !WHITESPACE_TOKENS.contains(&token.kind) { + if non_whitespace_token_ctr == lookahead { + return token; + } + non_whitespace_token_ctr += 1; + } + idx += 1; + } + None => { + return &self.eof_token; + } + } + } + } else { + match self.tokens.get(self.pos + lookahead) { + Some(token) => token, + None => &self.eof_token, + } + } + } + + /// checks if the current token is of `kind` + pub fn at(&self, kind: SyntaxKind) -> bool { + self.nth(0, false).kind == kind + } + + pub fn expect(&mut self, kind: SyntaxKind) { + if self.eat(kind) { + return; + } + if self.whitespace_token_buffer.is_some() { + self.error_at_pos( + format!( + "Expected {:#?}, found {:#?}", + kind, + self.tokens[self.whitespace_token_buffer.unwrap()].kind + ), + self.whitespace_token_buffer.unwrap(), + ); + } else { + self.error_at_pos( + format!("Expected {:#?}, found {:#?}", kind, self.nth(0, false)), + self.pos + 1, + ); + } + } +} diff --git a/crates/parser/src/syntax_error.rs b/crates/pg_statement_splitter/src/syntax_error.rs similarity index 94% rename from crates/parser/src/syntax_error.rs rename to crates/pg_statement_splitter/src/syntax_error.rs index df6d670f..1e5c3650 100644 --- a/crates/parser/src/syntax_error.rs +++ b/crates/pg_statement_splitter/src/syntax_error.rs @@ -1,6 +1,6 @@ use std::fmt; -use cstree::text::{TextRange, TextSize}; +use text_size::{TextRange, TextSize}; /// Represents the result of unsuccessful tokenization, parsing, /// or tree validation. diff --git a/crates/pg_statement_splitter/tests/data/simple_select__4.sql b/crates/pg_statement_splitter/tests/data/simple_select__4.sql new file mode 100644 index 00000000..bfd9e429 --- /dev/null +++ b/crates/pg_statement_splitter/tests/data/simple_select__4.sql @@ -0,0 +1,8 @@ +select id, name, test1231234123, unknown from co; + +select 14433313331333 + +alter table test drop column id; + +select lower('test'); + diff --git a/crates/pg_statement_splitter/tests/skipped.txt b/crates/pg_statement_splitter/tests/skipped.txt new file mode 100644 index 00000000..480089b9 --- /dev/null +++ b/crates/pg_statement_splitter/tests/skipped.txt @@ -0,0 +1,12 @@ +brin +brin_bloom +brin_multi +collate.icu.utf8 +collate.linux.utf8 +collate +copy2 +create_table_like +drop_operator +replica_identity +unicode +xmlmap diff --git a/crates/pg_statement_splitter/tests/statement_splitter_tests.rs b/crates/pg_statement_splitter/tests/statement_splitter_tests.rs new file mode 100644 index 00000000..fb639fef --- /dev/null +++ b/crates/pg_statement_splitter/tests/statement_splitter_tests.rs @@ -0,0 +1,114 @@ +use std::fs::{self}; + +const DATA_DIR_PATH: &str = "tests/data/"; +const POSTGRES_REGRESS_PATH: &str = "../../libpg_query/test/sql/postgres_regress/"; +const SKIPPED_REGRESS_TESTS: &str = include_str!("skipped.txt"); + +#[test] +fn test_postgres_regress() { + // all postgres regress tests are valid and complete statements, so we can use `split_with_parser` and compare with our own splitter + + let mut paths: Vec<_> = fs::read_dir(POSTGRES_REGRESS_PATH) + .unwrap() + .map(|r| r.unwrap()) + .collect(); + paths.sort_by_key(|dir| dir.path()); + + for f in paths.iter() { + let path = f.path(); + + let test_name = path.file_stem().unwrap().to_str().unwrap(); + + // these require fixes in the parser + if SKIPPED_REGRESS_TESTS + .lines() + .collect::>() + .contains(&test_name) + { + continue; + } + + // remove \commands because pg_query doesn't support them + let contents = fs::read_to_string(&path) + .unwrap() + .lines() + .filter(|l| !l.starts_with("\\") && !l.ends_with("\\gset")) + .collect::>() + .join(" "); + + let libpg_query_split = pg_query::split_with_parser(&contents).unwrap(); + + let parser_split = pg_statement_splitter::split(&contents); + + assert_eq!( + parser_split.errors.len(), + 0, + "Unexpected errors when parsing file {}:\n{:#?}", + test_name, + parser_split.errors + ); + + assert_eq!( + libpg_query_split.len(), + parser_split.ranges.len(), + "Mismatch in statement count for file {}: Expected {} statements, got {}", + test_name, + libpg_query_split.len(), + parser_split.ranges.len() + ); + + for (libpg_query_stmt, parser_range) in + libpg_query_split.iter().zip(parser_split.ranges.iter()) + { + let parser_stmt = &contents[parser_range.clone()].trim(); + + let libpg_query_stmt = if libpg_query_stmt.ends_with(';') { + libpg_query_stmt.to_string() + } else { + format!("{};", libpg_query_stmt.trim()) + }; + + let libpg_query_stmt_trimmed = libpg_query_stmt.trim(); + let parser_stmt_trimmed = parser_stmt.trim(); + + assert_eq!( + libpg_query_stmt_trimmed, parser_stmt_trimmed, + "Mismatch in statement {}:\nlibg_query: '{}'\nsplitter: '{}'", + test_name, libpg_query_stmt_trimmed, parser_stmt_trimmed + ); + } + } +} + +#[test] +fn test_statement_splitter() { + let mut paths: Vec<_> = fs::read_dir(DATA_DIR_PATH) + .unwrap() + .map(|r| r.unwrap()) + .collect(); + paths.sort_by_key(|dir| dir.path()); + + for f in paths.iter() { + let path = f.path(); + let test_name = path.file_stem().unwrap().to_str().unwrap(); + let expected_count = test_name + .split("__") + .last() + .unwrap() + .parse::() + .unwrap(); + + let contents = fs::read_to_string(&path).unwrap(); + + let split = pg_statement_splitter::split(&contents); + + assert_eq!( + split.ranges.len(), + expected_count, + "Mismatch in statement count for file {}: Expected {} statements, got {}", + test_name, + expected_count, + split.ranges.len() + ); + } +} diff --git a/crates/pg_syntax/Cargo.toml b/crates/pg_syntax/Cargo.toml new file mode 100644 index 00000000..38907eaa --- /dev/null +++ b/crates/pg_syntax/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pg_syntax" +version = "0.0.0" +edition = "2021" + +[dependencies] +petgraph = "0.6.4" + +cstree = { version = "0.12.0", features = ["derive"] } +text-size = "1.1.1" + +pg_query_ext.workspace = true +pg_lexer.workspace = true + +[dev-dependencies] +pg_query = "0.8" +insta = "1.31.0" diff --git a/crates/pg_syntax/src/ast.rs b/crates/pg_syntax/src/ast.rs new file mode 100644 index 00000000..0c39a37e --- /dev/null +++ b/crates/pg_syntax/src/ast.rs @@ -0,0 +1,58 @@ +pub mod builder; + +use petgraph::{ + stable_graph::{DefaultIx, NodeIndex, StableGraph}, + visit::IntoNodeReferences, + Direction, +}; +use text_size::{TextRange, TextSize}; + +#[derive(Debug, Clone)] +pub struct RangedNode { + pub node: pg_query_ext::NodeEnum, + pub start: TextSize, + pub end: Option, +} + +impl RangedNode { + pub fn range(&self) -> TextRange { + TextRange::new(self.start, self.end.unwrap()) + } +} + +#[derive(Debug, Clone)] +pub struct AST { + inner: StableGraph, +} + +impl AST { + pub fn new(g: StableGraph) -> Self { + Self { inner: g } + } + + pub fn root_node(&self) -> &RangedNode { + &self.inner[NodeIndex::::new(0)] + } + + pub fn iter_nodes(&self) -> impl Iterator { + self.inner.node_references().map(|(_, node)| node) + } + + pub fn covering_node(&self, range: TextRange) -> Option { + let mut res: NodeIndex = NodeIndex::::new(0); + + // check if any children contains the range. if not return, else continue + while let Some(idx) = self + .inner + .neighbors_directed(res, Direction::Outgoing) + .find(|&idx| { + let node = &self.inner[idx]; + node.range().contains_range(range) + }) + { + res = idx; + } + + Some(self.inner[res].clone()) + } +} diff --git a/crates/pg_syntax/src/ast/builder.rs b/crates/pg_syntax/src/ast/builder.rs new file mode 100644 index 00000000..93fdc544 --- /dev/null +++ b/crates/pg_syntax/src/ast/builder.rs @@ -0,0 +1,50 @@ +use petgraph::stable_graph::{DefaultIx, NodeIndex, StableGraph}; + +use crate::ast::{RangedNode, AST}; + +pub(crate) struct AstBuilder { + inner: StableGraph, + open_nodes: Vec>, + current_pos: usize, + current_idx: NodeIndex, +} + +impl AstBuilder { + pub fn new() -> Self { + Self { + inner: StableGraph::new(), + open_nodes: Vec::new(), + current_pos: 0, + current_idx: NodeIndex::new(0), + } + } + + pub fn start_node(&mut self, node: pg_query_ext::NodeEnum) { + let idx = self.inner.add_node(RangedNode { + node, + start: self.current_pos.try_into().unwrap(), + end: None, + }); + if self.open_nodes.len() > 0 { + let parent = self.open_nodes.last().unwrap(); + self.inner.add_edge(parent.to_owned(), idx, ()); + } + self.open_nodes.push(idx); + self.current_idx = idx; + } + + pub fn finish_node(&mut self) { + let idx = self.open_nodes.pop().unwrap(); + let end = self.current_pos; + self.inner[idx].end = Some(end.try_into().unwrap()); + self.current_idx = idx; + } + + pub fn token(&mut self, text: &str) { + self.current_pos += text.len(); + } + + pub fn finish(self) -> AST { + AST::new(self.inner) + } +} diff --git a/crates/pg_syntax/src/cst.rs b/crates/pg_syntax/src/cst.rs new file mode 100644 index 00000000..7e556f7f --- /dev/null +++ b/crates/pg_syntax/src/cst.rs @@ -0,0 +1,10 @@ +use cstree::syntax::ResolvedNode; +use pg_lexer::SyntaxKind; + +pub type CST = ResolvedNode; + +pub type SyntaxNode = cstree::syntax::SyntaxNode; +#[allow(dead_code)] +pub type SyntaxToken = cstree::syntax::SyntaxToken; +#[allow(dead_code)] +pub type SyntaxElement = cstree::syntax::SyntaxElement; diff --git a/crates/pg_syntax/src/lib.rs b/crates/pg_syntax/src/lib.rs new file mode 100644 index 00000000..c72c7530 --- /dev/null +++ b/crates/pg_syntax/src/lib.rs @@ -0,0 +1,19 @@ +mod ast; +mod cst; +mod parser; +mod statement_parser; +mod syntax_builder; + +pub use ast::AST; +pub use cst::CST; + +use statement_parser::StatementParser; +use syntax_builder::{Syntax, SyntaxBuilder}; + +pub fn parse_syntax(sql: &str, root: &pg_query_ext::NodeEnum) -> Syntax { + let mut builder = SyntaxBuilder::new(); + + StatementParser::new(&root, sql, &mut builder).parse(); + + builder.finish() +} diff --git a/crates/pg_syntax/src/parser.rs b/crates/pg_syntax/src/parser.rs new file mode 100644 index 00000000..b2dfc865 --- /dev/null +++ b/crates/pg_syntax/src/parser.rs @@ -0,0 +1,195 @@ +use pg_lexer::TokenType; +use pg_lexer::{SyntaxKind, Token, WHITESPACE_TOKENS}; +use std::ops::Range; + +pub enum ParserEvent<'a> { + Token(&'a Token), + StartNode(pg_query_ext::NodeEnum), + FinishNode, +} + +pub trait EventSink { + fn push(&mut self, event: ParserEvent); +} + +/// Main parser that exposes the `cstree` api, and collects errors and statements +pub struct Parser<'p> { + event_sink: Option<&'p mut dyn EventSink>, + /// The tokens to parse + pub tokens: Vec, + /// The current position in the token stream + pub pos: usize, + /// index from which whitespace tokens are buffered + pub whitespace_token_buffer: Option, + /// index from which tokens are buffered + token_buffer: Option, + + pub depth: usize, + + eof_token: Token, +} + +#[allow(dead_code)] +impl<'p> Parser<'p> { + pub fn new(tokens: Vec, event_sink: Option<&'p mut dyn EventSink>) -> Self { + Self { + event_sink, + eof_token: Token::eof(usize::from(tokens.last().unwrap().span.end())), + tokens, + pos: 0, + whitespace_token_buffer: None, + token_buffer: None, + depth: 0, + } + } + + pub fn token_range(&self) -> Range { + 0..self.tokens.len() + } + + /// start a new node of `SyntaxKind` + pub fn start_node(&mut self, kind: pg_query_ext::NodeEnum) { + self.flush_token_buffer(); + if let Some(ref mut event_sink) = self.event_sink { + (*event_sink).push(ParserEvent::StartNode(kind)); + } + self.depth += 1; + } + /// finish current node + pub fn finish_node(&mut self) { + if let Some(ref mut event_sink) = self.event_sink { + (*event_sink).push(ParserEvent::FinishNode); + } + self.depth -= 1; + } + + /// Opens a buffer for tokens. While the buffer is active, tokens are not applied to the tree. + pub fn open_buffer(&mut self) { + self.token_buffer = Some(self.pos); + } + + /// Closes the current token buffer, resets the position to the start of the buffer and returns the range of buffered tokens. + pub fn close_buffer(&mut self) -> Range { + let token_buffer = self.token_buffer.unwrap(); + let token_range = token_buffer..self.whitespace_token_buffer.unwrap_or(self.pos); + self.token_buffer = None; + self.pos = token_buffer; + token_range + } + + /// applies token and advances + pub fn advance(&mut self) { + assert!(!self.eof()); + if self.nth(0, false).kind == SyntaxKind::Whitespace { + if self.whitespace_token_buffer.is_none() { + self.whitespace_token_buffer = Some(self.pos); + } + } else { + self.flush_token_buffer(); + if self.token_buffer.is_none() { + let token = self.tokens.get(self.pos).unwrap(); + if let Some(ref mut event_sink) = self.event_sink { + (*event_sink).push(ParserEvent::Token(token)); + } + } + } + self.pos += 1; + } + + /// flush token buffer and applies all tokens + pub fn flush_token_buffer(&mut self) { + if self.whitespace_token_buffer.is_none() { + return; + } + while self.whitespace_token_buffer.unwrap() < self.pos { + let token = self + .tokens + .get(self.whitespace_token_buffer.unwrap()) + .unwrap(); + if self.token_buffer.is_none() { + if let Some(ref mut event_sink) = self.event_sink { + (*event_sink).push(ParserEvent::Token(token)); + } + } + self.whitespace_token_buffer = Some(self.whitespace_token_buffer.unwrap() + 1); + } + self.whitespace_token_buffer = None; + } + + pub fn eat(&mut self, kind: SyntaxKind) -> bool { + if self.at(kind) { + self.advance(); + true + } else { + false + } + } + + pub fn at_whitespace(&self) -> bool { + self.nth(0, false).kind == SyntaxKind::Whitespace + } + + pub fn eat_whitespace(&mut self) { + while self.nth(0, false).token_type == TokenType::Whitespace { + self.advance(); + } + } + + pub fn eof(&self) -> bool { + self.pos == self.tokens.len() + } + + /// lookahead method. + /// + /// if `ignore_whitespace` is true, it will skip all whitespace tokens + pub fn nth(&self, lookahead: usize, ignore_whitespace: bool) -> &Token { + if ignore_whitespace { + let mut idx = 0; + let mut non_whitespace_token_ctr = 0; + loop { + match self.tokens.get(self.pos + idx) { + Some(token) => { + if !WHITESPACE_TOKENS.contains(&token.kind) { + if non_whitespace_token_ctr == lookahead { + return token; + } + non_whitespace_token_ctr += 1; + } + idx += 1; + } + None => { + return &self.eof_token; + } + } + } + } else { + match self.tokens.get(self.pos + lookahead) { + Some(token) => token, + None => &self.eof_token, + } + } + } + + /// checks if the current token is any of `kinds` + pub fn at_any(&self, kinds: &[SyntaxKind]) -> bool { + kinds.iter().any(|&it| self.at(it)) + } + + /// checks if the current token is of `kind` + pub fn at(&self, kind: SyntaxKind) -> bool { + self.nth(0, false).kind == kind + } + + /// like at, but for multiple consecutive tokens + pub fn at_all(&self, kinds: &[SyntaxKind]) -> bool { + kinds + .iter() + .enumerate() + .all(|(idx, &it)| self.nth(idx, false).kind == it) + } + + /// like at_any, but for multiple consecutive tokens + pub fn at_any_all(&self, kinds: &Vec<&[SyntaxKind]>) -> bool { + kinds.iter().any(|&it| self.at_all(it)) + } +} diff --git a/crates/parser/src/parse/libpg_query_node.rs b/crates/pg_syntax/src/statement_parser.rs similarity index 88% rename from crates/parser/src/parse/libpg_query_node.rs rename to crates/pg_syntax/src/statement_parser.rs index 3c013ea6..ebb92384 100644 --- a/crates/parser/src/parse/libpg_query_node.rs +++ b/crates/pg_syntax/src/statement_parser.rs @@ -1,25 +1,17 @@ -use std::{assert_eq, ops::Range}; - -use crate::{ - codegen::{get_nodes, Node, SyntaxKind}, - lexer::TokenType, -}; -use log::{debug, log_enabled}; use petgraph::{ stable_graph::{DefaultIx, NodeIndex, StableGraph}, visit::{Bfs, Dfs}, Direction, }; -use pg_query::NodeEnum; +use pg_lexer::{lex, SyntaxKind, Token, TokenType}; +use pg_query_ext::{get_nodes, Node, NodeEnum, TokenProperty}; -use crate::Parser; +use crate::parser::Parser; -pub fn libpg_query_node(parser: &mut Parser, node: NodeEnum, token_range: &Range) { - LibpgQueryNodeParser::new(parser, node, token_range).parse(); -} +use super::syntax_builder::SyntaxBuilder; // TODO: implement sibling token handling -pub static SKIPPABLE_TOKENS: &[SyntaxKind] = &[ +static SKIPPABLE_TOKENS: &[SyntaxKind] = &[ // "[" SyntaxKind::Ascii91, // "]" @@ -36,47 +28,32 @@ pub static SKIPPABLE_TOKENS: &[SyntaxKind] = &[ SyntaxKind::Ascii59, ]; -struct LibpgQueryNodeParser<'p> { - parser: &'p mut Parser, - token_range: &'p Range, +pub(super) struct StatementParser<'p> { + parser: Parser<'p>, node_graph: StableGraph, current_node: NodeIndex, open_nodes: Vec>, } -impl<'p> LibpgQueryNodeParser<'p> { +impl<'p> StatementParser<'p> { pub fn new( - parser: &'p mut Parser, - node: NodeEnum, - token_range: &'p Range, - ) -> LibpgQueryNodeParser<'p> { - let current_depth = parser.depth.clone(); - debug!("Parsing node {:#?}", node); + root: &NodeEnum, + sql: &str, + event_sink: &'p mut SyntaxBuilder, + ) -> StatementParser<'p> { Self { - parser, - token_range, - node_graph: get_nodes(&node, current_depth), + node_graph: get_nodes(&root), current_node: NodeIndex::::new(0), open_nodes: Vec::new(), + parser: Parser::new(lex(sql), Some(event_sink)), } } pub fn parse(&mut self) { - if log_enabled!(log::Level::Debug) { - dbg!(&self.node_graph); - } - while self.parser.pos < self.token_range.end { - debug!("current node: {:#?}", self.current_node); - debug!("current token: {:#?}", self.current_token()); - debug!("current location: {:#?}", self.current_location()); - if log_enabled!(log::Level::Debug) { - debug!("node graph: {:#?}", self.node_graph); - } + while self.parser.pos < self.parser.token_range().end { if self.at_whitespace() { - debug!("skipping whitespace"); self.parser.advance(); } else if let Some(idx) = self.node_properties_position(self.current_node) { - debug!("found property at current node {:?}", self.current_node); // token is in current node. remove and advance. // open if not opened yet. if !self.node_is_open(&self.current_node) { @@ -86,7 +63,6 @@ impl<'p> LibpgQueryNodeParser<'p> { self.parser.advance(); self.finish_open_leaf_nodes(); } else if let Some((node_idx, prop_idx)) = self.search_children() { - debug!("found node in children {:?}", node_idx); if prop_idx.is_some() { self.remove_property(node_idx, prop_idx.unwrap()); } @@ -117,10 +93,8 @@ impl<'p> LibpgQueryNodeParser<'p> { self.finish_open_leaf_nodes(); } else if self.at_skippable() { - debug!("skipping token {:?}", self.current_token()); self.parser.advance(); } else if let Some((node_idx, prop_idx)) = self.search_parent_properties() { - debug!("found property within parent node {:?}", node_idx); self.remove_property(node_idx, prop_idx); self.finish_nodes_until_depth(self.node_graph[node_idx].depth + 1); @@ -232,7 +206,6 @@ impl<'p> LibpgQueryNodeParser<'p> { } else if self.node_graph[nx].location.is_some() && self.node_graph[nx].location.unwrap() == self.current_location() { - debug!("found node with location at current location"); // check if the location of the node is the current location // do a depth-first search to find the first node that either has a location that // is not the current one, or has the current token as a property @@ -353,7 +326,6 @@ impl<'p> LibpgQueryNodeParser<'p> { self.node_graph[node_to_remove].depth, self.parser.depth ); - debug!("finishing node {:?}", self.node_graph[node_to_remove]); self.node_graph.remove_node(node_to_remove); self.parser.finish_node(); } @@ -378,19 +350,20 @@ impl<'p> LibpgQueryNodeParser<'p> { self.current_location() ); } - debug!("starting node {:?}", self.node_graph[idx]); - self.parser.start_node(self.node_graph[idx].kind); + self.parser.start_node(self.node_graph[idx].inner.clone()); self.open_nodes.push(idx); } fn current_location(&self) -> usize { usize::from( self.current_token().span.start() - - self.parser.tokens[self.token_range.start].span.start(), + - self.parser.tokens[self.parser.token_range().start] + .span + .start(), ) } - fn current_token(&self) -> &crate::lexer::Token { + fn current_token(&self) -> &Token { self.parser.tokens.get(self.parser.pos).unwrap() } @@ -425,11 +398,12 @@ const ALIASES: [&[&str]; 10] = [ &["serial", "serial4"], ]; -fn cmp_tokens(p: &crate::codegen::TokenProperty, token: &crate::lexer::Token) -> bool { +fn cmp_tokens(p: &TokenProperty, token: &Token) -> bool { // TokenProperty has always either value or kind set assert!(p.value.is_some() || p.kind.is_some()); // TODO: move this to lexer + // we should also move alias handling to the lexer // remove enclosing ' quotes from token text let string_delimiter: &[char; 3] = &['\'', '$', '\"']; diff --git a/crates/pg_syntax/src/syntax_builder.rs b/crates/pg_syntax/src/syntax_builder.rs new file mode 100644 index 00000000..8d309196 --- /dev/null +++ b/crates/pg_syntax/src/syntax_builder.rs @@ -0,0 +1,59 @@ +use cstree::build::GreenNodeBuilder; + +use crate::cst::SyntaxNode; +use crate::parser::{EventSink, ParserEvent}; + +use pg_lexer::SyntaxKind; + +use super::ast::{builder::AstBuilder, AST}; +use super::cst::CST; + +#[derive(Debug)] +pub struct Syntax { + /// The abstract syntax tree with resolved ranges for each node + pub ast: AST, + /// The concrete syntax tree + pub cst: CST, +} + +pub(super) struct SyntaxBuilder { + ast_builder: AstBuilder, + cst_builder: GreenNodeBuilder<'static, 'static, SyntaxKind>, +} + +impl SyntaxBuilder { + pub fn new() -> Self { + Self { + ast_builder: AstBuilder::new(), + cst_builder: GreenNodeBuilder::new(), + } + } + + pub fn finish(self) -> Syntax { + let (tree, cache) = self.cst_builder.finish(); + let ast = self.ast_builder.finish(); + Syntax { + cst: SyntaxNode::new_root_with_resolver(tree, cache.unwrap().into_interner().unwrap()), + ast, + } + } +} + +impl EventSink for SyntaxBuilder { + fn push(&mut self, event: ParserEvent) { + match event { + ParserEvent::StartNode(node) => { + self.cst_builder.start_node(SyntaxKind::from(&node)); + self.ast_builder.start_node(node); + } + ParserEvent::FinishNode => { + self.cst_builder.finish_node(); + self.ast_builder.finish_node(); + } + ParserEvent::Token(token) => { + self.cst_builder.token(token.kind, token.text.as_str()); + self.ast_builder.token(token.text.as_str()); + } + } + } +} diff --git a/crates/parser/tests/data/statements/valid/0001.sql b/crates/pg_syntax/tests/data/0001.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0001.sql rename to crates/pg_syntax/tests/data/0001.sql diff --git a/crates/parser/tests/data/statements/valid/0002.sql b/crates/pg_syntax/tests/data/0002.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0002.sql rename to crates/pg_syntax/tests/data/0002.sql diff --git a/crates/parser/tests/data/statements/valid/0003.sql b/crates/pg_syntax/tests/data/0003.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0003.sql rename to crates/pg_syntax/tests/data/0003.sql diff --git a/crates/parser/tests/data/statements/valid/0004.sql b/crates/pg_syntax/tests/data/0004.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0004.sql rename to crates/pg_syntax/tests/data/0004.sql diff --git a/crates/parser/tests/data/statements/valid/0005.sql b/crates/pg_syntax/tests/data/0005.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0005.sql rename to crates/pg_syntax/tests/data/0005.sql diff --git a/crates/parser/tests/data/statements/valid/0006.sql b/crates/pg_syntax/tests/data/0006.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0006.sql rename to crates/pg_syntax/tests/data/0006.sql diff --git a/crates/parser/tests/data/statements/valid/0007.sql b/crates/pg_syntax/tests/data/0007.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0007.sql rename to crates/pg_syntax/tests/data/0007.sql diff --git a/crates/parser/tests/data/statements/valid/0008.sql b/crates/pg_syntax/tests/data/0008.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0008.sql rename to crates/pg_syntax/tests/data/0008.sql diff --git a/crates/parser/tests/data/statements/valid/0009.sql b/crates/pg_syntax/tests/data/0009.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0009.sql rename to crates/pg_syntax/tests/data/0009.sql diff --git a/crates/parser/tests/data/statements/valid/0010.sql b/crates/pg_syntax/tests/data/0010.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0010.sql rename to crates/pg_syntax/tests/data/0010.sql diff --git a/crates/parser/tests/data/statements/valid/0011.sql b/crates/pg_syntax/tests/data/0011.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0011.sql rename to crates/pg_syntax/tests/data/0011.sql diff --git a/crates/parser/tests/data/statements/valid/0012.sql b/crates/pg_syntax/tests/data/0012.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0012.sql rename to crates/pg_syntax/tests/data/0012.sql diff --git a/crates/parser/tests/data/statements/valid/0013.sql b/crates/pg_syntax/tests/data/0013.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0013.sql rename to crates/pg_syntax/tests/data/0013.sql diff --git a/crates/parser/tests/data/statements/valid/0014.sql b/crates/pg_syntax/tests/data/0014.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0014.sql rename to crates/pg_syntax/tests/data/0014.sql diff --git a/crates/parser/tests/data/statements/valid/0015.sql b/crates/pg_syntax/tests/data/0015.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0015.sql rename to crates/pg_syntax/tests/data/0015.sql diff --git a/crates/parser/tests/data/statements/valid/0016.sql b/crates/pg_syntax/tests/data/0016.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0016.sql rename to crates/pg_syntax/tests/data/0016.sql diff --git a/crates/parser/tests/data/statements/valid/0017.sql b/crates/pg_syntax/tests/data/0017.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0017.sql rename to crates/pg_syntax/tests/data/0017.sql diff --git a/crates/parser/tests/data/statements/valid/0018.sql b/crates/pg_syntax/tests/data/0018.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0018.sql rename to crates/pg_syntax/tests/data/0018.sql diff --git a/crates/parser/tests/data/statements/valid/0019.sql b/crates/pg_syntax/tests/data/0019.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0019.sql rename to crates/pg_syntax/tests/data/0019.sql diff --git a/crates/parser/tests/data/statements/valid/0020.sql b/crates/pg_syntax/tests/data/0020.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0020.sql rename to crates/pg_syntax/tests/data/0020.sql diff --git a/crates/parser/tests/data/statements/valid/0021.sql b/crates/pg_syntax/tests/data/0021.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0021.sql rename to crates/pg_syntax/tests/data/0021.sql diff --git a/crates/parser/tests/data/statements/valid/0022.sql b/crates/pg_syntax/tests/data/0022.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0022.sql rename to crates/pg_syntax/tests/data/0022.sql diff --git a/crates/parser/tests/data/statements/valid/0023.sql b/crates/pg_syntax/tests/data/0023.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0023.sql rename to crates/pg_syntax/tests/data/0023.sql diff --git a/crates/parser/tests/data/statements/valid/0024.sql b/crates/pg_syntax/tests/data/0024.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0024.sql rename to crates/pg_syntax/tests/data/0024.sql diff --git a/crates/parser/tests/data/statements/valid/0025.sql b/crates/pg_syntax/tests/data/0025.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0025.sql rename to crates/pg_syntax/tests/data/0025.sql diff --git a/crates/parser/tests/data/statements/valid/0026.sql b/crates/pg_syntax/tests/data/0026.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0026.sql rename to crates/pg_syntax/tests/data/0026.sql diff --git a/crates/parser/tests/data/statements/valid/0027.sql b/crates/pg_syntax/tests/data/0027.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0027.sql rename to crates/pg_syntax/tests/data/0027.sql diff --git a/crates/parser/tests/data/statements/valid/0028.sql b/crates/pg_syntax/tests/data/0028.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0028.sql rename to crates/pg_syntax/tests/data/0028.sql diff --git a/crates/parser/tests/data/statements/valid/0029.sql b/crates/pg_syntax/tests/data/0029.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0029.sql rename to crates/pg_syntax/tests/data/0029.sql diff --git a/crates/parser/tests/data/statements/valid/0030.sql b/crates/pg_syntax/tests/data/0030.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0030.sql rename to crates/pg_syntax/tests/data/0030.sql diff --git a/crates/parser/tests/data/statements/valid/0031.sql b/crates/pg_syntax/tests/data/0031.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0031.sql rename to crates/pg_syntax/tests/data/0031.sql diff --git a/crates/parser/tests/data/statements/valid/0032.sql b/crates/pg_syntax/tests/data/0032.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0032.sql rename to crates/pg_syntax/tests/data/0032.sql diff --git a/crates/parser/tests/data/statements/valid/0033.sql b/crates/pg_syntax/tests/data/0033.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0033.sql rename to crates/pg_syntax/tests/data/0033.sql diff --git a/crates/parser/tests/data/statements/valid/0034.sql b/crates/pg_syntax/tests/data/0034.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0034.sql rename to crates/pg_syntax/tests/data/0034.sql diff --git a/crates/parser/tests/data/statements/valid/0035.sql b/crates/pg_syntax/tests/data/0035.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0035.sql rename to crates/pg_syntax/tests/data/0035.sql diff --git a/crates/parser/tests/data/statements/valid/0036.sql b/crates/pg_syntax/tests/data/0036.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0036.sql rename to crates/pg_syntax/tests/data/0036.sql diff --git a/crates/parser/tests/data/statements/valid/0037.sql b/crates/pg_syntax/tests/data/0037.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0037.sql rename to crates/pg_syntax/tests/data/0037.sql diff --git a/crates/parser/tests/data/statements/valid/0038.sql b/crates/pg_syntax/tests/data/0038.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0038.sql rename to crates/pg_syntax/tests/data/0038.sql diff --git a/crates/parser/tests/data/statements/valid/0039.sql b/crates/pg_syntax/tests/data/0039.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0039.sql rename to crates/pg_syntax/tests/data/0039.sql diff --git a/crates/parser/tests/data/statements/valid/0040.sql b/crates/pg_syntax/tests/data/0040.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0040.sql rename to crates/pg_syntax/tests/data/0040.sql diff --git a/crates/parser/tests/data/statements/valid/0041.sql b/crates/pg_syntax/tests/data/0041.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0041.sql rename to crates/pg_syntax/tests/data/0041.sql diff --git a/crates/parser/tests/data/statements/valid/0042.sql b/crates/pg_syntax/tests/data/0042.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0042.sql rename to crates/pg_syntax/tests/data/0042.sql diff --git a/crates/parser/tests/data/statements/valid/0043.sql b/crates/pg_syntax/tests/data/0043.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0043.sql rename to crates/pg_syntax/tests/data/0043.sql diff --git a/crates/parser/tests/data/statements/valid/0044.sql b/crates/pg_syntax/tests/data/0044.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0044.sql rename to crates/pg_syntax/tests/data/0044.sql diff --git a/crates/parser/tests/data/statements/valid/0046.sql b/crates/pg_syntax/tests/data/0046.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0046.sql rename to crates/pg_syntax/tests/data/0046.sql diff --git a/crates/parser/tests/data/statements/valid/0047.sql b/crates/pg_syntax/tests/data/0047.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0047.sql rename to crates/pg_syntax/tests/data/0047.sql diff --git a/crates/parser/tests/data/statements/valid/0048.sql b/crates/pg_syntax/tests/data/0048.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0048.sql rename to crates/pg_syntax/tests/data/0048.sql diff --git a/crates/parser/tests/data/statements/valid/0049.sql b/crates/pg_syntax/tests/data/0049.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0049.sql rename to crates/pg_syntax/tests/data/0049.sql diff --git a/crates/parser/tests/data/statements/valid/0051.sql b/crates/pg_syntax/tests/data/0051.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0051.sql rename to crates/pg_syntax/tests/data/0051.sql diff --git a/crates/parser/tests/data/statements/valid/0052.sql b/crates/pg_syntax/tests/data/0052.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0052.sql rename to crates/pg_syntax/tests/data/0052.sql diff --git a/crates/parser/tests/data/statements/valid/0053.sql b/crates/pg_syntax/tests/data/0053.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0053.sql rename to crates/pg_syntax/tests/data/0053.sql diff --git a/crates/parser/tests/data/statements/valid/0054.sql b/crates/pg_syntax/tests/data/0054.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0054.sql rename to crates/pg_syntax/tests/data/0054.sql diff --git a/crates/parser/tests/data/statements/valid/0055.sql b/crates/pg_syntax/tests/data/0055.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0055.sql rename to crates/pg_syntax/tests/data/0055.sql diff --git a/crates/parser/tests/data/statements/valid/0056.sql b/crates/pg_syntax/tests/data/0056.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0056.sql rename to crates/pg_syntax/tests/data/0056.sql diff --git a/crates/parser/tests/data/statements/valid/0057.sql b/crates/pg_syntax/tests/data/0057.sql similarity index 100% rename from crates/parser/tests/data/statements/valid/0057.sql rename to crates/pg_syntax/tests/data/0057.sql diff --git a/crates/parser/tests/statement_parser_test.rs b/crates/pg_syntax/tests/pg_syntax_tests.rs similarity index 65% rename from crates/parser/tests/statement_parser_test.rs rename to crates/pg_syntax/tests/pg_syntax_tests.rs index f5d8fbcc..badbf9da 100644 --- a/crates/parser/tests/statement_parser_test.rs +++ b/crates/pg_syntax/tests/pg_syntax_tests.rs @@ -1,20 +1,21 @@ -mod common; - use insta::{assert_debug_snapshot, Settings}; -use log::{debug, info}; -use parser::parse_source; use pg_query::split_with_parser; -use std::{fs, panic}; +use std::{ + fs::{self}, + panic, +}; -const VALID_STATEMENTS_PATH: &str = "tests/data/statements/valid/"; +const VALID_STATEMENTS_PATH: &str = "tests/data/"; const POSTGRES_REGRESS_PATH: &str = "../../libpg_query/test/sql/postgres_regress/"; const SKIPPED_REGRESS_TESTS: &str = include_str!("skipped.txt"); +const REGRESSION_SNAPSHOTS_PATH: &str = "snapshots/postgres_regress"; +const SNAPSHOTS_PATH: &str = "snapshots/data"; + #[test] fn valid_statements() { - common::setup(); - - for path in [VALID_STATEMENTS_PATH, POSTGRES_REGRESS_PATH] { + // dont do postgres regress tests for now + for path in [VALID_STATEMENTS_PATH] { let mut paths: Vec<_> = fs::read_dir(path).unwrap().map(|r| r.unwrap()).collect(); paths.sort_by_key(|dir| dir.path()); @@ -31,24 +32,18 @@ fn valid_statements() { } let contents = fs::read_to_string(&path).unwrap(); + let cases = split_with_parser(&contents).unwrap(); for (i, case) in cases.iter().enumerate() { let case = format!("{};", case.trim()); - debug!("Parsing statement {}\n{}", test_name, case); + let root = pg_query_ext::parse(&case).unwrap(); - let result = panic::catch_unwind(|| parse_source(&case)); + let result = panic::catch_unwind(|| pg_syntax::parse_syntax(&case, &root)); if result.is_err() { assert!(false, "Failed to parse statement {}:\n{}", test_name, case); - } else { - info!( - "Successfully parsed statement {}\n'{}'\n{:#?}", - test_name, - case, - result.as_ref().unwrap().cst - ); } let mut settings = Settings::clone_current(); @@ -56,10 +51,17 @@ fn valid_statements() { settings.set_prepend_module_to_snapshot(false); settings.set_description(case.to_string()); settings.set_omit_expression(true); - settings.set_snapshot_path("snapshots/statements/valid"); + let snapshot_path = if path.starts_with(POSTGRES_REGRESS_PATH) { + REGRESSION_SNAPSHOTS_PATH + } else if path.starts_with(VALID_STATEMENTS_PATH) { + SNAPSHOTS_PATH + } else { + panic!("Unknown path: {:?}", path); + }; + settings.set_snapshot_path(snapshot_path); settings.set_snapshot_suffix((i + 1).to_string()); - settings.bind(|| assert_debug_snapshot!(test_name, result.unwrap())); + settings.bind(|| assert_debug_snapshot!(test_name, result.unwrap().cst)); } } } diff --git a/crates/parser/tests/skipped.txt b/crates/pg_syntax/tests/skipped.txt similarity index 97% rename from crates/parser/tests/skipped.txt rename to crates/pg_syntax/tests/skipped.txt index 02a0a3f8..deb56fa5 100644 --- a/crates/parser/tests/skipped.txt +++ b/crates/pg_syntax/tests/skipped.txt @@ -1,3 +1,13 @@ +0006 +0013 +0027 +0028 +0029 +0031 +0043 +0046 +0052 +advisory_lock aggregates alter_generic alter_operator @@ -101,6 +111,7 @@ largeobject limit line lock +lseg macaddr macaddr8 matview diff --git a/crates/pg_syntax/tests/snapshots/data/0001@1.snap b/crates/pg_syntax/tests/snapshots/data/0001@1.snap new file mode 100644 index 00000000..c8a8b631 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0001@1.snap @@ -0,0 +1,58 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT city, count(*) FILTER (WHERE temp_lo < 45), max(temp_lo)\n FROM weather\n GROUP BY city;" +--- +SelectStmt@0..99 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..11 + ColumnRef@7..11 + Ident@7..11 "city" + Ascii44@11..12 "," + Whitespace@12..13 " " + ResTarget@13..48 + FuncCall@13..48 + Ident@13..18 "count" + Ascii40@18..19 "(" + Ascii42@19..20 "*" + Ascii41@20..21 ")" + Whitespace@21..22 " " + Filter@22..28 "FILTER" + Whitespace@28..29 " " + Ascii40@29..30 "(" + Where@30..35 "WHERE" + Whitespace@35..36 " " + AExpr@36..48 + ColumnRef@36..43 + Ident@36..43 "temp_lo" + Whitespace@43..44 " " + Ascii60@44..45 "<" + Whitespace@45..46 " " + AConst@46..48 + Iconst@46..48 "45" + Ascii41@48..49 ")" + Ascii44@49..50 "," + Whitespace@50..51 " " + ResTarget@51..62 + FuncCall@51..62 + Ident@51..54 "max" + Ascii40@54..55 "(" + ColumnRef@55..62 + Ident@55..62 "temp_lo" + Ascii41@62..63 ")" + Newline@63..64 "\n" + Whitespace@64..68 " " + From@68..72 "FROM" + Whitespace@72..73 " " + RangeVar@73..80 + Ident@73..80 "weather" + Newline@80..81 "\n" + Whitespace@81..85 " " + GroupP@85..90 "GROUP" + Whitespace@90..91 " " + By@91..93 "BY" + Whitespace@93..94 " " + ColumnRef@94..98 + Ident@94..98 "city" + Ascii59@98..99 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0002@1.snap b/crates/pg_syntax/tests/snapshots/data/0002@1.snap new file mode 100644 index 00000000..a11ec0a5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0002@1.snap @@ -0,0 +1,15 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "COPY weather FROM '/home/user/weather.txt';" +--- +CopyStmt@0..43 + Copy@0..4 "COPY" + Whitespace@4..5 " " + RangeVar@5..12 + Ident@5..12 "weather" + Whitespace@12..13 " " + From@13..17 "FROM" + Whitespace@17..18 " " + Sconst@18..42 "'/home/user/weather.txt'" + Ascii59@42..43 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0003@1.snap b/crates/pg_syntax/tests/snapshots/data/0003@1.snap new file mode 100644 index 00000000..eff01a03 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0003@1.snap @@ -0,0 +1,69 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE weather (\n city varchar(80) references cities(name),\n temp_lo int,\n temp_hi int,\n prcp real,\n date date\n);" +--- +CreateStmt@0..173 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..20 + Ident@13..20 "weather" + Whitespace@20..21 " " + Ascii40@21..22 "(" + Newline@22..23 "\n" + Whitespace@23..31 " " + ColumnDef@31..75 + Ident@31..35 "city" + Whitespace@35..41 " " + TypeName@41..51 + Varchar@41..48 "varchar" + Ascii40@48..49 "(" + AConst@49..51 + Iconst@49..51 "80" + Ascii41@51..52 ")" + Whitespace@52..53 " " + Constraint@53..75 + References@53..63 "references" + Whitespace@63..64 " " + RangeVar@64..70 + Ident@64..70 "cities" + Ascii40@70..71 "(" + NameP@71..75 "name" + Ascii41@75..76 ")" + Ascii44@76..77 "," + Newline@77..78 "\n" + Whitespace@78..86 " " + ColumnDef@86..99 + Ident@86..93 "temp_lo" + Whitespace@93..96 " " + TypeName@96..99 + IntP@96..99 "int" + Ascii44@99..100 "," + Newline@100..101 "\n" + Whitespace@101..109 " " + ColumnDef@109..122 + Ident@109..116 "temp_hi" + Whitespace@116..119 " " + TypeName@119..122 + IntP@119..122 "int" + Ascii44@122..123 "," + Newline@123..124 "\n" + Whitespace@124..132 " " + ColumnDef@132..146 + Ident@132..136 "prcp" + Whitespace@136..142 " " + TypeName@142..146 + Real@142..146 "real" + Ascii44@146..147 "," + Newline@147..148 "\n" + Whitespace@148..156 " " + ColumnDef@156..170 + Ident@156..160 "date" + Whitespace@160..166 " " + TypeName@166..170 + Ident@166..170 "date" + Newline@170..171 "\n" + Ascii41@171..172 ")" + Ascii59@172..173 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0004@1.snap b/crates/pg_syntax/tests/snapshots/data/0004@1.snap new file mode 100644 index 00000000..6c36e8a5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0004@1.snap @@ -0,0 +1,50 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE VIEW myview AS\n SELECT name, location\n FROM weather, cities\n WHERE city = name;" +--- +ViewStmt@0..103 + Create@0..6 "CREATE" + Whitespace@6..7 " " + View@7..11 "VIEW" + Whitespace@11..12 " " + RangeVar@12..18 + Ident@12..18 "myview" + Whitespace@18..19 " " + As@19..21 "AS" + Newline@21..22 "\n" + Whitespace@22..26 " " + SelectStmt@26..102 + Select@26..32 "SELECT" + Whitespace@32..33 " " + ResTarget@33..37 + ColumnRef@33..37 + NameP@33..37 "name" + Ascii44@37..38 "," + Whitespace@38..39 " " + ResTarget@39..47 + ColumnRef@39..47 + Location@39..47 "location" + Newline@47..48 "\n" + Whitespace@48..56 " " + From@56..60 "FROM" + Whitespace@60..61 " " + RangeVar@61..68 + Ident@61..68 "weather" + Ascii44@68..69 "," + Whitespace@69..70 " " + RangeVar@70..76 + Ident@70..76 "cities" + Newline@76..77 "\n" + Whitespace@77..85 " " + Where@85..90 "WHERE" + Whitespace@90..91 " " + AExpr@91..102 + ColumnRef@91..95 + Ident@91..95 "city" + Whitespace@95..96 " " + Ascii61@96..97 "=" + Whitespace@97..98 " " + ColumnRef@98..102 + NameP@98..102 "name" + Ascii59@102..103 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0005@1.snap b/crates/pg_syntax/tests/snapshots/data/0005@1.snap new file mode 100644 index 00000000..40e1e15d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0005@1.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "DELETE FROM weather WHERE city = 'Hayward';" +--- +DeleteStmt@0..43 + DeleteP@0..6 "DELETE" + Whitespace@6..7 " " + From@7..11 "FROM" + Whitespace@11..12 " " + RangeVar@12..19 + Ident@12..19 "weather" + Whitespace@19..20 " " + Where@20..25 "WHERE" + Whitespace@25..26 " " + AExpr@26..42 + ColumnRef@26..30 + Ident@26..30 "city" + Whitespace@30..31 " " + Ascii61@31..32 "=" + Whitespace@32..33 " " + AConst@33..42 + Sconst@33..42 "'Hayward'" + Ascii59@42..43 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0007@1.snap b/crates/pg_syntax/tests/snapshots/data/0007@1.snap new file mode 100644 index 00000000..d495abdb --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0007@1.snap @@ -0,0 +1,42 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE cities (\n name text,\n population real,\n elevation int -- (in ft)\n);" +--- +CreateStmt@0..94 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..19 + Ident@13..19 "cities" + Whitespace@19..20 " " + Ascii40@20..21 "(" + Newline@21..22 "\n" + Whitespace@22..24 " " + ColumnDef@24..39 + NameP@24..28 "name" + Whitespace@28..35 " " + TypeName@35..39 + TextP@35..39 "text" + Ascii44@39..40 "," + Newline@40..41 "\n" + Whitespace@41..43 " " + ColumnDef@43..58 + Ident@43..53 "population" + Whitespace@53..54 " " + TypeName@54..58 + Real@54..58 "real" + Ascii44@58..59 "," + Newline@59..60 "\n" + Whitespace@60..62 " " + ColumnDef@62..76 + Ident@62..71 "elevation" + Whitespace@71..73 " " + TypeName@73..76 + IntP@73..76 "int" + Whitespace@76..81 " " + SqlComment@81..91 "-- (in ft)" + Newline@91..92 "\n" + Ascii41@92..93 ")" + Ascii59@93..94 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0008@1.snap b/crates/pg_syntax/tests/snapshots/data/0008@1.snap new file mode 100644 index 00000000..43b99529 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0008@1.snap @@ -0,0 +1,52 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "INSERT INTO weather (date, city, temp_hi, temp_lo)\n VALUES ('1994-11-29', 'Hayward', 54, 37);" +--- +InsertStmt@0..96 + Insert@0..6 "INSERT" + Whitespace@6..7 " " + Into@7..11 "INTO" + Whitespace@11..12 " " + RangeVar@12..19 + Ident@12..19 "weather" + Whitespace@19..20 " " + Ascii40@20..21 "(" + ResTarget@21..25 + Ident@21..25 "date" + Ascii44@25..26 "," + Whitespace@26..27 " " + ResTarget@27..31 + Ident@27..31 "city" + Ascii44@31..32 "," + Whitespace@32..33 " " + ResTarget@33..40 + Ident@33..40 "temp_hi" + Ascii44@40..41 "," + Whitespace@41..42 " " + ResTarget@42..49 + Ident@42..49 "temp_lo" + Ascii41@49..50 ")" + Newline@50..51 "\n" + Whitespace@51..55 " " + SelectStmt@55..94 + Values@55..61 "VALUES" + Whitespace@61..62 " " + Ascii40@62..63 "(" + List@63..94 + AConst@63..75 + Sconst@63..75 "'1994-11-29'" + Ascii44@75..76 "," + Whitespace@76..77 " " + AConst@77..86 + Sconst@77..86 "'Hayward'" + Ascii44@86..87 "," + Whitespace@87..88 " " + AConst@88..90 + Iconst@88..90 "54" + Ascii44@90..91 "," + Whitespace@91..92 " " + AConst@92..94 + Iconst@92..94 "37" + Ascii41@94..95 ")" + Ascii59@95..96 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0009@1.snap b/crates/pg_syntax/tests/snapshots/data/0009@1.snap new file mode 100644 index 00000000..06968fbf --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0009@1.snap @@ -0,0 +1,116 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,\n w2.city, w2.temp_lo AS low, w2.temp_hi AS high\n FROM weather w1 JOIN weather w2\n ON w1.temp_lo < w2.temp_lo AND w1.temp_hi > w2.temp_hi;" +--- +SelectStmt@0..208 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..14 + ColumnRef@7..14 + Ident@7..9 "w1" + Ascii46@9..10 "." + Ident@10..14 "city" + Ascii44@14..15 "," + Whitespace@15..16 " " + ResTarget@16..33 + ColumnRef@16..26 + Ident@16..18 "w1" + Ascii46@18..19 "." + Ident@19..26 "temp_lo" + Whitespace@26..27 " " + As@27..29 "AS" + Whitespace@29..30 " " + Ident@30..33 "low" + Ascii44@33..34 "," + Whitespace@34..35 " " + ResTarget@35..53 + ColumnRef@35..45 + Ident@35..37 "w1" + Ascii46@37..38 "." + Ident@38..45 "temp_hi" + Whitespace@45..46 " " + As@46..48 "AS" + Whitespace@48..49 " " + Ident@49..53 "high" + Ascii44@53..54 "," + Newline@54..55 "\n" + Whitespace@55..62 " " + ResTarget@62..69 + ColumnRef@62..69 + Ident@62..64 "w2" + Ascii46@64..65 "." + Ident@65..69 "city" + Ascii44@69..70 "," + Whitespace@70..71 " " + ResTarget@71..88 + ColumnRef@71..81 + Ident@71..73 "w2" + Ascii46@73..74 "." + Ident@74..81 "temp_lo" + Whitespace@81..82 " " + As@82..84 "AS" + Whitespace@84..85 " " + Ident@85..88 "low" + Ascii44@88..89 "," + Whitespace@89..90 " " + ResTarget@90..108 + ColumnRef@90..100 + Ident@90..92 "w2" + Ascii46@92..93 "." + Ident@93..100 "temp_hi" + Whitespace@100..101 " " + As@101..103 "AS" + Whitespace@103..104 " " + Ident@104..108 "high" + Newline@108..109 "\n" + Whitespace@109..113 " " + From@113..117 "FROM" + Whitespace@117..118 " " + JoinExpr@118..207 + RangeVar@118..128 + Ident@118..125 "weather" + Whitespace@125..126 " " + Alias@126..128 + Ident@126..128 "w1" + Whitespace@128..129 " " + Join@129..133 "JOIN" + Whitespace@133..134 " " + RangeVar@134..144 + Ident@134..141 "weather" + Whitespace@141..142 " " + Alias@142..144 + Ident@142..144 "w2" + Newline@144..145 "\n" + Whitespace@145..153 " " + On@153..155 "ON" + Whitespace@155..156 " " + BoolExpr@156..207 + AExpr@156..179 + ColumnRef@156..166 + Ident@156..158 "w1" + Ascii46@158..159 "." + Ident@159..166 "temp_lo" + Whitespace@166..167 " " + Ascii60@167..168 "<" + Whitespace@168..169 " " + ColumnRef@169..179 + Ident@169..171 "w2" + Ascii46@171..172 "." + Ident@172..179 "temp_lo" + Whitespace@179..180 " " + And@180..183 "AND" + Whitespace@183..184 " " + AExpr@184..207 + ColumnRef@184..194 + Ident@184..186 "w1" + Ascii46@186..187 "." + Ident@187..194 "temp_hi" + Whitespace@194..195 " " + Ascii62@195..196 ">" + Whitespace@196..197 " " + ColumnRef@197..207 + Ident@197..199 "w2" + Ascii46@199..200 "." + Ident@200..207 "temp_hi" + Ascii59@207..208 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0010@1.snap b/crates/pg_syntax/tests/snapshots/data/0010@1.snap new file mode 100644 index 00000000..26c85679 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0010@1.snap @@ -0,0 +1,38 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');" +--- +InsertStmt@0..73 + Insert@0..6 "INSERT" + Whitespace@6..7 " " + Into@7..11 "INTO" + Whitespace@11..12 " " + RangeVar@12..19 + Ident@12..19 "weather" + Whitespace@19..20 " " + SelectStmt@20..71 + Values@20..26 "VALUES" + Whitespace@26..27 " " + Ascii40@27..28 "(" + List@28..71 + AConst@28..43 + Sconst@28..43 "'San Francisco'" + Ascii44@43..44 "," + Whitespace@44..45 " " + AConst@45..47 + Iconst@45..47 "46" + Ascii44@47..48 "," + Whitespace@48..49 " " + AConst@49..51 + Iconst@49..51 "50" + Ascii44@51..52 "," + Whitespace@52..53 " " + AConst@53..57 + Fconst@53..57 "0.25" + Ascii44@57..58 "," + Whitespace@58..59 " " + AConst@59..71 + Sconst@59..71 "'1994-11-27'" + Ascii41@71..72 ")" + Ascii59@72..73 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0011@1.snap b/crates/pg_syntax/tests/snapshots/data/0011@1.snap new file mode 100644 index 00000000..94b81300 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0011@1.snap @@ -0,0 +1,29 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT DISTINCT city\n FROM weather\n ORDER BY city;" +--- +SelectStmt@0..56 + Select@0..6 "SELECT" + Whitespace@6..7 " " + Distinct@7..15 "DISTINCT" + Whitespace@15..16 " " + ResTarget@16..20 + ColumnRef@16..20 + Ident@16..20 "city" + Newline@20..21 "\n" + Whitespace@21..25 " " + From@25..29 "FROM" + Whitespace@29..30 " " + RangeVar@30..37 + Ident@30..37 "weather" + Newline@37..38 "\n" + Whitespace@38..42 " " + SortBy@42..55 + Order@42..47 "ORDER" + Whitespace@47..48 " " + By@48..50 "BY" + Whitespace@50..51 " " + ColumnRef@51..55 + Ident@51..55 "city" + Ascii59@55..56 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0012@1.snap b/crates/pg_syntax/tests/snapshots/data/0012@1.snap new file mode 100644 index 00000000..e5f7fb86 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0012@1.snap @@ -0,0 +1,57 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE measurement_y2008m01 PARTITION OF measurement\n FOR VALUES FROM ('2008-01-01') TO ('2008-02-01')\n WITH (parallel_workers = 4)\n TABLESPACE fasttablespace;" +--- +CreateStmt@0..174 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..33 + Ident@13..33 "measurement_y2008m01" + Whitespace@33..34 " " + Partition@34..43 "PARTITION" + Whitespace@43..44 " " + Of@44..46 "OF" + Whitespace@46..47 " " + RangeVar@47..58 + Ident@47..58 "measurement" + Newline@58..59 "\n" + Whitespace@59..63 " " + For@63..66 "FOR" + Whitespace@66..67 " " + Values@67..73 "VALUES" + Whitespace@73..74 " " + PartitionBoundSpec@74..110 + From@74..78 "FROM" + Whitespace@78..79 " " + Ascii40@79..80 "(" + AConst@80..92 + Sconst@80..92 "'2008-01-01'" + Ascii41@92..93 ")" + Whitespace@93..94 " " + To@94..96 "TO" + Whitespace@96..97 " " + Ascii40@97..98 "(" + AConst@98..110 + Sconst@98..110 "'2008-02-01'" + Ascii41@110..111 ")" + Newline@111..112 "\n" + Whitespace@112..116 " " + With@116..120 "WITH" + Whitespace@120..121 " " + Ascii40@121..122 "(" + DefElem@122..142 + Ident@122..138 "parallel_workers" + Whitespace@138..139 " " + Ascii61@139..140 "=" + Whitespace@140..141 " " + Iconst@141..142 "4" + Ascii41@142..143 ")" + Newline@143..144 "\n" + Whitespace@144..148 " " + Tablespace@148..158 "TABLESPACE" + Whitespace@158..159 " " + Ident@159..173 "fasttablespace" + Ascii59@173..174 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0014@1.snap b/crates/pg_syntax/tests/snapshots/data/0014@1.snap new file mode 100644 index 00000000..1abaa39a --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0014@1.snap @@ -0,0 +1,68 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT sum(salary) OVER w, avg(salary) OVER w\n FROM empsalary\n WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);" +--- +SelectStmt@0..121 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..25 + FuncCall@7..25 + Ident@7..10 "sum" + Ascii40@10..11 "(" + ColumnRef@11..17 + Ident@11..17 "salary" + Ascii41@17..18 ")" + Whitespace@18..19 " " + Over@19..23 "OVER" + Whitespace@23..24 " " + WindowDef@24..25 + Ident@24..25 "w" + Ascii44@25..26 "," + Whitespace@26..27 " " + ResTarget@27..45 + FuncCall@27..45 + Ident@27..30 "avg" + Ascii40@30..31 "(" + ColumnRef@31..37 + Ident@31..37 "salary" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Over@39..43 "OVER" + Whitespace@43..44 " " + WindowDef@44..45 + Ident@44..45 "w" + Newline@45..46 "\n" + Whitespace@46..48 " " + From@48..52 "FROM" + Whitespace@52..53 " " + RangeVar@53..62 + Ident@53..62 "empsalary" + Newline@62..63 "\n" + Whitespace@63..65 " " + WindowDef@65..119 + Window@65..71 "WINDOW" + Whitespace@71..72 " " + Ident@72..73 "w" + Whitespace@73..74 " " + As@74..76 "AS" + Whitespace@76..77 " " + Ascii40@77..78 "(" + Partition@78..87 "PARTITION" + Whitespace@87..88 " " + By@88..90 "BY" + Whitespace@90..91 " " + ColumnRef@91..98 + Ident@91..98 "depname" + Whitespace@98..99 " " + SortBy@99..119 + Order@99..104 "ORDER" + Whitespace@104..105 " " + By@105..107 "BY" + Whitespace@107..108 " " + ColumnRef@108..114 + Ident@108..114 "salary" + Whitespace@114..115 " " + Desc@115..119 "DESC" + Ascii41@119..120 ")" + Ascii59@120..121 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0015@1.snap b/crates/pg_syntax/tests/snapshots/data/0015@1.snap new file mode 100644 index 00000000..65e97405 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0015@1.snap @@ -0,0 +1,70 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT\n count(*) AS unfiltered,\n count(*) FILTER (WHERE i < 5) AS filtered\nFROM generate_series(1,10) AS s(i);" +--- +SelectStmt@0..116 + Select@0..6 "SELECT" + Newline@6..7 "\n" + Whitespace@7..11 " " + ResTarget@11..33 + FuncCall@11..18 + Ident@11..16 "count" + Ascii40@16..17 "(" + Ascii42@17..18 "*" + Ascii41@18..19 ")" + Whitespace@19..20 " " + As@20..22 "AS" + Whitespace@22..23 " " + Ident@23..33 "unfiltered" + Ascii44@33..34 "," + Newline@34..35 "\n" + Whitespace@35..39 " " + ResTarget@39..80 + FuncCall@39..67 + Ident@39..44 "count" + Ascii40@44..45 "(" + Ascii42@45..46 "*" + Ascii41@46..47 ")" + Whitespace@47..48 " " + Filter@48..54 "FILTER" + Whitespace@54..55 " " + Ascii40@55..56 "(" + Where@56..61 "WHERE" + Whitespace@61..62 " " + AExpr@62..67 + ColumnRef@62..63 + Ident@62..63 "i" + Whitespace@63..64 " " + Ascii60@64..65 "<" + Whitespace@65..66 " " + AConst@66..67 + Iconst@66..67 "5" + Ascii41@67..68 ")" + Whitespace@68..69 " " + As@69..71 "AS" + Whitespace@71..72 " " + Ident@72..80 "filtered" + Newline@80..81 "\n" + From@81..85 "FROM" + Whitespace@85..86 " " + RangeFunction@86..114 + List@86..106 + FuncCall@86..106 + Ident@86..101 "generate_series" + Ascii40@101..102 "(" + AConst@102..103 + Iconst@102..103 "1" + Ascii44@103..104 "," + AConst@104..106 + Iconst@104..106 "10" + Ascii41@106..107 ")" + Whitespace@107..108 " " + Alias@108..114 + As@108..110 "AS" + Whitespace@110..111 " " + Ident@111..112 "s" + Ascii40@112..113 "(" + Ident@113..114 "i" + Ascii41@114..115 ")" + Ascii59@115..116 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0016@1.snap b/crates/pg_syntax/tests/snapshots/data/0016@1.snap new file mode 100644 index 00000000..d1925e8a --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0016@1.snap @@ -0,0 +1,34 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT * FROM tbl WHERE a COLLATE \"C\" > 'foo';" +--- +SelectStmt@0..46 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..8 + ColumnRef@7..8 + AStar@7..8 + Ascii42@7..8 "*" + Whitespace@8..9 " " + From@9..13 "FROM" + Whitespace@13..14 " " + RangeVar@14..17 + Ident@14..17 "tbl" + Whitespace@17..18 " " + Where@18..23 "WHERE" + Whitespace@23..24 " " + AExpr@24..45 + CollateClause@24..37 + ColumnRef@24..25 + Ident@24..25 "a" + Whitespace@25..26 " " + Collate@26..33 "COLLATE" + Whitespace@33..34 " " + Ident@34..37 "\"C\"" + Whitespace@37..38 " " + Ascii62@38..39 ">" + Whitespace@39..40 " " + AConst@40..45 + Sconst@40..45 "'foo'" + Ascii59@45..46 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0017@1.snap b/crates/pg_syntax/tests/snapshots/data/0017@1.snap new file mode 100644 index 00000000..acd52748 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0017@1.snap @@ -0,0 +1,54 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)\n FROM states;" +--- +SelectStmt@0..92 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..11 + ColumnRef@7..11 + NameP@7..11 "name" + Ascii44@11..12 "," + Whitespace@12..13 " " + ResTarget@13..74 + SubLink@13..74 + SelectStmt@13..74 + Ascii40@13..14 "(" + Select@14..20 "SELECT" + Whitespace@20..21 " " + ResTarget@21..28 + FuncCall@21..28 + Ident@21..24 "max" + Ascii40@24..25 "(" + ColumnRef@25..28 + Ident@25..28 "pop" + Ascii41@28..29 ")" + Whitespace@29..30 " " + From@30..34 "FROM" + Whitespace@34..35 " " + RangeVar@35..41 + Ident@35..41 "cities" + Whitespace@41..42 " " + Where@42..47 "WHERE" + Whitespace@47..48 " " + AExpr@48..74 + ColumnRef@48..60 + Ident@48..54 "cities" + Ascii46@54..55 "." + Ident@55..60 "state" + Whitespace@60..61 " " + Ascii61@61..62 "=" + Whitespace@62..63 " " + ColumnRef@63..74 + Ident@63..69 "states" + Ascii46@69..70 "." + NameP@70..74 "name" + Ascii41@74..75 ")" + Newline@75..76 "\n" + Whitespace@76..80 " " + From@80..84 "FROM" + Whitespace@84..85 " " + RangeVar@85..91 + Ident@85..91 "states" + Ascii59@91..92 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0018@1.snap b/crates/pg_syntax/tests/snapshots/data/0018@1.snap new file mode 100644 index 00000000..3ed8760d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0018@1.snap @@ -0,0 +1,28 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT ARRAY[1,2,22.7]::integer[];" +--- +SelectStmt@0..34 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..31 + TypeCast@7..31 + AArrayExpr@7..21 + Array@7..12 "ARRAY" + Ascii91@12..13 "[" + AConst@13..14 + Iconst@13..14 "1" + Ascii44@14..15 "," + AConst@15..16 + Iconst@15..16 "2" + Ascii44@16..17 "," + AConst@17..21 + Fconst@17..21 "22.7" + Ascii93@21..22 "]" + Typecast@22..24 "::" + TypeName@24..31 + Integer@24..31 "integer" + Ascii91@31..32 "[" + Ascii93@32..33 "]" + Ascii59@33..34 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0019@1.snap b/crates/pg_syntax/tests/snapshots/data/0019@1.snap new file mode 100644 index 00000000..2aa1ce6d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0019@1.snap @@ -0,0 +1,53 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT CASE WHEN min(employees) > 0\n THEN avg(expenses / employees)\n END\n FROM departments;" +--- +SelectStmt@0..111 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..89 + CaseExpr@7..89 + Case@7..11 "CASE" + Whitespace@11..12 " " + CaseWhen@12..77 + When@12..16 "WHEN" + Whitespace@16..17 " " + AExpr@17..35 + FuncCall@17..30 + Ident@17..20 "min" + Ascii40@20..21 "(" + ColumnRef@21..30 + Ident@21..30 "employees" + Ascii41@30..31 ")" + Whitespace@31..32 " " + Ascii62@32..33 ">" + Whitespace@33..34 " " + AConst@34..35 + Iconst@34..35 "0" + Newline@35..36 "\n" + Whitespace@36..48 " " + Then@48..52 "THEN" + Whitespace@52..53 " " + FuncCall@53..77 + Ident@53..56 "avg" + Ascii40@56..57 "(" + AExpr@57..77 + ColumnRef@57..65 + Ident@57..65 "expenses" + Whitespace@65..66 " " + Ascii47@66..67 "/" + Whitespace@67..68 " " + ColumnRef@68..77 + Ident@68..77 "employees" + Ascii41@77..78 ")" + Newline@78..79 "\n" + Whitespace@79..86 " " + EndP@86..89 "END" + Newline@89..90 "\n" + Whitespace@90..94 " " + From@94..98 "FROM" + Whitespace@98..99 " " + RangeVar@99..110 + Ident@99..110 "departments" + Ascii59@110..111 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0020@1.snap b/crates/pg_syntax/tests/snapshots/data/0020@1.snap new file mode 100644 index 00000000..02d280a7 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0020@1.snap @@ -0,0 +1,60 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false)\nRETURNS text\nAS\n$$\n SELECT CASE\n WHEN $3 THEN UPPER($1 || ' ' || $2)\n ELSE LOWER($1 || ' ' || $2)\n END;\n$$\nLANGUAGE SQL IMMUTABLE STRICT;" +--- +CreateFunctionStmt@0..245 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Function@7..15 "FUNCTION" + Whitespace@15..16 " " + Ident@16..37 "concat_lower_or_upper" + Ascii40@37..38 "(" + FunctionParameter@38..44 + Ident@38..39 "a" + Whitespace@39..40 " " + TypeName@40..44 + TextP@40..44 "text" + Ascii44@44..45 "," + Whitespace@45..46 " " + FunctionParameter@46..52 + Ident@46..47 "b" + Whitespace@47..48 " " + TypeName@48..52 + TextP@48..52 "text" + Ascii44@52..53 "," + Whitespace@53..54 " " + FunctionParameter@54..85 + Ident@54..63 "uppercase" + Whitespace@63..64 " " + TypeName@64..71 + BooleanP@64..71 "boolean" + Whitespace@71..72 " " + Default@72..79 "DEFAULT" + Whitespace@79..80 " " + AConst@80..85 + FalseP@80..85 "false" + Ascii41@85..86 ")" + Newline@86..87 "\n" + Returns@87..94 "RETURNS" + Whitespace@94..95 " " + TypeName@95..99 + TextP@95..99 "text" + Newline@99..100 "\n" + DefElem@100..214 + As@100..102 "AS" + Newline@102..103 "\n" + List@103..214 + Sconst@103..214 "$$\n SELECT CASE\n ..." + Newline@214..215 "\n" + DefElem@215..227 + Language@215..223 "LANGUAGE" + Whitespace@223..224 " " + SqlP@224..227 "SQL" + Whitespace@227..228 " " + DefElem@228..237 + Immutable@228..237 "IMMUTABLE" + Whitespace@237..238 " " + DefElem@238..244 + StrictP@238..244 "STRICT" + Ascii59@244..245 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0021@1.snap b/crates/pg_syntax/tests/snapshots/data/0021@1.snap new file mode 100644 index 00000000..ee4b44b4 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0021@1.snap @@ -0,0 +1,39 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true);" +--- +SelectStmt@0..76 + Select@0..6 "SELECT" + Whitespace@6..7 " " + ResTarget@7..74 + FuncCall@7..74 + Ident@7..28 "concat_lower_or_upper" + Ascii40@28..29 "(" + NamedArgExpr@29..41 + Ident@29..30 "a" + Whitespace@30..31 " " + EqualsGreater@31..33 "=>" + Whitespace@33..34 " " + AConst@34..41 + Sconst@34..41 "'Hello'" + Ascii44@41..42 "," + Whitespace@42..43 " " + NamedArgExpr@43..55 + Ident@43..44 "b" + Whitespace@44..45 " " + EqualsGreater@45..47 "=>" + Whitespace@47..48 " " + AConst@48..55 + Sconst@48..55 "'World'" + Ascii44@55..56 "," + Whitespace@56..57 " " + NamedArgExpr@57..74 + Ident@57..66 "uppercase" + Whitespace@66..67 " " + EqualsGreater@67..69 "=>" + Whitespace@69..70 " " + AConst@70..74 + TrueP@70..74 "true" + Ascii41@74..75 ")" + Ascii59@75..76 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0022@1.snap b/crates/pg_syntax/tests/snapshots/data/0022@1.snap new file mode 100644 index 00000000..db9152a7 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0022@1.snap @@ -0,0 +1,46 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE products (\n product_no integer,\n name text,\n price numeric DEFAULT 9.99\n);" +--- +CreateStmt@0..96 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..21 + Ident@13..21 "products" + Whitespace@21..22 " " + Ascii40@22..23 "(" + Newline@23..24 "\n" + Whitespace@24..28 " " + ColumnDef@28..46 + Ident@28..38 "product_no" + Whitespace@38..39 " " + TypeName@39..46 + Integer@39..46 "integer" + Ascii44@46..47 "," + Newline@47..48 "\n" + Whitespace@48..52 " " + ColumnDef@52..61 + NameP@52..56 "name" + Whitespace@56..57 " " + TypeName@57..61 + TextP@57..61 "text" + Ascii44@61..62 "," + Newline@62..63 "\n" + Whitespace@63..67 " " + ColumnDef@67..93 + Ident@67..72 "price" + Whitespace@72..73 " " + TypeName@73..80 + Numeric@73..80 "numeric" + Whitespace@80..81 " " + Constraint@81..93 + Default@81..88 "DEFAULT" + Whitespace@88..89 " " + AConst@89..93 + Fconst@89..93 "9.99" + Newline@93..94 "\n" + Ascii41@94..95 ")" + Ascii59@95..96 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0023@1.snap b/crates/pg_syntax/tests/snapshots/data/0023@1.snap new file mode 100644 index 00000000..b1128e2d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0023@1.snap @@ -0,0 +1,92 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE products (\n product_no integer,\n name text,\n price numeric CHECK (price > 0),\n discounted_price numeric CHECK (discounted_price > 0),\n CHECK (price > discounted_price)\n);" +--- +CreateStmt@0..198 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..21 + Ident@13..21 "products" + Whitespace@21..22 " " + Ascii40@22..23 "(" + Newline@23..24 "\n" + Whitespace@24..28 " " + ColumnDef@28..46 + Ident@28..38 "product_no" + Whitespace@38..39 " " + TypeName@39..46 + Integer@39..46 "integer" + Ascii44@46..47 "," + Newline@47..48 "\n" + Whitespace@48..52 " " + ColumnDef@52..61 + NameP@52..56 "name" + Whitespace@56..57 " " + TypeName@57..61 + TextP@57..61 "text" + Ascii44@61..62 "," + Newline@62..63 "\n" + Whitespace@63..67 " " + ColumnDef@67..97 + Ident@67..72 "price" + Whitespace@72..73 " " + TypeName@73..80 + Numeric@73..80 "numeric" + Whitespace@80..81 " " + Constraint@81..97 + Check@81..86 "CHECK" + Whitespace@86..87 " " + Ascii40@87..88 "(" + AExpr@88..97 + ColumnRef@88..93 + Ident@88..93 "price" + Whitespace@93..94 " " + Ascii62@94..95 ">" + Whitespace@95..96 " " + AConst@96..97 + Iconst@96..97 "0" + Ascii41@97..98 ")" + Ascii44@98..99 "," + Newline@99..100 "\n" + Whitespace@100..104 " " + ColumnDef@104..156 + Ident@104..120 "discounted_price" + Whitespace@120..121 " " + TypeName@121..128 + Numeric@121..128 "numeric" + Whitespace@128..129 " " + Constraint@129..156 + Check@129..134 "CHECK" + Whitespace@134..135 " " + Ascii40@135..136 "(" + AExpr@136..156 + ColumnRef@136..152 + Ident@136..152 "discounted_price" + Whitespace@152..153 " " + Ascii62@153..154 ">" + Whitespace@154..155 " " + AConst@155..156 + Iconst@155..156 "0" + Ascii41@156..157 ")" + Ascii44@157..158 "," + Newline@158..159 "\n" + Whitespace@159..163 " " + Constraint@163..194 + Check@163..168 "CHECK" + Whitespace@168..169 " " + Ascii40@169..170 "(" + AExpr@170..194 + ColumnRef@170..175 + Ident@170..175 "price" + Whitespace@175..176 " " + Ascii62@176..177 ">" + Whitespace@177..178 " " + ColumnRef@178..194 + Ident@178..194 "discounted_price" + Ascii41@194..195 ")" + Newline@195..196 "\n" + Ascii41@196..197 ")" + Ascii59@197..198 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0024@1.snap b/crates/pg_syntax/tests/snapshots/data/0024@1.snap new file mode 100644 index 00000000..bbfcca9f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0024@1.snap @@ -0,0 +1,66 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE order_items (\n product_no integer REFERENCES products,\n order_id integer REFERENCES orders,\n quantity integer,\n PRIMARY KEY (product_no, order_id)\n);" +--- +CreateStmt@0..174 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..24 + Ident@13..24 "order_items" + Whitespace@24..25 " " + Ascii40@25..26 "(" + Newline@26..27 "\n" + Whitespace@27..31 " " + ColumnDef@31..69 + Ident@31..41 "product_no" + Whitespace@41..42 " " + TypeName@42..49 + Integer@42..49 "integer" + Whitespace@49..50 " " + Constraint@50..69 + References@50..60 "REFERENCES" + Whitespace@60..61 " " + RangeVar@61..69 + Ident@61..69 "products" + Ascii44@69..70 "," + Newline@70..71 "\n" + Whitespace@71..75 " " + ColumnDef@75..109 + Ident@75..83 "order_id" + Whitespace@83..84 " " + TypeName@84..91 + Integer@84..91 "integer" + Whitespace@91..92 " " + Constraint@92..109 + References@92..102 "REFERENCES" + Whitespace@102..103 " " + RangeVar@103..109 + Ident@103..109 "orders" + Ascii44@109..110 "," + Newline@110..111 "\n" + Whitespace@111..115 " " + ColumnDef@115..131 + Ident@115..123 "quantity" + Whitespace@123..124 " " + TypeName@124..131 + Integer@124..131 "integer" + Ascii44@131..132 "," + Newline@132..133 "\n" + Whitespace@133..137 " " + Constraint@137..170 + Primary@137..144 "PRIMARY" + Whitespace@144..145 " " + Key@145..148 "KEY" + Whitespace@148..149 " " + Ascii40@149..150 "(" + Ident@150..160 "product_no" + Ascii44@160..161 "," + Whitespace@161..162 " " + Ident@162..170 "order_id" + Ascii41@170..171 ")" + Newline@171..172 "\n" + Ascii41@172..173 ")" + Ascii59@173..174 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0025@1.snap b/crates/pg_syntax/tests/snapshots/data/0025@1.snap new file mode 100644 index 00000000..dfee884d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0025@1.snap @@ -0,0 +1,30 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "ALTER TABLE products ADD CHECK (name <> '');" +--- +AlterTableStmt@0..44 + Alter@0..5 "ALTER" + Whitespace@5..6 " " + Table@6..11 "TABLE" + Whitespace@11..12 " " + RangeVar@12..20 + Ident@12..20 "products" + Whitespace@20..21 " " + AlterTableCmd@21..42 + AddP@21..24 "ADD" + Whitespace@24..25 " " + Constraint@25..42 + Check@25..30 "CHECK" + Whitespace@30..31 " " + Ascii40@31..32 "(" + AExpr@32..42 + ColumnRef@32..36 + NameP@32..36 "name" + Whitespace@36..37 " " + NotEquals@37..39 "<>" + Whitespace@39..40 " " + AConst@40..42 + Sconst@40..42 "''" + Ascii41@42..43 ")" + Ascii59@43..44 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0026@1.snap b/crates/pg_syntax/tests/snapshots/data/0026@1.snap new file mode 100644 index 00000000..134d4a2e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0026@1.snap @@ -0,0 +1,33 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);" +--- +AlterTableStmt@0..59 + Alter@0..5 "ALTER" + Whitespace@5..6 " " + Table@6..11 "TABLE" + Whitespace@11..12 " " + RangeVar@12..20 + Ident@12..20 "products" + Whitespace@20..21 " " + AlterTableCmd@21..57 + Alter@21..26 "ALTER" + Whitespace@26..27 " " + Column@27..33 "COLUMN" + Whitespace@33..34 " " + Ident@34..39 "price" + Whitespace@39..40 " " + TypeP@40..44 "TYPE" + Whitespace@44..45 " " + ColumnDef@45..57 + TypeName@45..57 + Numeric@45..52 "numeric" + Ascii40@52..53 "(" + AConst@53..55 + Iconst@53..55 "10" + Ascii44@55..56 "," + AConst@56..57 + Iconst@56..57 "2" + Ascii41@57..58 ")" + Ascii59@58..59 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0030@1.snap b/crates/pg_syntax/tests/snapshots/data/0030@1.snap new file mode 100644 index 00000000..384a318f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0030@1.snap @@ -0,0 +1,36 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE POLICY account_managers ON accounts TO managers\n USING (manager = current_user);" +--- +CreatePolicyStmt@0..90 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Policy@7..13 "POLICY" + Whitespace@13..14 " " + Ident@14..30 "account_managers" + Whitespace@30..31 " " + On@31..33 "ON" + Whitespace@33..34 " " + RangeVar@34..42 + Ident@34..42 "accounts" + Whitespace@42..43 " " + To@43..45 "TO" + Whitespace@45..46 " " + RoleSpec@46..54 + Ident@46..54 "managers" + Newline@54..55 "\n" + Whitespace@55..59 " " + Using@59..64 "USING" + Whitespace@64..65 " " + Ascii40@65..66 "(" + AExpr@66..88 + ColumnRef@66..73 + Ident@66..73 "manager" + Whitespace@73..74 " " + Ascii61@74..75 "=" + Whitespace@75..76 " " + SqlvalueFunction@76..88 + CurrentUser@76..88 "current_user" + Ascii41@88..89 ")" + Ascii59@89..90 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0032@1.snap b/crates/pg_syntax/tests/snapshots/data/0032@1.snap new file mode 100644 index 00000000..345a59d5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0032@1.snap @@ -0,0 +1,18 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "SET search_path TO myschema,public;" +--- +VariableSetStmt@0..35 + Set@0..3 "SET" + Whitespace@3..4 " " + Ident@4..15 "search_path" + Whitespace@15..16 " " + To@16..18 "TO" + Whitespace@18..19 " " + AConst@19..27 + Ident@19..27 "myschema" + Ascii44@27..28 "," + AConst@28..34 + Ident@28..34 "public" + Ascii59@34..35 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0033@1.snap b/crates/pg_syntax/tests/snapshots/data/0033@1.snap new file mode 100644 index 00000000..bc127b2e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0033@1.snap @@ -0,0 +1,70 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE measurement (\n city_id int not null,\n logdate date not null,\n peaktemp int,\n unitsales int\n) PARTITION BY RANGE (logdate);" +--- +CreateStmt@0..176 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..24 + Ident@13..24 "measurement" + Whitespace@24..25 " " + Ascii40@25..26 "(" + Newline@26..27 "\n" + Whitespace@27..31 " " + ColumnDef@31..59 + Ident@31..38 "city_id" + Whitespace@38..47 " " + TypeName@47..50 + IntP@47..50 "int" + Whitespace@50..51 " " + Constraint@51..59 + Not@51..54 "not" + Whitespace@54..55 " " + NullP@55..59 "null" + Ascii44@59..60 "," + Newline@60..61 "\n" + Whitespace@61..65 " " + ColumnDef@65..94 + Ident@65..72 "logdate" + Whitespace@72..81 " " + TypeName@81..85 + Ident@81..85 "date" + Whitespace@85..86 " " + Constraint@86..94 + Not@86..89 "not" + Whitespace@89..90 " " + NullP@90..94 "null" + Ascii44@94..95 "," + Newline@95..96 "\n" + Whitespace@96..100 " " + ColumnDef@100..119 + Ident@100..108 "peaktemp" + Whitespace@108..116 " " + TypeName@116..119 + IntP@116..119 "int" + Ascii44@119..120 "," + Newline@120..121 "\n" + Whitespace@121..125 " " + ColumnDef@125..144 + Ident@125..134 "unitsales" + Whitespace@134..141 " " + TypeName@141..144 + IntP@141..144 "int" + Newline@144..145 "\n" + Ascii41@145..146 ")" + Whitespace@146..147 " " + PartitionSpec@147..174 + Partition@147..156 "PARTITION" + Whitespace@156..157 " " + By@157..159 "BY" + Whitespace@159..160 " " + Range@160..165 "RANGE" + Whitespace@165..166 " " + Ascii40@166..167 "(" + PartitionElem@167..174 + Ident@167..174 "logdate" + Ascii41@174..175 ")" + Ascii59@175..176 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0034@1.snap b/crates/pg_syntax/tests/snapshots/data/0034@1.snap new file mode 100644 index 00000000..2f1114da --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0034@1.snap @@ -0,0 +1,33 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "select *,some_col from contact where id = '123 4 5';" +--- +SelectStmt@0..52 + Select@0..6 "select" + Whitespace@6..7 " " + ResTarget@7..8 + ColumnRef@7..8 + AStar@7..8 + Ascii42@7..8 "*" + Ascii44@8..9 "," + ResTarget@9..17 + ColumnRef@9..17 + Ident@9..17 "some_col" + Whitespace@17..18 " " + From@18..22 "from" + Whitespace@22..23 " " + RangeVar@23..30 + Ident@23..30 "contact" + Whitespace@30..31 " " + Where@31..36 "where" + Whitespace@36..37 " " + AExpr@37..51 + ColumnRef@37..39 + Ident@37..39 "id" + Whitespace@39..40 " " + Ascii61@40..41 "=" + Whitespace@41..42 " " + AConst@42..51 + Sconst@42..51 "'123 4 5'" + Ascii59@51..52 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0035@1.snap b/crates/pg_syntax/tests/snapshots/data/0035@1.snap new file mode 100644 index 00000000..2f1114da --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0035@1.snap @@ -0,0 +1,33 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "select *,some_col from contact where id = '123 4 5';" +--- +SelectStmt@0..52 + Select@0..6 "select" + Whitespace@6..7 " " + ResTarget@7..8 + ColumnRef@7..8 + AStar@7..8 + Ascii42@7..8 "*" + Ascii44@8..9 "," + ResTarget@9..17 + ColumnRef@9..17 + Ident@9..17 "some_col" + Whitespace@17..18 " " + From@18..22 "from" + Whitespace@22..23 " " + RangeVar@23..30 + Ident@23..30 "contact" + Whitespace@30..31 " " + Where@31..36 "where" + Whitespace@36..37 " " + AExpr@37..51 + ColumnRef@37..39 + Ident@37..39 "id" + Whitespace@39..40 " " + Ascii61@40..41 "=" + Whitespace@41..42 " " + AConst@42..51 + Sconst@42..51 "'123 4 5'" + Ascii59@51..52 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0036@1.snap b/crates/pg_syntax/tests/snapshots/data/0036@1.snap new file mode 100644 index 00000000..84fa7c53 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0036@1.snap @@ -0,0 +1,50 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE FUNCTION dup(in int, out f1 int, out f2 text)\n AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$\n LANGUAGE SQL;" +--- +CreateFunctionStmt@0..125 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Function@7..15 "FUNCTION" + Whitespace@15..16 " " + Ident@16..19 "dup" + Ascii40@19..20 "(" + FunctionParameter@20..26 + InP@20..22 "in" + Whitespace@22..23 " " + TypeName@23..26 + IntP@23..26 "int" + Ascii44@26..27 "," + Whitespace@27..28 " " + FunctionParameter@28..38 + OutP@28..31 "out" + Whitespace@31..32 " " + Ident@32..34 "f1" + Whitespace@34..35 " " + TypeName@35..38 + IntP@35..38 "int" + Ascii44@38..39 "," + Whitespace@39..40 " " + FunctionParameter@40..51 + OutP@40..43 "out" + Whitespace@43..44 " " + Ident@44..46 "f2" + Whitespace@46..47 " " + TypeName@47..51 + TextP@47..51 "text" + Ascii41@51..52 ")" + Newline@52..53 "\n" + Whitespace@53..57 " " + DefElem@57..107 + As@57..59 "AS" + Whitespace@59..60 " " + List@60..107 + Sconst@60..107 "$$ SELECT $1, CAST($1 ..." + Newline@107..108 "\n" + Whitespace@108..112 " " + DefElem@112..124 + Language@112..120 "LANGUAGE" + Whitespace@120..121 " " + SqlP@121..124 "SQL" + Ascii59@124..125 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0037@1.snap b/crates/pg_syntax/tests/snapshots/data/0037@1.snap new file mode 100644 index 00000000..6ea71c7a --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0037@1.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');" +--- +CreateEnumStmt@0..57 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..22 "bug_status" + Whitespace@22..23 " " + As@23..25 "AS" + Whitespace@25..26 " " + EnumP@26..30 "ENUM" + Whitespace@30..31 " " + Ascii40@31..32 "(" + Sconst@32..37 "'new'" + Ascii44@37..38 "," + Whitespace@38..39 " " + Sconst@39..45 "'open'" + Ascii44@45..46 "," + Whitespace@46..47 " " + Sconst@47..55 "'closed'" + Ascii41@55..56 ")" + Ascii59@56..57 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0038@1.snap b/crates/pg_syntax/tests/snapshots/data/0038@1.snap new file mode 100644 index 00000000..0786c84b --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0038@1.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT; +--- +CreateCastStmt@0..70 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Cast@7..11 "CAST" + Whitespace@11..12 " " + Ascii40@12..13 "(" + TypeName@13..19 + Bigint@13..19 "bigint" + Whitespace@19..20 " " + As@20..22 "AS" + Whitespace@22..23 " " + TypeName@23..27 + Ident@23..27 "int4" + Ascii41@27..28 ")" + Whitespace@28..29 " " + With@29..33 "WITH" + Whitespace@33..34 " " + Function@34..42 "FUNCTION" + Whitespace@42..43 " " + ObjectWithArgs@43..55 + Ident@43..47 "int4" + Ascii40@47..48 "(" + TypeName@48..54 + Bigint@48..54 "bigint" + Ascii41@54..55 ")" + Whitespace@55..56 " " + As@56..58 "AS" + Whitespace@58..59 " " + Assignment@59..69 "ASSIGNMENT" + Ascii59@69..70 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0038@2.snap b/crates/pg_syntax/tests/snapshots/data/0038@2.snap new file mode 100644 index 00000000..2a446dca --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0038@2.snap @@ -0,0 +1,28 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE CAST (bigint AS int4) WITHOUT FUNCTION AS IMPLICIT; +--- +CreateCastStmt@0..58 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Cast@7..11 "CAST" + Whitespace@11..12 " " + Ascii40@12..13 "(" + TypeName@13..19 + Bigint@13..19 "bigint" + Whitespace@19..20 " " + As@20..22 "AS" + Whitespace@22..23 " " + TypeName@23..27 + Ident@23..27 "int4" + Ascii41@27..28 ")" + Whitespace@28..29 " " + Without@29..36 "WITHOUT" + Whitespace@36..37 " " + Function@37..45 "FUNCTION" + Whitespace@45..46 " " + As@46..48 "AS" + Whitespace@48..49 " " + ImplicitP@49..57 "IMPLICIT" + Ascii59@57..58 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0038@3.snap b/crates/pg_syntax/tests/snapshots/data/0038@3.snap new file mode 100644 index 00000000..e8993525 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0038@3.snap @@ -0,0 +1,28 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE CAST (bigint AS int4) WITH INOUT AS ASSIGNMENT; +--- +CreateCastStmt@0..54 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Cast@7..11 "CAST" + Whitespace@11..12 " " + Ascii40@12..13 "(" + TypeName@13..19 + Bigint@13..19 "bigint" + Whitespace@19..20 " " + As@20..22 "AS" + Whitespace@22..23 " " + TypeName@23..27 + Ident@23..27 "int4" + Ascii41@27..28 ")" + Whitespace@28..29 " " + With@29..33 "WITH" + Whitespace@33..34 " " + Inout@34..39 "INOUT" + Whitespace@39..40 " " + As@40..42 "AS" + Whitespace@42..43 " " + Assignment@43..53 "ASSIGNMENT" + Ascii59@53..54 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@1.snap b/crates/pg_syntax/tests/snapshots/data/0039@1.snap new file mode 100644 index 00000000..1762308f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@1.snap @@ -0,0 +1,38 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1);" +--- +DefineStmt@0..68 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..27 "aggregate1" + Whitespace@27..28 " " + Ascii40@28..29 "(" + List@29..33 + FunctionParameter@29..33 + TypeName@29..33 + Ident@29..33 "int4" + Ascii41@33..34 ")" + Whitespace@34..35 " " + Ascii40@35..36 "(" + DefElem@36..50 + Ident@36..41 "sfunc" + Whitespace@41..42 " " + Ascii61@42..43 "=" + Whitespace@43..44 " " + TypeName@44..50 + Ident@44..50 "sfunc1" + Ascii44@50..51 "," + Whitespace@51..52 " " + DefElem@52..66 + Ident@52..57 "stype" + Whitespace@57..58 " " + Ascii61@58..59 "=" + Whitespace@59..60 " " + TypeName@60..66 + Ident@60..66 "stype1" + Ascii41@66..67 ")" + Ascii59@67..68 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@2.snap b/crates/pg_syntax/tests/snapshots/data/0039@2.snap new file mode 100644 index 00000000..bb38da14 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@2.snap @@ -0,0 +1,43 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE aggregate1 (int4, bool) (sfunc = sfunc1, stype = stype1);" +--- +DefineStmt@0..74 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..27 "aggregate1" + Whitespace@27..28 " " + Ascii40@28..29 "(" + List@29..39 + FunctionParameter@29..33 + TypeName@29..33 + Ident@29..33 "int4" + Ascii44@33..34 "," + Whitespace@34..35 " " + FunctionParameter@35..39 + TypeName@35..39 + Ident@35..39 "bool" + Ascii41@39..40 ")" + Whitespace@40..41 " " + Ascii40@41..42 "(" + DefElem@42..56 + Ident@42..47 "sfunc" + Whitespace@47..48 " " + Ascii61@48..49 "=" + Whitespace@49..50 " " + TypeName@50..56 + Ident@50..56 "sfunc1" + Ascii44@56..57 "," + Whitespace@57..58 " " + DefElem@58..72 + Ident@58..63 "stype" + Whitespace@63..64 " " + Ascii61@64..65 "=" + Whitespace@65..66 " " + TypeName@66..72 + Ident@66..72 "stype1" + Ascii41@72..73 ")" + Ascii59@73..74 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@3.snap b/crates/pg_syntax/tests/snapshots/data/0039@3.snap new file mode 100644 index 00000000..54adc89c --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@3.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE aggregate1 (*) (sfunc = sfunc1, stype = stype1);" +--- +DefineStmt@0..65 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..27 "aggregate1" + Whitespace@27..28 " " + Ascii40@28..29 "(" + Ascii42@29..30 "*" + Ascii41@30..31 ")" + Whitespace@31..32 " " + Ascii40@32..33 "(" + DefElem@33..47 + Ident@33..38 "sfunc" + Whitespace@38..39 " " + Ascii61@39..40 "=" + Whitespace@40..41 " " + TypeName@41..47 + Ident@41..47 "sfunc1" + Ascii44@47..48 "," + Whitespace@48..49 " " + DefElem@49..63 + Ident@49..54 "stype" + Whitespace@54..55 " " + Ascii61@55..56 "=" + Whitespace@56..57 " " + TypeName@57..63 + Ident@57..63 "stype1" + Ascii41@63..64 ")" + Ascii59@64..65 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@4.snap b/crates/pg_syntax/tests/snapshots/data/0039@4.snap new file mode 100644 index 00000000..c9c833e1 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@4.snap @@ -0,0 +1,46 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1, finalfunc_extra, mfinalfuncextra);" +--- +DefineStmt@0..102 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..27 "aggregate1" + Whitespace@27..28 " " + Ascii40@28..29 "(" + List@29..33 + FunctionParameter@29..33 + TypeName@29..33 + Ident@29..33 "int4" + Ascii41@33..34 ")" + Whitespace@34..35 " " + Ascii40@35..36 "(" + DefElem@36..50 + Ident@36..41 "sfunc" + Whitespace@41..42 " " + Ascii61@42..43 "=" + Whitespace@43..44 " " + TypeName@44..50 + Ident@44..50 "sfunc1" + Ascii44@50..51 "," + Whitespace@51..52 " " + DefElem@52..66 + Ident@52..57 "stype" + Whitespace@57..58 " " + Ascii61@58..59 "=" + Whitespace@59..60 " " + TypeName@60..66 + Ident@60..66 "stype1" + Ascii44@66..67 "," + Whitespace@67..68 " " + DefElem@68..83 + Ident@68..83 "finalfunc_extra" + Ascii44@83..84 "," + Whitespace@84..85 " " + DefElem@85..100 + Ident@85..100 "mfinalfuncextra" + Ascii41@100..101 ")" + Ascii59@101..102 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@5.snap b/crates/pg_syntax/tests/snapshots/data/0039@5.snap new file mode 100644 index 00000000..9c894ba5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@5.snap @@ -0,0 +1,56 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE aggregate1 (int4) (sfunc = sfunc1, stype = stype1, finalfunc_modify = read_only, parallel = restricted);" +--- +DefineStmt@0..121 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..27 "aggregate1" + Whitespace@27..28 " " + Ascii40@28..29 "(" + List@29..33 + FunctionParameter@29..33 + TypeName@29..33 + Ident@29..33 "int4" + Ascii41@33..34 ")" + Whitespace@34..35 " " + Ascii40@35..36 "(" + DefElem@36..50 + Ident@36..41 "sfunc" + Whitespace@41..42 " " + Ascii61@42..43 "=" + Whitespace@43..44 " " + TypeName@44..50 + Ident@44..50 "sfunc1" + Ascii44@50..51 "," + Whitespace@51..52 " " + DefElem@52..66 + Ident@52..57 "stype" + Whitespace@57..58 " " + Ascii61@58..59 "=" + Whitespace@59..60 " " + TypeName@60..66 + Ident@60..66 "stype1" + Ascii44@66..67 "," + Whitespace@67..68 " " + DefElem@68..96 + Ident@68..84 "finalfunc_modify" + Whitespace@84..85 " " + Ascii61@85..86 "=" + Whitespace@86..87 " " + TypeName@87..96 + Ident@87..96 "read_only" + Ascii44@96..97 "," + Whitespace@97..98 " " + DefElem@98..119 + Parallel@98..106 "parallel" + Whitespace@106..107 " " + Ascii61@107..108 "=" + Whitespace@108..109 " " + TypeName@109..119 + Ident@109..119 "restricted" + Ascii41@119..120 ")" + Ascii59@120..121 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@6.snap b/crates/pg_syntax/tests/snapshots/data/0039@6.snap new file mode 100644 index 00000000..12f0a7ec --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@6.snap @@ -0,0 +1,59 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement) (sfunc = ordered_set_transition, stype = internal, finalfunc = percentile_disc_final, finalfunc_extra);" +--- +DefineStmt@0..165 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..32 "percentile_disc" + Whitespace@32..33 " " + Ascii40@33..34 "(" + List@34..60 + FunctionParameter@34..40 + TypeName@34..40 + Ident@34..40 "float8" + Whitespace@40..41 " " + Order@41..46 "ORDER" + Whitespace@46..47 " " + By@47..49 "BY" + Whitespace@49..50 " " + FunctionParameter@50..60 + TypeName@50..60 + Ident@50..60 "anyelement" + Ascii41@60..61 ")" + Whitespace@61..62 " " + Ascii40@62..63 "(" + DefElem@63..93 + Ident@63..68 "sfunc" + Whitespace@68..69 " " + Ascii61@69..70 "=" + Whitespace@70..71 " " + TypeName@71..93 + Ident@71..93 "ordered_set_transition" + Ascii44@93..94 "," + Whitespace@94..95 " " + DefElem@95..111 + Ident@95..100 "stype" + Whitespace@100..101 " " + Ascii61@101..102 "=" + Whitespace@102..103 " " + TypeName@103..111 + Ident@103..111 "internal" + Ascii44@111..112 "," + Whitespace@112..113 " " + DefElem@113..146 + Ident@113..122 "finalfunc" + Whitespace@122..123 " " + Ascii61@123..124 "=" + Whitespace@124..125 " " + TypeName@125..146 + Ident@125..146 "percentile_disc_final" + Ascii44@146..147 "," + Whitespace@147..148 " " + DefElem@148..163 + Ident@148..163 "finalfunc_extra" + Ascii41@163..164 ")" + Ascii59@164..165 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0039@7.snap b/crates/pg_syntax/tests/snapshots/data/0039@7.snap new file mode 100644 index 00000000..ecaaca72 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0039@7.snap @@ -0,0 +1,51 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE AGGREGATE custom_aggregate (float8 ORDER BY column1, column2) (sfunc = sfunc1, stype = stype1);" +--- +DefineStmt@0..102 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Aggregate@7..16 "AGGREGATE" + Whitespace@16..17 " " + Ident@17..33 "custom_aggregate" + Whitespace@33..34 " " + Ascii40@34..35 "(" + List@35..67 + FunctionParameter@35..41 + TypeName@35..41 + Ident@35..41 "float8" + Whitespace@41..42 " " + Order@42..47 "ORDER" + Whitespace@47..48 " " + By@48..50 "BY" + Whitespace@50..51 " " + FunctionParameter@51..58 + TypeName@51..58 + Ident@51..58 "column1" + Ascii44@58..59 "," + Whitespace@59..60 " " + FunctionParameter@60..67 + TypeName@60..67 + Ident@60..67 "column2" + Ascii41@67..68 ")" + Whitespace@68..69 " " + Ascii40@69..70 "(" + DefElem@70..84 + Ident@70..75 "sfunc" + Whitespace@75..76 " " + Ascii61@76..77 "=" + Whitespace@77..78 " " + TypeName@78..84 + Ident@78..84 "sfunc1" + Ascii44@84..85 "," + Whitespace@85..86 " " + DefElem@86..100 + Ident@86..91 "stype" + Whitespace@91..92 " " + Ascii61@92..93 "=" + Whitespace@93..94 " " + TypeName@94..100 + Ident@94..100 "stype1" + Ascii41@100..101 ")" + Ascii59@101..102 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@1.snap b/crates/pg_syntax/tests/snapshots/data/0040@1.snap new file mode 100644 index 00000000..9327b8f6 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@1.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql;" +--- +CreateFunctionStmt@0..113 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Function@7..15 "FUNCTION" + Whitespace@15..16 " " + Ident@16..22 "getfoo" + Ascii40@22..23 "(" + FunctionParameter@23..26 + TypeName@23..26 + IntP@23..26 "int" + Ascii41@26..27 ")" + Whitespace@27..28 " " + Returns@28..35 "RETURNS" + Whitespace@35..36 " " + Setof@36..41 "SETOF" + Whitespace@41..42 " " + TypeName@42..47 + Ident@42..47 "users" + Whitespace@47..48 " " + DefElem@48..99 + As@48..50 "AS" + Whitespace@50..51 " " + List@51..99 + Sconst@51..99 "$$SELECT * FROM \\\"use ..." + Whitespace@99..100 " " + DefElem@100..112 + Language@100..108 "LANGUAGE" + Whitespace@108..109 " " + SqlP@109..112 "sql" + Ascii59@112..113 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@2.snap b/crates/pg_syntax/tests/snapshots/data/0040@2.snap new file mode 100644 index 00000000..1856ee9d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@2.snap @@ -0,0 +1,39 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql;" +--- +CreateFunctionStmt@0..124 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + FunctionParameter@34..37 + TypeName@34..37 + IntP@34..37 "int" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Returns@39..46 "RETURNS" + Whitespace@46..47 " " + Setof@47..52 "SETOF" + Whitespace@52..53 " " + TypeName@53..58 + Ident@53..58 "users" + Whitespace@58..59 " " + DefElem@59..110 + As@59..61 "AS" + Whitespace@61..62 " " + List@62..110 + Sconst@62..110 "$$SELECT * FROM \\\"use ..." + Whitespace@110..111 " " + DefElem@111..123 + Language@111..119 "LANGUAGE" + Whitespace@119..120 " " + SqlP@120..123 "sql" + Ascii59@123..124 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@3.snap b/crates/pg_syntax/tests/snapshots/data/0040@3.snap new file mode 100644 index 00000000..621be529 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@3.snap @@ -0,0 +1,42 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE;" +--- +CreateFunctionStmt@0..134 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + FunctionParameter@34..37 + TypeName@34..37 + IntP@34..37 "int" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Returns@39..46 "RETURNS" + Whitespace@46..47 " " + Setof@47..52 "SETOF" + Whitespace@52..53 " " + TypeName@53..58 + Ident@53..58 "users" + Whitespace@58..59 " " + DefElem@59..110 + As@59..61 "AS" + Whitespace@61..62 " " + List@62..110 + Sconst@62..110 "$$SELECT * FROM \\\"use ..." + Whitespace@110..111 " " + DefElem@111..123 + Language@111..119 "LANGUAGE" + Whitespace@119..120 " " + SqlP@120..123 "sql" + Whitespace@123..124 " " + DefElem@124..133 + Immutable@124..133 "IMMUTABLE" + Ascii59@133..134 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@4.snap b/crates/pg_syntax/tests/snapshots/data/0040@4.snap new file mode 100644 index 00000000..1d40703e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@4.snap @@ -0,0 +1,45 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE STRICT;" +--- +CreateFunctionStmt@0..141 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + FunctionParameter@34..37 + TypeName@34..37 + IntP@34..37 "int" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Returns@39..46 "RETURNS" + Whitespace@46..47 " " + Setof@47..52 "SETOF" + Whitespace@52..53 " " + TypeName@53..58 + Ident@53..58 "users" + Whitespace@58..59 " " + DefElem@59..110 + As@59..61 "AS" + Whitespace@61..62 " " + List@62..110 + Sconst@62..110 "$$SELECT * FROM \\\"use ..." + Whitespace@110..111 " " + DefElem@111..123 + Language@111..119 "LANGUAGE" + Whitespace@119..120 " " + SqlP@120..123 "sql" + Whitespace@123..124 " " + DefElem@124..133 + Immutable@124..133 "IMMUTABLE" + Whitespace@133..134 " " + DefElem@134..140 + StrictP@134..140 "STRICT" + Ascii59@140..141 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@5.snap b/crates/pg_syntax/tests/snapshots/data/0040@5.snap new file mode 100644 index 00000000..30e37019 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@5.snap @@ -0,0 +1,53 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE RETURNS NULL ON NULL INPUT;" +--- +CreateFunctionStmt@0..161 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + FunctionParameter@34..37 + TypeName@34..37 + IntP@34..37 "int" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Returns@39..46 "RETURNS" + Whitespace@46..47 " " + Setof@47..52 "SETOF" + Whitespace@52..53 " " + TypeName@53..58 + Ident@53..58 "users" + Whitespace@58..59 " " + DefElem@59..110 + As@59..61 "AS" + Whitespace@61..62 " " + List@62..110 + Sconst@62..110 "$$SELECT * FROM \\\"use ..." + Whitespace@110..111 " " + DefElem@111..123 + Language@111..119 "LANGUAGE" + Whitespace@119..120 " " + SqlP@120..123 "sql" + Whitespace@123..124 " " + DefElem@124..133 + Immutable@124..133 "IMMUTABLE" + Whitespace@133..134 " " + DefElem@134..141 + Returns@134..141 "RETURNS" + Whitespace@141..142 " " + NullP@142..146 "NULL" + Whitespace@146..147 " " + On@147..149 "ON" + Whitespace@149..150 " " + NullP@150..154 "NULL" + Whitespace@154..155 " " + InputP@155..160 "INPUT" + Ascii59@160..161 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@6.snap b/crates/pg_syntax/tests/snapshots/data/0040@6.snap new file mode 100644 index 00000000..e7c3b344 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@6.snap @@ -0,0 +1,51 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF users AS $$SELECT * FROM \\\"users\\\" WHERE users.id = $1;$$ LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT;" +--- +CreateFunctionStmt@0..155 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + FunctionParameter@34..37 + TypeName@34..37 + IntP@34..37 "int" + Ascii41@37..38 ")" + Whitespace@38..39 " " + Returns@39..46 "RETURNS" + Whitespace@46..47 " " + Setof@47..52 "SETOF" + Whitespace@52..53 " " + TypeName@53..58 + Ident@53..58 "users" + Whitespace@58..59 " " + DefElem@59..110 + As@59..61 "AS" + Whitespace@61..62 " " + List@62..110 + Sconst@62..110 "$$SELECT * FROM \\\"use ..." + Whitespace@110..111 " " + DefElem@111..123 + Language@111..119 "LANGUAGE" + Whitespace@119..120 " " + SqlP@120..123 "sql" + Whitespace@123..124 " " + DefElem@124..133 + Immutable@124..133 "IMMUTABLE" + Whitespace@133..134 " " + DefElem@134..140 + Called@134..140 "CALLED" + Whitespace@140..141 " " + On@141..143 "ON" + Whitespace@143..144 " " + NullP@144..148 "NULL" + Whitespace@148..149 " " + InputP@149..154 "INPUT" + Ascii59@154..155 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0040@7.snap b/crates/pg_syntax/tests/snapshots/data/0040@7.snap new file mode 100644 index 00000000..a9a97cf6 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0040@7.snap @@ -0,0 +1,46 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE FUNCTION getfoo() RETURNS text AS $$SELECT name FROM \\\"users\\\" LIMIT 1$$ LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT;" +--- +CreateFunctionStmt@0..135 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Function@18..26 "FUNCTION" + Whitespace@26..27 " " + Ident@27..33 "getfoo" + Ascii40@33..34 "(" + Ascii41@34..35 ")" + Whitespace@35..36 " " + Returns@36..43 "RETURNS" + Whitespace@43..44 " " + TypeName@44..48 + TextP@44..48 "text" + Whitespace@48..49 " " + DefElem@49..90 + As@49..51 "AS" + Whitespace@51..52 " " + List@52..90 + Sconst@52..90 "$$SELECT name FROM \\\" ..." + Whitespace@90..91 " " + DefElem@91..103 + Language@91..99 "LANGUAGE" + Whitespace@99..100 " " + SqlP@100..103 "sql" + Whitespace@103..104 " " + DefElem@104..113 + Immutable@104..113 "IMMUTABLE" + Whitespace@113..114 " " + DefElem@114..120 + Called@114..120 "CALLED" + Whitespace@120..121 " " + On@121..123 "ON" + Whitespace@123..124 " " + NullP@124..128 "NULL" + Whitespace@128..129 " " + InputP@129..134 "INPUT" + Ascii59@134..135 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0041@1.snap b/crates/pg_syntax/tests/snapshots/data/0041@1.snap new file mode 100644 index 00000000..4fff07e6 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0041@1.snap @@ -0,0 +1,12 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE SCHEMA myschema; +--- +CreateSchemaStmt@0..23 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Schema@7..13 "SCHEMA" + Whitespace@13..14 " " + Ident@14..22 "myschema" + Ascii59@22..23 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0041@2.snap b/crates/pg_syntax/tests/snapshots/data/0041@2.snap new file mode 100644 index 00000000..4fe627a5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0041@2.snap @@ -0,0 +1,15 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE SCHEMA AUTHORIZATION joe; +--- +CreateSchemaStmt@0..32 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Schema@7..13 "SCHEMA" + Whitespace@13..14 " " + Authorization@14..27 "AUTHORIZATION" + Whitespace@27..28 " " + RoleSpec@28..31 + Ident@28..31 "joe" + Ascii59@31..32 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0041@3.snap b/crates/pg_syntax/tests/snapshots/data/0041@3.snap new file mode 100644 index 00000000..e6cbf88e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0041@3.snap @@ -0,0 +1,23 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe; +--- +CreateSchemaStmt@0..51 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Schema@7..13 "SCHEMA" + Whitespace@13..14 " " + IfP@14..16 "IF" + Whitespace@16..17 " " + Not@17..20 "NOT" + Whitespace@20..21 " " + Exists@21..27 "EXISTS" + Whitespace@27..28 " " + Ident@28..32 "test" + Whitespace@32..33 " " + Authorization@33..46 "AUTHORIZATION" + Whitespace@46..47 " " + RoleSpec@47..50 + Ident@47..50 "joe" + Ascii59@50..51 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0041@4.snap b/crates/pg_syntax/tests/snapshots/data/0041@4.snap new file mode 100644 index 00000000..5ef37004 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0041@4.snap @@ -0,0 +1,83 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE SCHEMA hollywood CREATE TABLE films (title text, release date, awards text[]) CREATE VIEW winners AS SELECT title, release FROM films WHERE awards IS NOT NULL;" +--- +CreateSchemaStmt@0..166 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Schema@7..13 "SCHEMA" + Whitespace@13..14 " " + Ident@14..23 "hollywood" + Whitespace@23..24 " " + CreateStmt@24..81 + Create@24..30 "CREATE" + Whitespace@30..31 " " + Table@31..36 "TABLE" + Whitespace@36..37 " " + RangeVar@37..42 + Ident@37..42 "films" + Whitespace@42..43 " " + Ascii40@43..44 "(" + ColumnDef@44..54 + Ident@44..49 "title" + Whitespace@49..50 " " + TypeName@50..54 + TextP@50..54 "text" + Ascii44@54..55 "," + Whitespace@55..56 " " + ColumnDef@56..68 + Release@56..63 "release" + Whitespace@63..64 " " + TypeName@64..68 + Ident@64..68 "date" + Ascii44@68..69 "," + Whitespace@69..70 " " + ColumnDef@70..81 + Ident@70..76 "awards" + Whitespace@76..77 " " + TypeName@77..81 + TextP@77..81 "text" + Ascii91@81..82 "[" + Ascii93@82..83 "]" + Ascii41@83..84 ")" + Whitespace@84..85 " " + ViewStmt@85..165 + Create@85..91 "CREATE" + Whitespace@91..92 " " + View@92..96 "VIEW" + Whitespace@96..97 " " + RangeVar@97..104 + Ident@97..104 "winners" + Whitespace@104..105 " " + As@105..107 "AS" + Whitespace@107..108 " " + SelectStmt@108..165 + Select@108..114 "SELECT" + Whitespace@114..115 " " + ResTarget@115..120 + ColumnRef@115..120 + Ident@115..120 "title" + Ascii44@120..121 "," + Whitespace@121..122 " " + ResTarget@122..129 + ColumnRef@122..129 + Release@122..129 "release" + Whitespace@129..130 " " + From@130..134 "FROM" + Whitespace@134..135 " " + RangeVar@135..140 + Ident@135..140 "films" + Whitespace@140..141 " " + Where@141..146 "WHERE" + Whitespace@146..147 " " + NullTest@147..165 + ColumnRef@147..153 + Ident@147..153 "awards" + Whitespace@153..154 " " + Is@154..156 "IS" + Whitespace@156..157 " " + Not@157..160 "NOT" + Whitespace@160..161 " " + NullP@161..165 "NULL" + Ascii59@165..166 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0042@1.snap b/crates/pg_syntax/tests/snapshots/data/0042@1.snap new file mode 100644 index 00000000..57b18249 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0042@1.snap @@ -0,0 +1,42 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE DOMAIN us_postal_code AS TEXT CHECK(VALUE ~ '^\\d{5}$' OR VALUE ~ '^\\d{5}-\\d{4}$');" +--- +CreateDomainStmt@0..89 + Create@0..6 "CREATE" + Whitespace@6..7 " " + DomainP@7..13 "DOMAIN" + Whitespace@13..14 " " + Ident@14..28 "us_postal_code" + Whitespace@28..29 " " + As@29..31 "AS" + Whitespace@31..32 " " + TypeName@32..36 + TextP@32..36 "TEXT" + Whitespace@36..37 " " + Constraint@37..87 + Check@37..42 "CHECK" + Ascii40@42..43 "(" + BoolExpr@43..87 + AExpr@43..60 + ColumnRef@43..48 + ValueP@43..48 "VALUE" + Whitespace@48..49 " " + Op@49..50 "~" + Whitespace@50..51 " " + AConst@51..60 + Sconst@51..60 "'^\\d{5}$'" + Whitespace@60..61 " " + Or@61..63 "OR" + Whitespace@63..64 " " + AExpr@64..87 + ColumnRef@64..69 + ValueP@64..69 "VALUE" + Whitespace@69..70 " " + Op@70..71 "~" + Whitespace@71..72 " " + AConst@72..87 + Sconst@72..87 "'^\\d{5}-\\d{4}$'" + Ascii41@87..88 ")" + Ascii59@88..89 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@1.snap b/crates/pg_syntax/tests/snapshots/data/0043@1.snap new file mode 100644 index 00000000..433b48c3 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@1.snap @@ -0,0 +1,58 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE UNLOGGED TABLE cities (name text, population real, altitude double, identifier smallint, postal_code int, foreign_id bigint);" +--- +CreateStmt@0..132 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Unlogged@7..15 "UNLOGGED" + Whitespace@15..16 " " + Table@16..21 "TABLE" + Whitespace@21..22 " " + RangeVar@22..28 + Ident@22..28 "cities" + Whitespace@28..29 " " + Ascii40@29..30 "(" + ColumnDef@30..39 + NameP@30..34 "name" + Whitespace@34..35 " " + TypeName@35..39 + TextP@35..39 "text" + Ascii44@39..40 "," + Whitespace@40..41 " " + ColumnDef@41..56 + Ident@41..51 "population" + Whitespace@51..52 " " + TypeName@52..56 + Real@52..56 "real" + Ascii44@56..57 "," + Whitespace@57..58 " " + ColumnDef@58..73 + Ident@58..66 "altitude" + Whitespace@66..67 " " + TypeName@67..73 + DoubleP@67..73 "double" + Ascii44@73..74 "," + Whitespace@74..75 " " + ColumnDef@75..94 + Ident@75..85 "identifier" + Whitespace@85..86 " " + TypeName@86..94 + Smallint@86..94 "smallint" + Ascii44@94..95 "," + Whitespace@95..96 " " + ColumnDef@96..111 + Ident@96..107 "postal_code" + Whitespace@107..108 " " + TypeName@108..111 + IntP@108..111 "int" + Ascii44@111..112 "," + Whitespace@112..113 " " + ColumnDef@113..130 + Ident@113..123 "foreign_id" + Whitespace@123..124 " " + TypeName@124..130 + Bigint@124..130 "bigint" + Ascii41@130..131 ")" + Ascii59@131..132 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@10.snap b/crates/pg_syntax/tests/snapshots/data/0043@10.snap new file mode 100644 index 00000000..3c51d79b --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@10.snap @@ -0,0 +1,25 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE TABLE like_constraint_rename_cache (LIKE constraint_rename_cache INCLUDING ALL); +--- +CreateStmt@0..87 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..41 + Ident@13..41 "like_constraint_renam ..." + Whitespace@41..42 " " + Ascii40@42..43 "(" + TableLikeClause@43..85 + Like@43..47 "LIKE" + Whitespace@47..48 " " + RangeVar@48..71 + Ident@48..71 "constraint_rename_cache" + Whitespace@71..72 " " + Including@72..81 "INCLUDING" + Whitespace@81..82 " " + All@82..85 "ALL" + Ascii41@85..86 ")" + Ascii59@86..87 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@11.snap b/crates/pg_syntax/tests/snapshots/data/0043@11.snap new file mode 100644 index 00000000..d79df88e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@11.snap @@ -0,0 +1,58 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE distributors (did int, name varchar(40), UNIQUE (name) WITH (fillfactor=70)) WITH (fillfactor=70);" +--- +CreateStmt@0..111 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..25 + Ident@13..25 "distributors" + Whitespace@25..26 " " + Ascii40@26..27 "(" + ColumnDef@27..34 + Ident@27..30 "did" + Whitespace@30..31 " " + TypeName@31..34 + IntP@31..34 "int" + Ascii44@34..35 "," + Whitespace@35..36 " " + ColumnDef@36..51 + NameP@36..40 "name" + Whitespace@40..41 " " + TypeName@41..51 + Varchar@41..48 "varchar" + Ascii40@48..49 "(" + AConst@49..51 + Iconst@49..51 "40" + Ascii41@51..52 ")" + Ascii44@52..53 "," + Whitespace@53..54 " " + Constraint@54..87 + Unique@54..60 "UNIQUE" + Whitespace@60..61 " " + Ascii40@61..62 "(" + NameP@62..66 "name" + Ascii41@66..67 ")" + Whitespace@67..68 " " + With@68..72 "WITH" + Whitespace@72..73 " " + Ascii40@73..74 "(" + DefElem@74..87 + Ident@74..84 "fillfactor" + Ascii61@84..85 "=" + Iconst@85..87 "70" + Ascii41@87..88 ")" + Ascii41@88..89 ")" + Whitespace@89..90 " " + With@90..94 "WITH" + Whitespace@94..95 " " + Ascii40@95..96 "(" + DefElem@96..109 + Ident@96..106 "fillfactor" + Ascii61@106..107 "=" + Iconst@107..109 "70" + Ascii41@109..110 ")" + Ascii59@110..111 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@2.snap b/crates/pg_syntax/tests/snapshots/data/0043@2.snap new file mode 100644 index 00000000..3c460f90 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@2.snap @@ -0,0 +1,164 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE IF NOT EXISTS distributors (name varchar(40) DEFAULT 'Luso Films', len interval hour to second(3), name varchar(40) DEFAULT 'Luso Films', did int DEFAULT nextval('distributors_serial'), stamp timestamp DEFAULT now() NOT NULL, stamptz timestamp with time zone, \"time\" time NOT NULL, timetz time with time zone, CONSTRAINT name_len PRIMARY KEY (name, len));" +--- +CreateStmt@0..368 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + IfP@13..15 "IF" + Whitespace@15..16 " " + Not@16..19 "NOT" + Whitespace@19..20 " " + Exists@20..26 "EXISTS" + Whitespace@26..27 " " + RangeVar@27..39 + Ident@27..39 "distributors" + Whitespace@39..40 " " + Ascii40@40..41 "(" + ColumnDef@41..78 + NameP@41..45 "name" + Whitespace@45..46 " " + TypeName@46..56 + Varchar@46..53 "varchar" + Ascii40@53..54 "(" + AConst@54..56 + Iconst@54..56 "40" + Ascii41@56..57 ")" + Whitespace@57..58 " " + Constraint@58..78 + Default@58..65 "DEFAULT" + Whitespace@65..66 " " + AConst@66..78 + Sconst@66..78 "'Luso Films'" + Ascii44@78..79 "," + Whitespace@79..80 " " + ColumnDef@80..109 + Ident@80..83 "len" + Whitespace@83..84 " " + TypeName@84..109 + Interval@84..92 "interval" + Whitespace@92..93 " " + AConst@93..97 + HourP@93..97 "hour" + Whitespace@97..98 " " + To@98..100 "to" + Whitespace@100..101 " " + SecondP@101..107 "second" + Ascii40@107..108 "(" + AConst@108..109 + Iconst@108..109 "3" + Ascii41@109..110 ")" + Ascii44@110..111 "," + Whitespace@111..112 " " + ColumnDef@112..149 + NameP@112..116 "name" + Whitespace@116..117 " " + TypeName@117..127 + Varchar@117..124 "varchar" + Ascii40@124..125 "(" + AConst@125..127 + Iconst@125..127 "40" + Ascii41@127..128 ")" + Whitespace@128..129 " " + Constraint@129..149 + Default@129..136 "DEFAULT" + Whitespace@136..137 " " + AConst@137..149 + Sconst@137..149 "'Luso Films'" + Ascii44@149..150 "," + Whitespace@150..151 " " + ColumnDef@151..196 + Ident@151..154 "did" + Whitespace@154..155 " " + TypeName@155..158 + IntP@155..158 "int" + Whitespace@158..159 " " + Constraint@159..196 + Default@159..166 "DEFAULT" + Whitespace@166..167 " " + FuncCall@167..196 + Ident@167..174 "nextval" + Ascii40@174..175 "(" + AConst@175..196 + Sconst@175..196 "'distributors_serial'" + Ascii41@196..197 ")" + Ascii44@197..198 "," + Whitespace@198..199 " " + ColumnDef@199..237 + Ident@199..204 "stamp" + Whitespace@204..205 " " + TypeName@205..214 + Timestamp@205..214 "timestamp" + Whitespace@214..215 " " + Constraint@215..226 + Default@215..222 "DEFAULT" + Whitespace@222..223 " " + FuncCall@223..226 + Ident@223..226 "now" + Ascii40@226..227 "(" + Ascii41@227..228 ")" + Whitespace@228..229 " " + Constraint@229..237 + Not@229..232 "NOT" + Whitespace@232..233 " " + NullP@233..237 "NULL" + Ascii44@237..238 "," + Whitespace@238..239 " " + ColumnDef@239..271 + Ident@239..246 "stamptz" + Whitespace@246..247 " " + TypeName@247..271 + Timestamp@247..256 "timestamp" + Whitespace@256..257 " " + With@257..261 "with" + Whitespace@261..262 " " + Time@262..266 "time" + Whitespace@266..267 " " + Zone@267..271 "zone" + Ascii44@271..272 "," + Whitespace@272..273 " " + ColumnDef@273..293 + Ident@273..279 "\"time\"" + Whitespace@279..280 " " + TypeName@280..284 + Time@280..284 "time" + Whitespace@284..285 " " + Constraint@285..293 + Not@285..288 "NOT" + Whitespace@288..289 " " + NullP@289..293 "NULL" + Ascii44@293..294 "," + Whitespace@294..295 " " + ColumnDef@295..321 + Ident@295..301 "timetz" + Whitespace@301..302 " " + TypeName@302..321 + Time@302..306 "time" + Whitespace@306..307 " " + With@307..311 "with" + Whitespace@311..312 " " + Time@312..316 "time" + Whitespace@316..317 " " + Zone@317..321 "zone" + Ascii44@321..322 "," + Whitespace@322..323 " " + Constraint@323..365 + Constraint@323..333 "CONSTRAINT" + Whitespace@333..334 " " + Ident@334..342 "name_len" + Whitespace@342..343 " " + Primary@343..350 "PRIMARY" + Whitespace@350..351 " " + Key@351..354 "KEY" + Whitespace@354..355 " " + Ascii40@355..356 "(" + NameP@356..360 "name" + Ascii44@360..361 "," + Whitespace@361..362 " " + Ident@362..365 "len" + Ascii41@365..366 ")" + Ascii41@366..367 ")" + Ascii59@367..368 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@3.snap b/crates/pg_syntax/tests/snapshots/data/0043@3.snap new file mode 100644 index 00000000..d388454b --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@3.snap @@ -0,0 +1,89 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE types (a real, b double precision, c numeric(2, 3), d char(4), e char(5), f varchar(6), g varchar(7));" +--- +CreateStmt@0..115 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..18 + TypesP@13..18 "types" + Whitespace@18..19 " " + Ascii40@19..20 "(" + ColumnDef@20..26 + Ident@20..21 "a" + Whitespace@21..22 " " + TypeName@22..26 + Real@22..26 "real" + Ascii44@26..27 "," + Whitespace@27..28 " " + ColumnDef@28..46 + Ident@28..29 "b" + Whitespace@29..30 " " + TypeName@30..46 + DoubleP@30..36 "double" + Whitespace@36..37 " " + Precision@37..46 "precision" + Ascii44@46..47 "," + Whitespace@47..48 " " + ColumnDef@48..62 + Ident@48..49 "c" + Whitespace@49..50 " " + TypeName@50..62 + Numeric@50..57 "numeric" + Ascii40@57..58 "(" + AConst@58..59 + Iconst@58..59 "2" + Ascii44@59..60 "," + Whitespace@60..61 " " + AConst@61..62 + Iconst@61..62 "3" + Ascii41@62..63 ")" + Ascii44@63..64 "," + Whitespace@64..65 " " + ColumnDef@65..73 + Ident@65..66 "d" + Whitespace@66..67 " " + TypeName@67..73 + CharP@67..71 "char" + Ascii40@71..72 "(" + AConst@72..73 + Iconst@72..73 "4" + Ascii41@73..74 ")" + Ascii44@74..75 "," + Whitespace@75..76 " " + ColumnDef@76..84 + Ident@76..77 "e" + Whitespace@77..78 " " + TypeName@78..84 + CharP@78..82 "char" + Ascii40@82..83 "(" + AConst@83..84 + Iconst@83..84 "5" + Ascii41@84..85 ")" + Ascii44@85..86 "," + Whitespace@86..87 " " + ColumnDef@87..98 + Ident@87..88 "f" + Whitespace@88..89 " " + TypeName@89..98 + Varchar@89..96 "varchar" + Ascii40@96..97 "(" + AConst@97..98 + Iconst@97..98 "6" + Ascii41@98..99 ")" + Ascii44@99..100 "," + Whitespace@100..101 " " + ColumnDef@101..112 + Ident@101..102 "g" + Whitespace@102..103 " " + TypeName@103..112 + Varchar@103..110 "varchar" + Ascii40@110..111 "(" + AConst@111..112 + Iconst@111..112 "7" + Ascii41@112..113 ")" + Ascii41@113..114 ")" + Ascii59@114..115 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@4.snap b/crates/pg_syntax/tests/snapshots/data/0043@4.snap new file mode 100644 index 00000000..e2e65193 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@4.snap @@ -0,0 +1,30 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE TABLE types (a geometry(point) NOT NULL); +--- +CreateStmt@0..48 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..18 + TypesP@13..18 "types" + Whitespace@18..19 " " + Ascii40@19..20 "(" + ColumnDef@20..46 + Ident@20..21 "a" + Whitespace@21..22 " " + TypeName@22..36 + Ident@22..30 "geometry" + Ascii40@30..31 "(" + ColumnRef@31..36 + Ident@31..36 "point" + Ascii41@36..37 ")" + Whitespace@37..38 " " + Constraint@38..46 + Not@38..41 "NOT" + Whitespace@41..42 " " + NullP@42..46 "NULL" + Ascii41@46..47 ")" + Ascii59@47..48 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@5.snap b/crates/pg_syntax/tests/snapshots/data/0043@5.snap new file mode 100644 index 00000000..5eea1e8f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@5.snap @@ -0,0 +1,36 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLE tablename (colname int NOT NULL DEFAULT nextval('tablename_colname_seq'));" +--- +CreateStmt@0..87 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..22 + Ident@13..22 "tablename" + Whitespace@22..23 " " + Ascii40@23..24 "(" + ColumnDef@24..84 + Ident@24..31 "colname" + Whitespace@31..32 " " + TypeName@32..35 + IntP@32..35 "int" + Whitespace@35..36 " " + Constraint@36..44 + Not@36..39 "NOT" + Whitespace@39..40 " " + NullP@40..44 "NULL" + Whitespace@44..45 " " + Constraint@45..84 + Default@45..52 "DEFAULT" + Whitespace@52..53 " " + FuncCall@53..84 + Ident@53..60 "nextval" + Ascii40@60..61 "(" + AConst@61..84 + Sconst@61..84 "'tablename_colname_seq'" + Ascii41@84..85 ")" + Ascii41@85..86 ")" + Ascii59@86..87 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0043@6.snap b/crates/pg_syntax/tests/snapshots/data/0043@6.snap new file mode 100644 index 00000000..879bdc39 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0043@6.snap @@ -0,0 +1,32 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE TABLE capitals (state char(2)) INHERITS (cities); +--- +CreateStmt@0..56 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Table@7..12 "TABLE" + Whitespace@12..13 " " + RangeVar@13..21 + Ident@13..21 "capitals" + Whitespace@21..22 " " + Ascii40@22..23 "(" + ColumnDef@23..35 + Ident@23..28 "state" + Whitespace@28..29 " " + TypeName@29..35 + CharP@29..33 "char" + Ascii40@33..34 "(" + AConst@34..35 + Iconst@34..35 "2" + Ascii41@35..36 ")" + Ascii41@36..37 ")" + Whitespace@37..38 " " + Inherits@38..46 "INHERITS" + Whitespace@46..47 " " + Ascii40@47..48 "(" + RangeVar@48..54 + Ident@48..54 "cities" + Ascii41@54..55 ")" + Ascii59@55..56 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0044@1.snap b/crates/pg_syntax/tests/snapshots/data/0044@1.snap new file mode 100644 index 00000000..17fbd351 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0044@1.snap @@ -0,0 +1,39 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE VIEW comedies AS SELECT * FROM films WHERE kind = 'Comedy';" +--- +ViewStmt@0..66 + Create@0..6 "CREATE" + Whitespace@6..7 " " + View@7..11 "VIEW" + Whitespace@11..12 " " + RangeVar@12..20 + Ident@12..20 "comedies" + Whitespace@20..21 " " + As@21..23 "AS" + Whitespace@23..24 " " + SelectStmt@24..65 + Select@24..30 "SELECT" + Whitespace@30..31 " " + ResTarget@31..32 + ColumnRef@31..32 + AStar@31..32 + Ascii42@31..32 "*" + Whitespace@32..33 " " + From@33..37 "FROM" + Whitespace@37..38 " " + RangeVar@38..43 + Ident@38..43 "films" + Whitespace@43..44 " " + Where@44..49 "WHERE" + Whitespace@49..50 " " + AExpr@50..65 + ColumnRef@50..54 + Ident@50..54 "kind" + Whitespace@54..55 " " + Ascii61@55..56 "=" + Whitespace@56..57 " " + AConst@57..65 + Sconst@57..65 "'Comedy'" + Ascii59@65..66 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0044@2.snap b/crates/pg_syntax/tests/snapshots/data/0044@2.snap new file mode 100644 index 00000000..1edcbbb5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0044@2.snap @@ -0,0 +1,47 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE VIEW universal_comedies AS SELECT * FROM comedies WHERE classification = 'U' WITH LOCAL CHECK OPTION;" +--- +ViewStmt@0..108 + Create@0..6 "CREATE" + Whitespace@6..7 " " + View@7..11 "VIEW" + Whitespace@11..12 " " + RangeVar@12..30 + Ident@12..30 "universal_comedies" + Whitespace@30..31 " " + As@31..33 "AS" + Whitespace@33..34 " " + SelectStmt@34..83 + Select@34..40 "SELECT" + Whitespace@40..41 " " + ResTarget@41..42 + ColumnRef@41..42 + AStar@41..42 + Ascii42@41..42 "*" + Whitespace@42..43 " " + From@43..47 "FROM" + Whitespace@47..48 " " + RangeVar@48..56 + Ident@48..56 "comedies" + Whitespace@56..57 " " + Where@57..62 "WHERE" + Whitespace@62..63 " " + AExpr@63..83 + ColumnRef@63..77 + Ident@63..77 "classification" + Whitespace@77..78 " " + Ascii61@78..79 "=" + Whitespace@79..80 " " + AConst@80..83 + Sconst@80..83 "'U'" + Whitespace@83..84 " " + With@84..88 "WITH" + Whitespace@88..89 " " + Local@89..94 "LOCAL" + Whitespace@94..95 " " + Check@95..100 "CHECK" + Whitespace@100..101 " " + Option@101..107 "OPTION" + Ascii59@107..108 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0044@3.snap b/crates/pg_syntax/tests/snapshots/data/0044@3.snap new file mode 100644 index 00000000..0f082ead --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0044@3.snap @@ -0,0 +1,47 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE VIEW pg_comedies AS SELECT * FROM comedies WHERE classification = 'PG' WITH CASCADED CHECK OPTION;" +--- +ViewStmt@0..105 + Create@0..6 "CREATE" + Whitespace@6..7 " " + View@7..11 "VIEW" + Whitespace@11..12 " " + RangeVar@12..23 + Ident@12..23 "pg_comedies" + Whitespace@23..24 " " + As@24..26 "AS" + Whitespace@26..27 " " + SelectStmt@27..77 + Select@27..33 "SELECT" + Whitespace@33..34 " " + ResTarget@34..35 + ColumnRef@34..35 + AStar@34..35 + Ascii42@34..35 "*" + Whitespace@35..36 " " + From@36..40 "FROM" + Whitespace@40..41 " " + RangeVar@41..49 + Ident@41..49 "comedies" + Whitespace@49..50 " " + Where@50..55 "WHERE" + Whitespace@55..56 " " + AExpr@56..77 + ColumnRef@56..70 + Ident@56..70 "classification" + Whitespace@70..71 " " + Ascii61@71..72 "=" + Whitespace@72..73 " " + AConst@73..77 + Sconst@73..77 "'PG'" + Whitespace@77..78 " " + With@78..82 "WITH" + Whitespace@82..83 " " + Cascaded@83..91 "CASCADED" + Whitespace@91..92 " " + Check@92..97 "CHECK" + Whitespace@97..98 " " + Option@98..104 "OPTION" + Ascii59@104..105 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0044@4.snap b/crates/pg_syntax/tests/snapshots/data/0044@4.snap new file mode 100644 index 00000000..3f74e0a5 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0044@4.snap @@ -0,0 +1,106 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE VIEW comedies AS SELECT f.*, country_code_to_name(f.country_code) AS country, (SELECT avg(r.rating) FROM user_ratings r WHERE r.film_id = f.id) AS avg_rating FROM films f WHERE f.kind = 'Comedy';" +--- +ViewStmt@0..202 + Create@0..6 "CREATE" + Whitespace@6..7 " " + View@7..11 "VIEW" + Whitespace@11..12 " " + RangeVar@12..20 + Ident@12..20 "comedies" + Whitespace@20..21 " " + As@21..23 "AS" + Whitespace@23..24 " " + SelectStmt@24..201 + Select@24..30 "SELECT" + Whitespace@30..31 " " + ResTarget@31..34 + ColumnRef@31..34 + Ident@31..32 "f" + Ascii46@32..33 "." + AStar@33..34 + Ascii42@33..34 "*" + Ascii44@34..35 "," + Whitespace@35..36 " " + ResTarget@36..83 + FuncCall@36..71 + Ident@36..56 "country_code_to_name" + Ascii40@56..57 "(" + ColumnRef@57..71 + Ident@57..58 "f" + Ascii46@58..59 "." + Ident@59..71 "country_code" + Ascii41@71..72 ")" + Whitespace@72..73 " " + As@73..75 "AS" + Whitespace@75..76 " " + Ident@76..83 "country" + Ascii44@83..84 "," + Whitespace@84..85 " " + ResTarget@85..164 + SubLink@85..149 + SelectStmt@85..149 + Ascii40@85..86 "(" + Select@86..92 "SELECT" + Whitespace@92..93 " " + ResTarget@93..105 + FuncCall@93..105 + Ident@93..96 "avg" + Ascii40@96..97 "(" + ColumnRef@97..105 + Ident@97..98 "r" + Ascii46@98..99 "." + Ident@99..105 "rating" + Ascii41@105..106 ")" + Whitespace@106..107 " " + From@107..111 "FROM" + Whitespace@111..112 " " + RangeVar@112..126 + Ident@112..124 "user_ratings" + Whitespace@124..125 " " + Alias@125..126 + Ident@125..126 "r" + Whitespace@126..127 " " + Where@127..132 "WHERE" + Whitespace@132..133 " " + AExpr@133..149 + ColumnRef@133..142 + Ident@133..134 "r" + Ascii46@134..135 "." + Ident@135..142 "film_id" + Whitespace@142..143 " " + Ascii61@143..144 "=" + Whitespace@144..145 " " + ColumnRef@145..149 + Ident@145..146 "f" + Ascii46@146..147 "." + Ident@147..149 "id" + Ascii41@149..150 ")" + Whitespace@150..151 " " + As@151..153 "AS" + Whitespace@153..154 " " + Ident@154..164 "avg_rating" + Whitespace@164..165 " " + From@165..169 "FROM" + Whitespace@169..170 " " + RangeVar@170..177 + Ident@170..175 "films" + Whitespace@175..176 " " + Alias@176..177 + Ident@176..177 "f" + Whitespace@177..178 " " + Where@178..183 "WHERE" + Whitespace@183..184 " " + AExpr@184..201 + ColumnRef@184..190 + Ident@184..185 "f" + Ascii46@185..186 "." + Ident@186..190 "kind" + Whitespace@190..191 " " + Ascii61@191..192 "=" + Whitespace@192..193 " " + AConst@193..201 + Sconst@193..201 "'Comedy'" + Ascii59@201..202 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@1.snap b/crates/pg_syntax/tests/snapshots/data/0046@1.snap new file mode 100644 index 00000000..8c6d568c --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@1.snap @@ -0,0 +1,12 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE TYPE type1; +--- +DefineStmt@0..18 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Ascii59@17..18 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@2.snap b/crates/pg_syntax/tests/snapshots/data/0046@2.snap new file mode 100644 index 00000000..239c104f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@2.snap @@ -0,0 +1,30 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE type1 AS (attr1 int4, attr2 bool);" +--- +CompositeTypeStmt@0..46 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + RangeVar@12..17 + Ident@12..17 "type1" + Whitespace@17..18 " " + As@18..20 "AS" + Whitespace@20..21 " " + Ascii40@21..22 "(" + ColumnDef@22..32 + Ident@22..27 "attr1" + Whitespace@27..28 " " + TypeName@28..32 + Ident@28..32 "int4" + Ascii44@32..33 "," + Whitespace@33..34 " " + ColumnDef@34..44 + Ident@34..39 "attr2" + Whitespace@39..40 " " + TypeName@40..44 + Ident@40..44 "bool" + Ascii41@44..45 ")" + Ascii59@45..46 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@4.snap b/crates/pg_syntax/tests/snapshots/data/0046@4.snap new file mode 100644 index 00000000..a132fa05 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@4.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE type1 AS ENUM ('value1', 'value2', 'value3');" +--- +CreateEnumStmt@0..57 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Whitespace@17..18 " " + As@18..20 "AS" + Whitespace@20..21 " " + EnumP@21..25 "ENUM" + Whitespace@25..26 " " + Ascii40@26..27 "(" + Sconst@27..35 "'value1'" + Ascii44@35..36 "," + Whitespace@36..37 " " + Sconst@37..45 "'value2'" + Ascii44@45..46 "," + Whitespace@46..47 " " + Sconst@47..55 "'value3'" + Ascii41@55..56 ")" + Ascii59@56..57 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@5.snap b/crates/pg_syntax/tests/snapshots/data/0046@5.snap new file mode 100644 index 00000000..4c4ca388 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@5.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE TYPE type1 AS RANGE (subtype = int4); +--- +CreateRangeStmt@0..44 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Whitespace@17..18 " " + As@18..20 "AS" + Whitespace@20..21 " " + Range@21..26 "RANGE" + Whitespace@26..27 " " + Ascii40@27..28 "(" + DefElem@28..42 + Ident@28..35 "subtype" + Whitespace@35..36 " " + Ascii61@36..37 "=" + Whitespace@37..38 " " + TypeName@38..42 + Ident@38..42 "int4" + Ascii41@42..43 ")" + Ascii59@43..44 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@6.snap b/crates/pg_syntax/tests/snapshots/data/0046@6.snap new file mode 100644 index 00000000..ce3eaaab --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@6.snap @@ -0,0 +1,39 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE type1 AS RANGE (subtype = int4, receive = receive_func, passedbyvalue);" +--- +CreateRangeStmt@0..83 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Whitespace@17..18 " " + As@18..20 "AS" + Whitespace@20..21 " " + Range@21..26 "RANGE" + Whitespace@26..27 " " + Ascii40@27..28 "(" + DefElem@28..42 + Ident@28..35 "subtype" + Whitespace@35..36 " " + Ascii61@36..37 "=" + Whitespace@37..38 " " + TypeName@38..42 + Ident@38..42 "int4" + Ascii44@42..43 "," + Whitespace@43..44 " " + DefElem@44..66 + Ident@44..51 "receive" + Whitespace@51..52 " " + Ascii61@52..53 "=" + Whitespace@53..54 " " + TypeName@54..66 + Ident@54..66 "receive_func" + Ascii44@66..67 "," + Whitespace@67..68 " " + DefElem@68..81 + Ident@68..81 "passedbyvalue" + Ascii41@81..82 ")" + Ascii59@82..83 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@7.snap b/crates/pg_syntax/tests/snapshots/data/0046@7.snap new file mode 100644 index 00000000..4422b755 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@7.snap @@ -0,0 +1,31 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE type1 (input = input1, output = output1);" +--- +DefineStmt@0..53 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Whitespace@17..18 " " + Ascii40@18..19 "(" + DefElem@19..33 + InputP@19..24 "input" + Whitespace@24..25 " " + Ascii61@25..26 "=" + Whitespace@26..27 " " + TypeName@27..33 + Ident@27..33 "input1" + Ascii44@33..34 "," + Whitespace@34..35 " " + DefElem@35..51 + Ident@35..41 "output" + Whitespace@41..42 " " + Ascii61@42..43 "=" + Whitespace@43..44 " " + TypeName@44..51 + Ident@44..51 "output1" + Ascii41@51..52 ")" + Ascii59@52..53 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0046@8.snap b/crates/pg_syntax/tests/snapshots/data/0046@8.snap new file mode 100644 index 00000000..c7ccaeee --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0046@8.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TYPE type1 (input = input1, output = output1, passedbyvalue);" +--- +DefineStmt@0..68 + Create@0..6 "CREATE" + Whitespace@6..7 " " + TypeP@7..11 "TYPE" + Whitespace@11..12 " " + Ident@12..17 "type1" + Whitespace@17..18 " " + Ascii40@18..19 "(" + DefElem@19..33 + InputP@19..24 "input" + Whitespace@24..25 " " + Ascii61@25..26 "=" + Whitespace@26..27 " " + TypeName@27..33 + Ident@27..33 "input1" + Ascii44@33..34 "," + Whitespace@34..35 " " + DefElem@35..51 + Ident@35..41 "output" + Whitespace@41..42 " " + Ascii61@42..43 "=" + Whitespace@43..44 " " + TypeName@44..51 + Ident@44..51 "output1" + Ascii44@51..52 "," + Whitespace@52..53 " " + DefElem@53..66 + Ident@53..66 "passedbyvalue" + Ascii41@66..67 ")" + Ascii59@67..68 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@1.snap b/crates/pg_syntax/tests/snapshots/data/0047@1.snap new file mode 100644 index 00000000..1722a226 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@1.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE DATABASE x OWNER abc CONNECTION LIMIT 5; +--- +CreatedbStmt@0..47 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..27 + Owner@18..23 "OWNER" + Whitespace@23..24 " " + Ident@24..27 "abc" + Whitespace@27..28 " " + DefElem@28..46 + Connection@28..38 "CONNECTION" + Whitespace@38..39 " " + Limit@39..44 "LIMIT" + Whitespace@44..45 " " + Iconst@45..46 "5" + Ascii59@46..47 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@2.snap b/crates/pg_syntax/tests/snapshots/data/0047@2.snap new file mode 100644 index 00000000..51deb3d3 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@2.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE DATABASE x ENCODING \"SQL_ASCII\";" +--- +CreatedbStmt@0..39 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..38 + Encoding@18..26 "ENCODING" + Whitespace@26..27 " " + Ident@27..38 "\"SQL_ASCII\"" + Ascii59@38..39 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@3.snap b/crates/pg_syntax/tests/snapshots/data/0047@3.snap new file mode 100644 index 00000000..722053ab --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@3.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE DATABASE x LC_COLLATE \"en_US.UTF-8\";" +--- +CreatedbStmt@0..43 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..42 + Ident@18..28 "LC_COLLATE" + Whitespace@28..29 " " + Ident@29..42 "\"en_US.UTF-8\"" + Ascii59@42..43 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@4.snap b/crates/pg_syntax/tests/snapshots/data/0047@4.snap new file mode 100644 index 00000000..77fd4d9d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@4.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE DATABASE x LOCATION DEFAULT; +--- +CreatedbStmt@0..35 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..34 + Location@18..26 "LOCATION" + Whitespace@26..27 " " + Default@27..34 "DEFAULT" + Ascii59@34..35 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@5.snap b/crates/pg_syntax/tests/snapshots/data/0047@5.snap new file mode 100644 index 00000000..c66afef2 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@5.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE DATABASE x TABLESPACE abc; +--- +CreatedbStmt@0..33 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..32 + Tablespace@18..28 "TABLESPACE" + Whitespace@28..29 " " + Ident@29..32 "abc" + Ascii59@32..33 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0047@6.snap b/crates/pg_syntax/tests/snapshots/data/0047@6.snap new file mode 100644 index 00000000..1332b3b9 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0047@6.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE DATABASE x TEMPLATE TRUE; +--- +CreatedbStmt@0..32 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Database@7..15 "DATABASE" + Whitespace@15..16 " " + Ident@16..17 "x" + Whitespace@17..18 " " + DefElem@18..31 + Template@18..26 "TEMPLATE" + Whitespace@26..27 " " + TrueP@27..31 "TRUE" + Ascii59@31..32 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0048@1.snap b/crates/pg_syntax/tests/snapshots/data/0048@1.snap new file mode 100644 index 00000000..198bb5a4 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0048@1.snap @@ -0,0 +1,16 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLESPACE x LOCATION 'a';" +--- +CreateTableSpaceStmt@0..33 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Tablespace@7..17 "TABLESPACE" + Whitespace@17..18 " " + Ident@18..19 "x" + Whitespace@19..20 " " + Location@20..28 "LOCATION" + Whitespace@28..29 " " + Sconst@29..32 "'a'" + Ascii59@32..33 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0048@2.snap b/crates/pg_syntax/tests/snapshots/data/0048@2.snap new file mode 100644 index 00000000..a6f44bcf --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0048@2.snap @@ -0,0 +1,36 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TABLESPACE x OWNER a LOCATION 'b' WITH (random_page_cost=42, seq_page_cost=3);" +--- +CreateTableSpaceStmt@0..85 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Tablespace@7..17 "TABLESPACE" + Whitespace@17..18 " " + Ident@18..19 "x" + Whitespace@19..20 " " + Owner@20..25 "OWNER" + Whitespace@25..26 " " + RoleSpec@26..27 + Ident@26..27 "a" + Whitespace@27..28 " " + Location@28..36 "LOCATION" + Whitespace@36..37 " " + Sconst@37..40 "'b'" + Whitespace@40..41 " " + With@41..45 "WITH" + Whitespace@45..46 " " + Ascii40@46..47 "(" + DefElem@47..66 + Ident@47..63 "random_page_cost" + Ascii61@63..64 "=" + Iconst@64..66 "42" + Ascii44@66..67 "," + Whitespace@67..68 " " + DefElem@68..83 + Ident@68..81 "seq_page_cost" + Ascii61@81..82 "=" + Iconst@82..83 "3" + Ascii41@83..84 ")" + Ascii59@84..85 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0049@1.snap b/crates/pg_syntax/tests/snapshots/data/0049@1.snap new file mode 100644 index 00000000..e9b86aab --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0049@1.snap @@ -0,0 +1,12 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE EXTENSION x; +--- +CreateExtensionStmt@0..19 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Extension@7..16 "EXTENSION" + Whitespace@16..17 " " + Ident@17..18 "x" + Ascii59@18..19 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0049@2.snap b/crates/pg_syntax/tests/snapshots/data/0049@2.snap new file mode 100644 index 00000000..307757bf --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0049@2.snap @@ -0,0 +1,31 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE EXTENSION IF NOT EXISTS x CASCADE VERSION \"1.2\" SCHEMA a;" +--- +CreateExtensionStmt@0..64 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Extension@7..16 "EXTENSION" + Whitespace@16..17 " " + IfP@17..19 "IF" + Whitespace@19..20 " " + Not@20..23 "NOT" + Whitespace@23..24 " " + Exists@24..30 "EXISTS" + Whitespace@30..31 " " + Ident@31..32 "x" + Whitespace@32..33 " " + DefElem@33..40 + Cascade@33..40 "CASCADE" + Whitespace@40..41 " " + DefElem@41..54 + VersionP@41..48 "VERSION" + Whitespace@48..49 " " + Ident@49..54 "\"1.2\"" + Whitespace@54..55 " " + DefElem@55..63 + Schema@55..61 "SCHEMA" + Whitespace@61..62 " " + Ident@62..63 "a" + Ascii59@63..64 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@1.snap b/crates/pg_syntax/tests/snapshots/data/0051@1.snap new file mode 100644 index 00000000..aa1caca9 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@1.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE UNIQUE INDEX title_idx ON films (title); +--- +IndexStmt@0..47 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Unique@7..13 "UNIQUE" + Whitespace@13..14 " " + Index@14..19 "INDEX" + Whitespace@19..20 " " + Ident@20..29 "title_idx" + Whitespace@29..30 " " + On@30..32 "ON" + Whitespace@32..33 " " + RangeVar@33..38 + Ident@33..38 "films" + Whitespace@38..39 " " + Ascii40@39..40 "(" + IndexElem@40..45 + Ident@40..45 "title" + Ascii41@45..46 ")" + Ascii59@46..47 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@10.snap b/crates/pg_syntax/tests/snapshots/data/0051@10.snap new file mode 100644 index 00000000..aba2ea95 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@10.snap @@ -0,0 +1,34 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE INDEX pointloc ON points USING gist (box(location,location));" +--- +IndexStmt@0..68 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..21 "pointloc" + Whitespace@21..22 " " + On@22..24 "ON" + Whitespace@24..25 " " + RangeVar@25..31 + Ident@25..31 "points" + Whitespace@31..32 " " + Using@32..37 "USING" + Whitespace@37..38 " " + Ident@38..42 "gist" + Whitespace@42..43 " " + Ascii40@43..44 "(" + IndexElem@44..65 + FuncCall@44..65 + Ident@44..47 "box" + Ascii40@47..48 "(" + ColumnRef@48..56 + Location@48..56 "location" + Ascii44@56..57 "," + ColumnRef@57..65 + Location@57..65 "location" + Ascii41@65..66 ")" + Ascii41@66..67 ")" + Ascii59@67..68 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@11.snap b/crates/pg_syntax/tests/snapshots/data/0051@11.snap new file mode 100644 index 00000000..9e016565 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@11.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity); +--- +IndexStmt@0..73 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Concurrently@13..25 "CONCURRENTLY" + Whitespace@25..26 " " + Ident@26..46 "sales_quantity_index" + Whitespace@46..47 " " + On@47..49 "ON" + Whitespace@49..50 " " + RangeVar@50..61 + Ident@50..61 "sales_table" + Whitespace@61..62 " " + Ascii40@62..63 "(" + IndexElem@63..71 + Ident@63..71 "quantity" + Ascii41@71..72 ")" + Ascii59@72..73 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@2.snap b/crates/pg_syntax/tests/snapshots/data/0051@2.snap new file mode 100644 index 00000000..b2b5d71d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@2.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);" +--- +IndexStmt@0..74 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Unique@7..13 "UNIQUE" + Whitespace@13..14 " " + Index@14..19 "INDEX" + Whitespace@19..20 " " + Ident@20..29 "title_idx" + Whitespace@29..30 " " + On@30..32 "ON" + Whitespace@32..33 " " + RangeVar@33..38 + Ident@33..38 "films" + Whitespace@38..39 " " + Ascii40@39..40 "(" + IndexElem@40..45 + Ident@40..45 "title" + Ascii41@45..46 ")" + Whitespace@46..47 " " + Include@47..54 "INCLUDE" + Whitespace@54..55 " " + Ascii40@55..56 "(" + IndexElem@56..64 + Ident@56..64 "director" + Ascii44@64..65 "," + Whitespace@65..66 " " + IndexElem@66..72 + Ident@66..72 "rating" + Ascii41@72..73 ")" + Ascii59@73..74 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@3.snap b/crates/pg_syntax/tests/snapshots/data/0051@3.snap new file mode 100644 index 00000000..d906b6f4 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@3.snap @@ -0,0 +1,34 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off); +--- +IndexStmt@0..71 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..22 "title_idx" + Whitespace@22..23 " " + On@23..25 "ON" + Whitespace@25..26 " " + RangeVar@26..31 + Ident@26..31 "films" + Whitespace@31..32 " " + Ascii40@32..33 "(" + IndexElem@33..38 + Ident@33..38 "title" + Ascii41@38..39 ")" + Whitespace@39..40 " " + With@40..44 "WITH" + Whitespace@44..45 " " + Ascii40@45..46 "(" + DefElem@46..69 + Ident@46..63 "deduplicate_items" + Whitespace@63..64 " " + Ascii61@64..65 "=" + Whitespace@65..66 " " + TypeName@66..69 + Off@66..69 "off" + Ascii41@69..70 ")" + Ascii59@70..71 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@4.snap b/crates/pg_syntax/tests/snapshots/data/0051@4.snap new file mode 100644 index 00000000..17b3ea3f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@4.snap @@ -0,0 +1,27 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX ON films ((lower(title))); +--- +IndexStmt@0..39 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + On@13..15 "ON" + Whitespace@15..16 " " + RangeVar@16..21 + Ident@16..21 "films" + Whitespace@21..22 " " + Ascii40@22..23 "(" + Ascii40@23..24 "(" + IndexElem@24..35 + FuncCall@24..35 + Ident@24..29 "lower" + Ascii40@29..30 "(" + ColumnRef@30..35 + Ident@30..35 "title" + Ascii41@35..36 ")" + Ascii41@36..37 ")" + Ascii41@37..38 ")" + Ascii59@38..39 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@5.snap b/crates/pg_syntax/tests/snapshots/data/0051@5.snap new file mode 100644 index 00000000..bdffe04e --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@5.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE INDEX title_idx_german ON films (title COLLATE \"de_DE\");" +--- +IndexStmt@0..63 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..29 "title_idx_german" + Whitespace@29..30 " " + On@30..32 "ON" + Whitespace@32..33 " " + RangeVar@33..38 + Ident@33..38 "films" + Whitespace@38..39 " " + Ascii40@39..40 "(" + IndexElem@40..61 + Ident@40..45 "title" + Whitespace@45..46 " " + Collate@46..53 "COLLATE" + Whitespace@53..54 " " + Ident@54..61 "\"de_DE\"" + Ascii41@61..62 ")" + Ascii59@62..63 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@6.snap b/crates/pg_syntax/tests/snapshots/data/0051@6.snap new file mode 100644 index 00000000..a34569e0 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@6.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST); +--- +IndexStmt@0..62 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..32 "title_idx_nulls_low" + Whitespace@32..33 " " + On@33..35 "ON" + Whitespace@35..36 " " + RangeVar@36..41 + Ident@36..41 "films" + Whitespace@41..42 " " + Ascii40@42..43 "(" + IndexElem@43..60 + Ident@43..48 "title" + Whitespace@48..49 " " + NullsP@49..54 "NULLS" + Whitespace@54..55 " " + FirstP@55..60 "FIRST" + Ascii41@60..61 ")" + Ascii59@61..62 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@7.snap b/crates/pg_syntax/tests/snapshots/data/0051@7.snap new file mode 100644 index 00000000..ad884c6f --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@7.snap @@ -0,0 +1,35 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70); +--- +IndexStmt@0..70 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Unique@7..13 "UNIQUE" + Whitespace@13..14 " " + Index@14..19 "INDEX" + Whitespace@19..20 " " + Ident@20..29 "title_idx" + Whitespace@29..30 " " + On@30..32 "ON" + Whitespace@32..33 " " + RangeVar@33..38 + Ident@33..38 "films" + Whitespace@38..39 " " + Ascii40@39..40 "(" + IndexElem@40..45 + Ident@40..45 "title" + Ascii41@45..46 ")" + Whitespace@46..47 " " + With@47..51 "WITH" + Whitespace@51..52 " " + Ascii40@52..53 "(" + DefElem@53..68 + Ident@53..63 "fillfactor" + Whitespace@63..64 " " + Ascii61@64..65 "=" + Whitespace@65..66 " " + Iconst@66..68 "70" + Ascii41@68..69 ")" + Ascii59@69..70 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@8.snap b/crates/pg_syntax/tests/snapshots/data/0051@8.snap new file mode 100644 index 00000000..20de1d06 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@8.snap @@ -0,0 +1,38 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off); +--- +IndexStmt@0..86 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..20 "gin_idx" + Whitespace@20..21 " " + On@21..23 "ON" + Whitespace@23..24 " " + RangeVar@24..39 + Ident@24..39 "documents_table" + Whitespace@39..40 " " + Using@40..45 "USING" + Whitespace@45..46 " " + Ident@46..49 "GIN" + Whitespace@49..50 " " + Ascii40@50..51 "(" + IndexElem@51..60 + Ident@51..60 "locations" + Ascii41@60..61 ")" + Whitespace@61..62 " " + With@62..66 "WITH" + Whitespace@66..67 " " + Ascii40@67..68 "(" + DefElem@68..84 + Ident@68..78 "fastupdate" + Whitespace@78..79 " " + Ascii61@79..80 "=" + Whitespace@80..81 " " + TypeName@81..84 + Off@81..84 "off" + Ascii41@84..85 ")" + Ascii59@85..86 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0051@9.snap b/crates/pg_syntax/tests/snapshots/data/0051@9.snap new file mode 100644 index 00000000..b78e5c34 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0051@9.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE INDEX code_idx ON films (code) TABLESPACE indexspace; +--- +IndexStmt@0..60 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Index@7..12 "INDEX" + Whitespace@12..13 " " + Ident@13..21 "code_idx" + Whitespace@21..22 " " + On@22..24 "ON" + Whitespace@24..25 " " + RangeVar@25..30 + Ident@25..30 "films" + Whitespace@30..31 " " + Ascii40@31..32 "(" + IndexElem@32..36 + Ident@32..36 "code" + Ascii41@36..37 ")" + Whitespace@37..38 " " + Tablespace@38..48 "TABLESPACE" + Whitespace@48..49 " " + Ident@49..59 "indexspace" + Ascii59@59..60 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0052@1.snap b/crates/pg_syntax/tests/snapshots/data/0052@1.snap new file mode 100644 index 00000000..35277c77 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0052@1.snap @@ -0,0 +1,37 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b);$$;" +--- +CreateFunctionStmt@0..127 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Procedure@7..16 "PROCEDURE" + Whitespace@16..17 " " + Ident@17..28 "insert_data" + Ascii40@28..29 "(" + FunctionParameter@29..38 + Ident@29..30 "a" + Whitespace@30..31 " " + TypeName@31..38 + Integer@31..38 "integer" + Ascii44@38..39 "," + Whitespace@39..40 " " + FunctionParameter@40..49 + Ident@40..41 "b" + Whitespace@41..42 " " + TypeName@42..49 + Integer@42..49 "integer" + Ascii41@49..50 ")" + Whitespace@50..51 " " + DefElem@51..63 + Language@51..59 "LANGUAGE" + Whitespace@59..60 " " + SqlP@60..63 "SQL" + Whitespace@63..64 " " + DefElem@64..126 + As@64..66 "AS" + Whitespace@66..67 " " + List@67..126 + Sconst@67..126 "$$INSERT INTO tbl VAL ..." + Ascii59@126..127 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@1.snap b/crates/pg_syntax/tests/snapshots/data/0053@1.snap new file mode 100644 index 00000000..ec36c719 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@1.snap @@ -0,0 +1,27 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PUBLICATION mypublication FOR TABLE users, departments;" +--- +CreatePublicationStmt@0..62 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..32 "mypublication" + Whitespace@32..33 " " + For@33..36 "FOR" + Whitespace@36..37 " " + Table@37..42 "TABLE" + Whitespace@42..43 " " + PublicationObjSpec@43..48 + PublicationTable@43..48 + RangeVar@43..48 + Ident@43..48 "users" + Ascii44@48..49 "," + Whitespace@49..50 " " + PublicationObjSpec@50..61 + PublicationTable@50..61 + RangeVar@50..61 + Ident@50..61 "departments" + Ascii59@61..62 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@2.snap b/crates/pg_syntax/tests/snapshots/data/0053@2.snap new file mode 100644 index 00000000..af2529cc --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@2.snap @@ -0,0 +1,33 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE); +--- +CreatePublicationStmt@0..83 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..37 "active_departments" + Whitespace@37..38 " " + For@38..41 "FOR" + Whitespace@41..42 " " + Table@42..47 "TABLE" + Whitespace@47..48 " " + PublicationObjSpec@48..81 + PublicationTable@48..81 + RangeVar@48..59 + Ident@48..59 "departments" + Whitespace@59..60 " " + Where@60..65 "WHERE" + Whitespace@65..66 " " + Ascii40@66..67 "(" + BooleanTest@67..81 + ColumnRef@67..73 + Ident@67..73 "active" + Whitespace@73..74 " " + Is@74..76 "IS" + Whitespace@76..77 " " + TrueP@77..81 "TRUE" + Ascii41@81..82 ")" + Ascii59@82..83 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@3.snap b/crates/pg_syntax/tests/snapshots/data/0053@3.snap new file mode 100644 index 00000000..e4d5a7e0 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@3.snap @@ -0,0 +1,18 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: CREATE PUBLICATION alltables FOR ALL TABLES; +--- +CreatePublicationStmt@0..44 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..28 "alltables" + Whitespace@28..29 " " + For@29..32 "FOR" + Whitespace@32..33 " " + All@33..36 "ALL" + Whitespace@36..37 " " + Tables@37..43 "TABLES" + Ascii59@43..44 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@4.snap b/crates/pg_syntax/tests/snapshots/data/0053@4.snap new file mode 100644 index 00000000..4e54a678 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@4.snap @@ -0,0 +1,32 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PUBLICATION insert_only FOR TABLE mydata WITH (publish = 'insert');" +--- +CreatePublicationStmt@0..74 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..30 "insert_only" + Whitespace@30..31 " " + For@31..34 "FOR" + Whitespace@34..35 " " + Table@35..40 "TABLE" + Whitespace@40..41 " " + PublicationObjSpec@41..47 + PublicationTable@41..47 + RangeVar@41..47 + Ident@41..47 "mydata" + Whitespace@47..48 " " + With@48..52 "WITH" + Whitespace@52..53 " " + Ascii40@53..54 "(" + DefElem@54..72 + Ident@54..61 "publish" + Whitespace@61..62 " " + Ascii61@62..63 "=" + Whitespace@63..64 " " + Sconst@64..72 "'insert'" + Ascii41@72..73 ")" + Ascii59@73..74 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@5.snap b/crates/pg_syntax/tests/snapshots/data/0053@5.snap new file mode 100644 index 00000000..bc175999 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@5.snap @@ -0,0 +1,37 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;" +--- +CreatePublicationStmt@0..100 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..41 "production_publication" + Whitespace@41..42 " " + For@42..45 "FOR" + Whitespace@45..46 " " + Table@46..51 "TABLE" + Whitespace@51..52 " " + PublicationObjSpec@52..57 + PublicationTable@52..57 + RangeVar@52..57 + Ident@52..57 "users" + Ascii44@57..58 "," + Whitespace@58..59 " " + PublicationObjSpec@59..70 + PublicationTable@59..70 + RangeVar@59..70 + Ident@59..70 "departments" + Ascii44@70..71 "," + Whitespace@71..72 " " + Tables@72..78 "TABLES" + Whitespace@78..79 " " + InP@79..81 "IN" + Whitespace@81..82 " " + Schema@82..88 "SCHEMA" + Whitespace@88..89 " " + PublicationObjSpec@89..99 + Ident@89..99 "production" + Ascii59@99..100 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@6.snap b/crates/pg_syntax/tests/snapshots/data/0053@6.snap new file mode 100644 index 00000000..0e30fdee --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@6.snap @@ -0,0 +1,27 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;" +--- +CreatePublicationStmt@0..75 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..36 "sales_publication" + Whitespace@36..37 " " + For@37..40 "FOR" + Whitespace@40..41 " " + Tables@41..47 "TABLES" + Whitespace@47..48 " " + InP@48..50 "IN" + Whitespace@50..51 " " + Schema@51..57 "SCHEMA" + Whitespace@57..58 " " + PublicationObjSpec@58..67 + Ident@58..67 "marketing" + Ascii44@67..68 "," + Whitespace@68..69 " " + PublicationObjSpec@69..74 + Ident@69..74 "sales" + Ascii59@74..75 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0053@7.snap b/crates/pg_syntax/tests/snapshots/data/0053@7.snap new file mode 100644 index 00000000..54e47703 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0053@7.snap @@ -0,0 +1,28 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);" +--- +CreatePublicationStmt@0..71 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Publication@7..18 "PUBLICATION" + Whitespace@18..19 " " + Ident@19..33 "users_filtered" + Whitespace@33..34 " " + For@34..37 "FOR" + Whitespace@37..38 " " + Table@38..43 "TABLE" + Whitespace@43..44 " " + PublicationObjSpec@44..69 + PublicationTable@44..69 + RangeVar@44..49 + Ident@44..49 "users" + Whitespace@49..50 " " + Ascii40@50..51 "(" + Ident@51..58 "user_id" + Ascii44@58..59 "," + Whitespace@59..60 " " + Ident@60..69 "firstname" + Ascii41@69..70 ")" + Ascii59@70..71 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0054@1.snap b/crates/pg_syntax/tests/snapshots/data/0054@1.snap new file mode 100644 index 00000000..4259b54d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0054@1.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" +--- +CreateConversionStmt@0..60 + Create@0..6 "CREATE" + Whitespace@6..7 " " + ConversionP@7..17 "CONVERSION" + Whitespace@17..18 " " + Ident@18..24 "myconv" + Whitespace@24..25 " " + For@25..28 "FOR" + Whitespace@28..29 " " + Sconst@29..35 "'UTF8'" + Whitespace@35..36 " " + To@36..38 "TO" + Whitespace@38..39 " " + Sconst@39..47 "'LATIN1'" + Whitespace@47..48 " " + From@48..52 "FROM" + Whitespace@52..53 " " + Ident@53..59 "myfunc" + Ascii59@59..60 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0054@2.snap b/crates/pg_syntax/tests/snapshots/data/0054@2.snap new file mode 100644 index 00000000..ce4fdeec --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0054@2.snap @@ -0,0 +1,26 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" +--- +CreateConversionStmt@0..68 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Default@7..14 "DEFAULT" + Whitespace@14..15 " " + ConversionP@15..25 "CONVERSION" + Whitespace@25..26 " " + Ident@26..32 "myconv" + Whitespace@32..33 " " + For@33..36 "FOR" + Whitespace@36..37 " " + Sconst@37..43 "'UTF8'" + Whitespace@43..44 " " + To@44..46 "TO" + Whitespace@46..47 " " + Sconst@47..55 "'LATIN1'" + Whitespace@55..56 " " + From@56..60 "FROM" + Whitespace@60..61 " " + Ident@61..67 "myfunc" + Ascii59@67..68 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0055@1.snap b/crates/pg_syntax/tests/snapshots/data/0055@1.snap new file mode 100644 index 00000000..3584f630 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0055@1.snap @@ -0,0 +1,24 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: select 1 union all select 2; +--- +SelectStmt@0..28 + Select@0..6 "select" + Whitespace@6..7 " " + SelectStmt@7..8 + ResTarget@7..8 + AConst@7..8 + Iconst@7..8 "1" + Whitespace@8..9 " " + Union@9..14 "union" + Whitespace@14..15 " " + All@15..18 "all" + Whitespace@18..19 " " + SelectStmt@19..27 + Select@19..25 "select" + Whitespace@25..26 " " + ResTarget@26..27 + AConst@26..27 + Iconst@26..27 "2" + Ascii59@27..28 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0055@2.snap b/crates/pg_syntax/tests/snapshots/data/0055@2.snap new file mode 100644 index 00000000..e1172033 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0055@2.snap @@ -0,0 +1,22 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: select 1 union select 2; +--- +SelectStmt@0..24 + Select@0..6 "select" + Whitespace@6..7 " " + SelectStmt@7..8 + ResTarget@7..8 + AConst@7..8 + Iconst@7..8 "1" + Whitespace@8..9 " " + Union@9..14 "union" + Whitespace@14..15 " " + SelectStmt@15..23 + Select@15..21 "select" + Whitespace@21..22 " " + ResTarget@22..23 + AConst@22..23 + Iconst@22..23 "2" + Ascii59@23..24 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0056@1.snap b/crates/pg_syntax/tests/snapshots/data/0056@1.snap new file mode 100644 index 00000000..65ba58ac --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0056@1.snap @@ -0,0 +1,56 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE TRANSFORM FOR hstore LANGUAGE plpython3u (\n FROM SQL WITH FUNCTION hstore_to_plpython(internal),\n TO SQL WITH FUNCTION plpython_to_hstore(internal)\n);" +--- +CreateTransformStmt@0..163 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Transform@7..16 "TRANSFORM" + Whitespace@16..17 " " + For@17..20 "FOR" + Whitespace@20..21 " " + TypeName@21..27 + Ident@21..27 "hstore" + Whitespace@27..28 " " + Language@28..36 "LANGUAGE" + Whitespace@36..37 " " + Ident@37..47 "plpython3u" + Whitespace@47..48 " " + Ascii40@48..49 "(" + Newline@49..50 "\n" + Whitespace@50..54 " " + From@54..58 "FROM" + Whitespace@58..59 " " + SqlP@59..62 "SQL" + Whitespace@62..63 " " + With@63..67 "WITH" + Whitespace@67..68 " " + Function@68..76 "FUNCTION" + Whitespace@76..77 " " + ObjectWithArgs@77..107 + Ident@77..95 "hstore_to_plpython" + Ascii40@95..96 "(" + TypeName@96..104 + Ident@96..104 "internal" + Ascii41@104..105 ")" + Ascii44@105..106 "," + Newline@106..107 "\n" + Whitespace@107..111 " " + To@111..113 "TO" + Whitespace@113..114 " " + SqlP@114..117 "SQL" + Whitespace@117..118 " " + With@118..122 "WITH" + Whitespace@122..123 " " + Function@123..131 "FUNCTION" + Whitespace@131..132 " " + ObjectWithArgs@132..163 + Ident@132..150 "plpython_to_hstore" + Ascii40@150..151 "(" + TypeName@151..159 + Ident@151..159 "internal" + Ascii41@159..160 ")" + Newline@160..161 "\n" + Ascii41@161..162 ")" + Ascii59@162..163 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0056@2.snap b/crates/pg_syntax/tests/snapshots/data/0056@2.snap new file mode 100644 index 00000000..677d332a --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0056@2.snap @@ -0,0 +1,60 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: "CREATE OR REPLACE TRANSFORM FOR hstore LANGUAGE plpython3u (\n FROM SQL WITH FUNCTION hstore_to_plpython(internal),\n TO SQL WITH FUNCTION plpython_to_hstore(internal)\n);" +--- +CreateTransformStmt@0..174 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Or@7..9 "OR" + Whitespace@9..10 " " + Replace@10..17 "REPLACE" + Whitespace@17..18 " " + Transform@18..27 "TRANSFORM" + Whitespace@27..28 " " + For@28..31 "FOR" + Whitespace@31..32 " " + TypeName@32..38 + Ident@32..38 "hstore" + Whitespace@38..39 " " + Language@39..47 "LANGUAGE" + Whitespace@47..48 " " + Ident@48..58 "plpython3u" + Whitespace@58..59 " " + Ascii40@59..60 "(" + Newline@60..61 "\n" + Whitespace@61..65 " " + From@65..69 "FROM" + Whitespace@69..70 " " + SqlP@70..73 "SQL" + Whitespace@73..74 " " + With@74..78 "WITH" + Whitespace@78..79 " " + Function@79..87 "FUNCTION" + Whitespace@87..88 " " + ObjectWithArgs@88..118 + Ident@88..106 "hstore_to_plpython" + Ascii40@106..107 "(" + TypeName@107..115 + Ident@107..115 "internal" + Ascii41@115..116 ")" + Ascii44@116..117 "," + Newline@117..118 "\n" + Whitespace@118..122 " " + To@122..124 "TO" + Whitespace@124..125 " " + SqlP@125..128 "SQL" + Whitespace@128..129 " " + With@129..133 "WITH" + Whitespace@133..134 " " + Function@134..142 "FUNCTION" + Whitespace@142..143 " " + ObjectWithArgs@143..174 + Ident@143..161 "plpython_to_hstore" + Ascii40@161..162 "(" + TypeName@162..170 + Ident@162..170 "internal" + Ascii41@170..171 ")" + Newline@171..172 "\n" + Ascii41@172..173 ")" + Ascii59@173..174 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@1.snap b/crates/pg_syntax/tests/snapshots/data/0057@1.snap new file mode 100644 index 00000000..27222365 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@1.snap @@ -0,0 +1,17 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE users CONTINUE IDENTITY RESTRICT; +--- +TruncateStmt@0..42 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + RangeVar@9..14 + Ident@9..14 "users" + Whitespace@14..15 " " + ContinueP@15..23 "CONTINUE" + Whitespace@23..24 " " + IdentityP@24..32 "IDENTITY" + Whitespace@32..33 " " + Restrict@33..41 "RESTRICT" + Ascii59@41..42 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@2.snap b/crates/pg_syntax/tests/snapshots/data/0057@2.snap new file mode 100644 index 00000000..a3b78e8d --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@2.snap @@ -0,0 +1,19 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE TABLE users RESTART IDENTITY CASCADE; +--- +TruncateStmt@0..46 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + Table@9..14 "TABLE" + Whitespace@14..15 " " + RangeVar@15..20 + Ident@15..20 "users" + Whitespace@20..21 " " + Restart@21..28 "RESTART" + Whitespace@28..29 " " + IdentityP@29..37 "IDENTITY" + Whitespace@37..38 " " + Cascade@38..45 "CASCADE" + Ascii59@45..46 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@3.snap b/crates/pg_syntax/tests/snapshots/data/0057@3.snap new file mode 100644 index 00000000..d317dd4b --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@3.snap @@ -0,0 +1,11 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE users; +--- +TruncateStmt@0..15 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + RangeVar@9..14 + Ident@9..14 "users" + Ascii59@14..15 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@4.snap b/crates/pg_syntax/tests/snapshots/data/0057@4.snap new file mode 100644 index 00000000..73f22275 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@4.snap @@ -0,0 +1,13 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE accounts CASCADE; +--- +TruncateStmt@0..26 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + RangeVar@9..17 + Ident@9..17 "accounts" + Whitespace@17..18 " " + Cascade@18..25 "CASCADE" + Ascii59@25..26 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@5.snap b/crates/pg_syntax/tests/snapshots/data/0057@5.snap new file mode 100644 index 00000000..180590de --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@5.snap @@ -0,0 +1,13 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE accounts RESTRICT; +--- +TruncateStmt@0..27 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + RangeVar@9..17 + Ident@9..17 "accounts" + Whitespace@17..18 " " + Restrict@18..26 "RESTRICT" + Ascii59@26..27 ";" + diff --git a/crates/pg_syntax/tests/snapshots/data/0057@6.snap b/crates/pg_syntax/tests/snapshots/data/0057@6.snap new file mode 100644 index 00000000..3d2cb600 --- /dev/null +++ b/crates/pg_syntax/tests/snapshots/data/0057@6.snap @@ -0,0 +1,13 @@ +--- +source: crates/pg_syntax/tests/pg_syntax_tests.rs +description: TRUNCATE TABLE users; +--- +TruncateStmt@0..21 + Truncate@0..8 "TRUNCATE" + Whitespace@8..9 " " + Table@9..14 "TABLE" + Whitespace@14..15 " " + RangeVar@15..20 + Ident@15..20 "users" + Ascii59@20..21 ";" + diff --git a/crates/pg_type_resolver/Cargo.toml b/crates/pg_type_resolver/Cargo.toml new file mode 100644 index 00000000..757c3e3b --- /dev/null +++ b/crates/pg_type_resolver/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "pg_type_resolver" +version = "0.0.0" +edition = "2021" + +[dependencies] +pg_query_ext.workspace = true +pg_schema_cache.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_type_resolver/src/functions.rs b/crates/pg_type_resolver/src/functions.rs new file mode 100644 index 00000000..39ab5268 --- /dev/null +++ b/crates/pg_type_resolver/src/functions.rs @@ -0,0 +1,95 @@ +use pg_schema_cache::{Function, SchemaCache}; + +use crate::{ + types::{resolve_type, PossibleType}, + util::get_string_from_node, +}; + +pub fn resolve_func_call<'a, 'b>( + node: &'a pg_query_ext::protobuf::FuncCall, + schema_cache: &'b SchemaCache, +) -> Option<&'b Function> { + let (schema, name) = resolve_func_identifier(node); + + let fns = schema_cache + .functions + .iter() + .filter(|f| { + function_matches( + f, + schema.as_ref().map(|s| s.as_str()), + name.as_str(), + node.args + .iter() + .map(|a| resolve_type(a.node.as_ref().unwrap(), schema_cache)) + .collect(), + ) + }) + .collect::>(); + + if fns.len() == 1 { + Some(fns[0]) + } else { + None + } +} + +fn resolve_func_identifier(node: &pg_query_ext::protobuf::FuncCall) -> (Option, String) { + match node.funcname.as_slice() { + [name] => (None, get_string_from_node(name)), + [schema, name] => ( + Some(get_string_from_node(schema)), + get_string_from_node(name), + ), + _ => panic!("Function name has more than 2 parts"), + } +} + +fn function_matches( + func: &Function, + schema: Option<&str>, + name: &str, + arg_types: Vec, +) -> bool { + if func.name.as_ref().map(|s| s.as_str()) != Some(name) { + return false; + } + + if schema.is_some() && func.schema.as_ref().map(|s| s.as_str()) != schema { + return false; + } + + let arg_count = arg_types.len(); + let args_with_default = func + .args + .args + .iter() + .filter(|a| a.has_default.is_some()) + .count(); + let total_args = func.args.args.len(); + + if total_args < arg_count || total_args - args_with_default > arg_count { + return false; + } + + for (i, (func_arg, possible_type)) in func.args.args.iter().zip(arg_types.iter()).enumerate() { + match possible_type { + PossibleType::Null => { + // can be any type + } + PossibleType::AnyOf(types) => { + if types + .iter() + .all(|type_id| type_id.to_owned() != func_arg.type_id) + { + return false; + } + } + } + + if i >= arg_count && !func_arg.has_default.unwrap_or(false) { + return false; + } + } + true +} diff --git a/crates/pg_type_resolver/src/lib.rs b/crates/pg_type_resolver/src/lib.rs new file mode 100644 index 00000000..ef8fdca6 --- /dev/null +++ b/crates/pg_type_resolver/src/lib.rs @@ -0,0 +1,5 @@ +mod functions; +mod types; +mod util; + +pub use functions::resolve_func_call; diff --git a/crates/pg_type_resolver/src/types.rs b/crates/pg_type_resolver/src/types.rs new file mode 100644 index 00000000..104f82a5 --- /dev/null +++ b/crates/pg_type_resolver/src/types.rs @@ -0,0 +1,85 @@ +use pg_schema_cache::SchemaCache; + +pub(crate) enum PossibleType { + Null, + AnyOf(Vec), +} + +pub fn resolve_type(node: &pg_query_ext::NodeEnum, schema_cache: &SchemaCache) -> PossibleType { + match node { + pg_query_ext::NodeEnum::AConst(n) => { + if n.isnull { + PossibleType::Null + } else { + match n + .val + .as_ref() + .expect("expected non-nullable AConst to have a value") + { + pg_query_ext::protobuf::a_const::Val::Ival(_) => { + let types: Vec = vec!["int2", "int4", "int8"] + .iter() + .map(|s| s.to_string()) + .collect(); + + PossibleType::AnyOf( + schema_cache + .types + .iter() + .filter(|t| { + types.iter().find(|i| i == &&t.name).is_some() + && t.schema == "pg_catalog" + }) + .map(|t| t.id) + .collect(), + ) + } + pg_query_ext::protobuf::a_const::Val::Fval(_) => { + let types: Vec = vec!["float4", "float8"] + .iter() + .map(|s| s.to_string()) + .collect(); + + PossibleType::AnyOf( + schema_cache + .types + .iter() + .filter(|t| types.contains(&t.name) && t.schema == "pg_catalog") + .map(|t| t.id) + .collect(), + ) + } + pg_query_ext::protobuf::a_const::Val::Boolval(_) => PossibleType::AnyOf( + schema_cache + .types + .iter() + .filter(|t| t.name == "bool" && t.schema == "pg_catalog") + .map(|t| t.id) + .collect(), + ), + pg_query_ext::protobuf::a_const::Val::Sval(v) => { + let types: Vec = vec!["text", "varchar"] + .iter() + .map(|s| s.to_string()) + .collect(); + + PossibleType::AnyOf( + schema_cache + .types + .iter() + .filter(|t| { + (types.iter().find(|i| i == &&t.name).is_some() + && t.schema == "pg_catalog") + || t.enums.values.contains(&v.sval) + }) + .map(|t| t.id) + .collect(), + ) + } + pg_query_ext::protobuf::a_const::Val::Bsval(_) => todo!(), + } + } + } + _ => todo!(), + } +} diff --git a/crates/pg_type_resolver/src/util.rs b/crates/pg_type_resolver/src/util.rs new file mode 100644 index 00000000..90fd48d0 --- /dev/null +++ b/crates/pg_type_resolver/src/util.rs @@ -0,0 +1,6 @@ +pub(crate) fn get_string_from_node(node: &pg_query_ext::protobuf::Node) -> String { + match &node.node { + Some(pg_query_ext::NodeEnum::String(s)) => s.sval.to_string(), + _ => "".to_string(), + } +} diff --git a/crates/pg_typecheck/Cargo.toml b/crates/pg_typecheck/Cargo.toml new file mode 100644 index 00000000..89f5262e --- /dev/null +++ b/crates/pg_typecheck/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "pg_typecheck" +version = "0.0.0" +edition = "2021" + +[dependencies] +pg_base_db.workspace = true +pg_schema_cache.workspace = true +pg_syntax.workspace = true +pg_query_ext.workspace = true +text-size = "1.1.1" +async-std = "1.12.0" +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_typecheck/src/lib.rs b/crates/pg_typecheck/src/lib.rs new file mode 100644 index 00000000..6a53e766 --- /dev/null +++ b/crates/pg_typecheck/src/lib.rs @@ -0,0 +1,116 @@ +use sqlx::postgres::PgDatabaseError; +pub use sqlx::postgres::PgSeverity; +use sqlx::Executor; +use sqlx::PgPool; +use text_size::TextRange; +use text_size::TextSize; + +pub struct TypecheckerParams<'a> { + pub conn: &'a PgPool, + pub sql: &'a str, + pub enriched_ast: Option<&'a pg_syntax::AST>, + pub ast: &'a pg_query_ext::NodeEnum, +} + +#[derive(Debug, Clone)] +pub struct TypeError { + pub message: String, + pub code: String, + pub severity: PgSeverity, + pub position: Option, + pub range: Option, + pub table: Option, + pub column: Option, + pub data_type: Option, + pub constraint: Option, +} + +pub async fn check_sql<'a>(params: TypecheckerParams<'a>) -> Vec { + let mut errs = vec![]; + + // prpeared statements work only for select, insert, update, delete, and cte + if match params.ast { + pg_query_ext::NodeEnum::SelectStmt(_) => false, + pg_query_ext::NodeEnum::InsertStmt(_) => false, + pg_query_ext::NodeEnum::UpdateStmt(_) => false, + pg_query_ext::NodeEnum::DeleteStmt(_) => false, + pg_query_ext::NodeEnum::CommonTableExpr(_) => false, + _ => true, + } { + return errs; + } + + let res = params.conn.prepare(params.sql).await; + + if res.is_err() { + if let sqlx::Error::Database(err) = res.as_ref().unwrap_err() { + let pg_err = err.downcast_ref::(); + + let position = match pg_err.position() { + Some(sqlx::postgres::PgErrorPosition::Original(pos)) => Some(pos - 1), + _ => None, + }; + + let range = match params.enriched_ast { + Some(ast) => { + if position.is_none() { + None + } else { + ast.covering_node(TextRange::empty( + TextSize::try_from(position.unwrap()).unwrap(), + )) + .map(|node| node.range()) + } + } + None => None, + }; + + errs.push(TypeError { + message: pg_err.message().to_string(), + code: pg_err.code().to_string(), + severity: pg_err.severity(), + position, + range, + table: pg_err.table().map(|s| s.to_string()), + column: pg_err.column().map(|s| s.to_string()), + data_type: pg_err.data_type().map(|s| s.to_string()), + constraint: pg_err.constraint().map(|s| s.to_string()), + }); + } + } + + errs +} + +#[cfg(test)] +mod tests { + use async_std::task::block_on; + use sqlx::PgPool; + + use crate::{check_sql, TypecheckerParams}; + + #[test] + fn test_check_sql() { + let input = "select id, unknown from contact;"; + + let conn_string = std::env::var("DB_CONNECTION_STRING").unwrap(); + + let pool = block_on(PgPool::connect(conn_string.as_str())).unwrap(); + + let root = pg_query_ext::parse(input).unwrap(); + let ast = pg_syntax::parse_syntax(input, &root).ast; + + let errs = block_on(check_sql(TypecheckerParams { + conn: &pool, + sql: input, + ast: &root, + enriched_ast: Some(&ast), + })); + + assert_eq!(errs.len(), 1); + + let e = &errs[0]; + + assert_eq!(&input[e.range.unwrap()], "unknown"); + } +} diff --git a/crates/pg_workspace/Cargo.toml b/crates/pg_workspace/Cargo.toml new file mode 100644 index 00000000..e330ae02 --- /dev/null +++ b/crates/pg_workspace/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "pg_workspace" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" +dashmap = "5.5.3" +async-std = "1.12.0" +sqlx = { version = "0.7.3", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] } + +pg_base_db.workspace = true +pg_diagnostics.workspace = true +pg_query_ext.workspace = true +pg_lint.workspace = true +pg_syntax.workspace = true +pg_hover.workspace = true +pg_typecheck.workspace = true +pg_schema_cache.workspace = true + +tree-sitter.workspace = true +tree_sitter_sql.workspace = true + +[dev-dependencies] + +[lib] +doctest = false + +[features] diff --git a/crates/pg_workspace/src/lib.rs b/crates/pg_workspace/src/lib.rs new file mode 100644 index 00000000..bc4edfa8 --- /dev/null +++ b/crates/pg_workspace/src/lib.rs @@ -0,0 +1,538 @@ +mod lint; +mod pg_query; +mod tree_sitter; +mod typecheck; + +use std::sync::{RwLock, RwLockWriteGuard}; + +use dashmap::{DashMap, DashSet}; +use lint::Linter; +use pg_base_db::{Document, DocumentChange, PgLspPath, StatementRef}; +use pg_query::PgQueryParser; +use pg_schema_cache::SchemaCache; +use sqlx::PgPool; +use tree_sitter::TreeSitterParser; +use typecheck::Typechecker; + +pub struct Workspace { + pub documents: DashMap, + // Stores the statements that have changed since the last analysis + changed_stmts: DashSet, + pub schema_cache: RwLock, + + pub tree_sitter: TreeSitterParser, + pub pg_query: PgQueryParser, + pub linter: Linter, + pub typechecker: Typechecker, +} + +impl Workspace { + pub fn new() -> Workspace { + Workspace { + documents: DashMap::new(), + schema_cache: RwLock::new(SchemaCache::new()), + changed_stmts: DashSet::new(), + + tree_sitter: TreeSitterParser::new(), + pg_query: PgQueryParser::new(), + linter: Linter::new(), + typechecker: Typechecker::new(), + } + } + + /// Applies changes to the current state of the world + /// + /// Returns a list of changed statements + pub fn apply_change(&self, url: PgLspPath, mut change: DocumentChange) { + let mut doc = self + .documents + .entry(url.clone()) + .or_insert(Document::new(url, None)); + + change.apply(doc.value_mut()); + + let changed_stmts = change.collect_statement_changes(); + + for c in &changed_stmts { + match c { + pg_base_db::StatementChange::Added(s) => { + self.tree_sitter.add_statement(s); + self.pg_query.add_statement(s); + + self.changed_stmts.insert(s.to_owned()); + } + pg_base_db::StatementChange::Deleted(s) => { + self.tree_sitter.remove_statement(s); + self.pg_query.remove_statement(s); + self.linter.clear_statement_violations(s); + self.typechecker.clear_statement_errors(s); + + self.changed_stmts.insert(s.to_owned()); + } + pg_base_db::StatementChange::Modified(s) => { + self.tree_sitter.modify_statement(s); + self.pg_query.modify_statement(s); + self.linter.clear_statement_violations(&s.statement); + self.typechecker.clear_statement_errors(&s.statement); + + self.changed_stmts.remove(&s.statement); + self.changed_stmts.insert(s.new_statement().to_owned()); + } + } + } + } + + pub fn remove_document(&self, url: PgLspPath) { + let r = self.documents.remove(&url); + if r.is_some() { + let doc = r.unwrap().1; + for stmt in doc.statement_refs() { + self.tree_sitter.remove_statement(&stmt); + self.pg_query.remove_statement(&stmt); + self.linter.clear_statement_violations(&stmt); + self.typechecker.clear_statement_errors(&stmt); + } + } + } + + /// Collects all diagnostics for a given document. It does not compute them, it just collects. + pub fn diagnostics(&self, url: &PgLspPath) -> Vec { + let mut diagnostics: Vec = vec![]; + + let doc = self.documents.get(&url); + + if doc.is_none() { + return diagnostics; + } + + let doc = doc.unwrap(); + + for (range, stmt) in doc.statement_refs_with_range() { + diagnostics.extend(self.pg_query.diagnostics(&stmt, range)); + diagnostics.extend(self.linter.diagnostics(&stmt, range)); + diagnostics.extend(self.typechecker.diagnostics(&stmt, range)); + } + + diagnostics + } + + /// Drain changed statements to kick off analysis + pub fn compute(&self, conn: Option) -> Vec { + let changed: Vec = self + .changed_stmts + .iter() + .map(|arc| (*arc).clone()) + .collect(); + + self.changed_stmts.clear(); + + changed.iter().for_each(|stmt| { + self.pg_query.compute_cst(stmt); + + if let Some(ast) = self.pg_query.ast(stmt) { + self.linter.compute_statement_violations( + stmt, + ::pg_lint::LinterParams { + ast: ast.as_ref(), + enriched_ast: self + .pg_query + .enriched_ast(stmt) + .as_ref() + .map(|a| a.as_ref()), + }, + ); + if let Some(conn) = conn.as_ref() { + self.typechecker.run_typecheck( + stmt, + ::pg_typecheck::TypecheckerParams { + conn, + sql: &stmt.text, + ast: ast.as_ref(), + enriched_ast: self + .pg_query + .enriched_ast(stmt) + .as_ref() + .map(|a| a.as_ref()), + }, + ); + } + } + }); + changed + } + + pub fn set_schema_cache(&self, cache: SchemaCache) { + let mut schema_cache: RwLockWriteGuard = self.schema_cache.write().unwrap(); + *schema_cache = cache; + + // clear all schema cache related diagnostics + // and add all statements to the changed statements + self.typechecker.clear_errors(); + self.documents + .iter() + .flat_map(|entry| entry.value().statement_refs()) + .for_each(|f| { + self.changed_stmts.insert(f); + }) + } +} + +#[cfg(test)] +mod tests { + + use pg_base_db::{Change, DocumentChange}; + use pg_diagnostics::Diagnostic; + use text_size::{TextRange, TextSize}; + + use crate::{PgLspPath, Workspace}; + + #[test] + fn test_apply_change() { + let ide = Workspace::new(); + + ide.apply_change( + PgLspPath::new("test.sql"), + DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select 1;".to_string(), + }], + ), + ); + } + + #[test] + fn test_diagnostics_within_statement() { + let ide = Workspace::new(); + + let url = PgLspPath::new("test.sql"); + + ide.apply_change( + url.clone(), + DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select unknown from contact;\n\nselect 12345;\n\nalter table test drop column id;\n".to_string(), + }], + ), + ); + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + + { + let doc = ide.documents.get(&PgLspPath::new("test.sql")).unwrap(); + assert_eq!(doc.statement_refs().len(), 3); + assert_eq!( + doc.statement_ref(0).text, + "select unknown from contact;".to_string() + ); + assert_eq!(doc.statement_ref(1).text, "select 12345;".to_string()); + assert_eq!( + doc.statement_ref(2).text, + "alter table test drop column id;".to_string() + ); + } + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + + ide.apply_change( + PgLspPath::new("test.sql"), + DocumentChange::new( + 1, + vec![Change { + range: Some(TextRange::new(76.into(), 76.into())), + text: "a".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&PgLspPath::new("test.sql")).unwrap(); + assert_eq!(doc.statement_refs().len(), 3); + assert_eq!( + doc.statement_ref(0).text, + "select unknown from contact;".to_string() + ); + assert_eq!(doc.statement_ref(1).text, "select 12345;".to_string()); + assert_eq!( + doc.statement_ref(2).text, + "alter table test drop column ida;".to_string() + ); + } + + // the problem is here! + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + } + + #[test] + fn test_apply_deletion_change() { + let ide = Workspace::new(); + + let url = PgLspPath::new("test.sql"); + + ide.apply_change( + url.clone(), + DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select unknown from contact;\n\nselect 12345;\n\nalter table test drop column id;\n".to_string(), + }], + ), + ); + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + + { + let doc = ide.documents.get(&PgLspPath::new("test.sql")).unwrap(); + assert_eq!(doc.statement_refs().len(), 3); + assert_eq!( + doc.statement_ref(0).text, + "select unknown from contact;".to_string() + ); + assert_eq!(doc.statement_ref(1).text, "select 12345;".to_string()); + assert_eq!( + doc.statement_ref(2).text, + "alter table test drop column id;".to_string() + ); + } + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + + ide.apply_change( + PgLspPath::new("test.sql"), + DocumentChange::new( + 1, + vec![Change { + range: Some(TextRange::new(39.into(), 40.into())), + text: "".to_string(), + }], + ), + ); + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + + { + let doc = ide.documents.get(&PgLspPath::new("test.sql")).unwrap(); + assert_eq!(doc.statement_refs().len(), 3); + assert_eq!( + doc.statement_ref(0).text, + "select unknown from contact;".to_string() + ); + assert_eq!(doc.statement_ref(1).text, "select 1245;".to_string()); + assert_eq!( + doc.statement_ref(2).text, + "alter table test drop column id;".to_string() + ); + } + + ide.compute(None); + + assert_eq!(ide.diagnostics(&url).len(), 1); + } + + #[test] + fn test_lint() { + let ide = Workspace::new(); + let path = PgLspPath::new("test.sql"); + + ide.apply_change( + path.clone(), + DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select 1 from contact;\nselect 1;\nalter table test drop column id;" + .to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + assert_eq!(doc.statement_ranges.len(), 3); + assert_eq!( + doc.statement_ref(0).text, + "select 1 from contact;".to_string() + ); + assert_eq!(doc.statement_ref(1).text, "select 1;".to_string()); + assert_eq!( + doc.statement_ref(2).text, + "alter table test drop column id;".to_string() + ); + } + + ide.compute(None); + + let d = ide.diagnostics(&path); + + assert_eq!(d.len(), 1); + + assert_eq!( + d[0], + Diagnostic { + message: "Dropping a column may break existing clients.".to_string(), + description: None, + severity: pg_diagnostics::Severity::Warning, + source: "lint".to_string(), + range: TextRange::new(TextSize::new(50), TextSize::new(64)), + } + ); + } + + #[test] + fn test_apply_change_with_error() { + let ide = Workspace::new(); + + let path = PgLspPath::new("test.sql"); + + ide.apply_change( + path.clone(), + DocumentChange::new( + 1, + vec![Change { + range: None, + text: "select 1;\nselect 2;".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + assert_eq!(doc.statement_ref(0).text, "select 1;".to_string()); + assert_eq!(doc.statement_ref(1).text, "select 2;".to_string()); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + } + + ide.apply_change( + path.clone(), + DocumentChange::new( + 2, + vec![Change { + range: Some(TextRange::new(7.into(), 8.into())), + text: "".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + + assert_eq!(doc.text, "select ;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!(doc.statement_ref(0).text, "select ;".to_string()); + assert_eq!(doc.statement_ref(1).text, "select 2;".to_string()); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(8)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(9), TextSize::new(18)) + ); + } + + ide.apply_change( + path.clone(), + DocumentChange::new( + 3, + vec![Change { + range: Some(TextRange::new(7.into(), 7.into())), + text: "!".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + + assert_eq!(doc.text, "select !;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + } + + assert_eq!(ide.diagnostics(&PgLspPath::new("test.sql")).len(), 1); + + ide.apply_change( + path.clone(), + DocumentChange::new( + 2, + vec![Change { + range: Some(TextRange::new(7.into(), 8.into())), + text: "".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + + assert_eq!(doc.text, "select ;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(8)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(9), TextSize::new(18)) + ); + } + + ide.apply_change( + path.clone(), + DocumentChange::new( + 3, + vec![Change { + range: Some(TextRange::new(7.into(), 7.into())), + text: "1".to_string(), + }], + ), + ); + + { + let doc = ide.documents.get(&path).unwrap(); + + assert_eq!(doc.text, "select 1;\nselect 2;"); + assert_eq!(doc.statement_refs().len(), 2); + assert_eq!( + doc.statement_ranges[0], + TextRange::new(TextSize::new(0), TextSize::new(9)) + ); + assert_eq!( + doc.statement_ranges[1], + TextRange::new(TextSize::new(10), TextSize::new(19)) + ); + } + + assert_eq!(ide.diagnostics(&PgLspPath::new("test.sql")).len(), 0); + } +} diff --git a/crates/pg_workspace/src/lint.rs b/crates/pg_workspace/src/lint.rs new file mode 100644 index 00000000..a874cff6 --- /dev/null +++ b/crates/pg_workspace/src/lint.rs @@ -0,0 +1,53 @@ +use std::sync::Arc; + +use dashmap::DashMap; +use pg_base_db::StatementRef; +use pg_diagnostics::{Diagnostic, Severity}; +use text_size::TextRange; + +pub struct Linter { + violations: DashMap>>, +} + +impl Linter { + pub fn new() -> Linter { + Linter { + violations: DashMap::new(), + } + } + + pub fn diagnostics(&self, statement: &StatementRef, at_range: TextRange) -> Vec { + let mut diagnostics = Vec::new(); + if let Some(v) = self.violations.get(statement) { + diagnostics.extend(v.iter().flat_map(|v| { + v.messages.iter().map(|m| Diagnostic { + description: None, + source: "lint".to_string(), + range: v.range.map(|r| r + at_range.start()).unwrap_or(at_range), + severity: match m { + pg_lint::ViolationMessage::Note(_) => Severity::Warning, + pg_lint::ViolationMessage::Help(_) => Severity::Hint, + }, + message: match m { + pg_lint::ViolationMessage::Note(n) => n.to_owned(), + pg_lint::ViolationMessage::Help(n) => n.to_owned(), + }, + }) + })); + } + diagnostics + } + + pub fn compute_statement_violations( + &self, + statement: &StatementRef, + params: pg_lint::LinterParams<'_>, + ) { + self.violations + .insert(statement.clone(), Arc::new(pg_lint::check_sql(params))); + } + + pub fn clear_statement_violations(&self, statement: &StatementRef) { + self.violations.remove(statement); + } +} diff --git a/crates/pg_workspace/src/pg_query.rs b/crates/pg_workspace/src/pg_query.rs new file mode 100644 index 00000000..7158766e --- /dev/null +++ b/crates/pg_workspace/src/pg_query.rs @@ -0,0 +1,85 @@ +use std::sync::Arc; + +use dashmap::DashMap; +use pg_base_db::{ChangedStatement, StatementRef}; +use pg_diagnostics::{Diagnostic, Severity}; +use text_size::TextRange; + +pub struct PgQueryParser { + ast_db: DashMap>, + native_diagnostics: DashMap>, + enriched_ast_db: DashMap>, + cst_db: DashMap>, +} + +impl PgQueryParser { + pub fn new() -> PgQueryParser { + PgQueryParser { + ast_db: DashMap::new(), + native_diagnostics: DashMap::new(), + enriched_ast_db: DashMap::new(), + cst_db: DashMap::new(), + } + } + + pub fn ast(&self, statement: &StatementRef) -> Option> { + self.ast_db.get(statement).map(|x| x.clone()) + } + + pub fn enriched_ast(&self, statement: &StatementRef) -> Option> { + self.enriched_ast_db.get(statement).map(|x| x.clone()) + } + + pub fn cst(&self, statement: &StatementRef) -> Option> { + self.cst_db.get(statement).map(|x| x.clone()) + } + + pub fn compute_cst(&self, statement: &StatementRef) { + if self.cst_db.contains_key(statement) { + return; + } + + if let Some(ast) = self.ast_db.get(statement) { + let r = pg_syntax::parse_syntax(&statement.text, &ast); + self.cst_db.insert(statement.clone(), Arc::new(r.cst)); + self.enriched_ast_db + .insert(statement.clone(), Arc::new(r.ast)); + } + } + + pub fn diagnostics(&self, statement: &StatementRef, at_range: TextRange) -> Vec { + let mut diagnostics = Vec::new(); + if let Some(err) = self.native_diagnostics.get(statement) { + diagnostics.push(Diagnostic { + description: None, + source: "pg_query".to_string(), + range: at_range, + severity: Severity::Error, + message: err.to_string(), + }); + } + diagnostics + } + + pub fn add_statement(&self, statement: &StatementRef) { + let r = pg_query_ext::parse(statement.text.as_str()); + if r.is_ok() { + self.ast_db.insert(statement.clone(), Arc::new(r.unwrap())); + } else { + self.native_diagnostics + .insert(statement.clone(), Arc::new(r.unwrap_err())); + } + } + + pub fn remove_statement(&self, statement: &StatementRef) { + self.ast_db.remove(statement); + self.native_diagnostics.remove(statement); + self.enriched_ast_db.remove(statement); + self.cst_db.remove(statement); + } + + pub fn modify_statement(&self, change: &ChangedStatement) { + self.remove_statement(&change.statement); + self.add_statement(&change.new_statement()); + } +} diff --git a/crates/pg_workspace/src/tree_sitter.rs b/crates/pg_workspace/src/tree_sitter.rs new file mode 100644 index 00000000..e9da5215 --- /dev/null +++ b/crates/pg_workspace/src/tree_sitter.rs @@ -0,0 +1,158 @@ +use std::sync::{Arc, RwLock}; + +use dashmap::DashMap; +use pg_base_db::{ChangedStatement, StatementRef}; +use tree_sitter::InputEdit; + +pub struct TreeSitterParser { + db: DashMap>, + + parser: RwLock, +} + +impl TreeSitterParser { + pub fn new() -> TreeSitterParser { + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(tree_sitter_sql::language()) + .expect("Error loading sql language"); + + TreeSitterParser { + db: DashMap::new(), + parser: RwLock::new(parser), + } + } + + pub fn tree(&self, statement: &StatementRef) -> Option> { + self.db.get(statement).map(|x| x.clone()) + } + + pub fn add_statement(&self, statement: &StatementRef) { + let mut guard = self.parser.write().expect("Error reading parser"); + // todo handle error + let tree = guard.parse(&statement.text, None).unwrap(); + drop(guard); + self.db.insert(statement.clone(), Arc::new(tree)); + } + + pub fn remove_statement(&self, statement: &StatementRef) { + self.db.remove(&statement); + } + + pub fn modify_statement(&self, change: &ChangedStatement) { + let old = self.db.remove(&change.statement); + + if old.is_none() { + self.add_statement(&change.new_statement()); + return; + } + + // we clone the three for now, lets see if that is sufficient or if we need to mutate the + // original tree instead but that will require some kind of locking + let mut tree = old.unwrap().1.as_ref().clone(); + + let edit = edit_from_change( + &change.statement.text.as_str(), + usize::from(change.range.start()), + usize::from(change.range.end()), + change.text.as_str(), + ); + + tree.edit(&edit); + + let new_stmt = change.new_statement(); + let new_text = new_stmt.text.clone(); + + let mut guard = self.parser.write().expect("Error reading parser"); + // todo handle error + self.db.insert( + new_stmt, + Arc::new(guard.parse(new_text, Some(&tree)).unwrap()), + ); + drop(guard); + } +} + +// i wont pretend to know whats going on here but it seems to work +pub fn edit_from_change( + text: &str, + start_char: usize, + end_char: usize, + replacement_text: &str, +) -> InputEdit { + let mut start_byte = 0; + let mut end_byte = 0; + let mut chars_counted = 0; + + let mut line = 0; + let mut current_line_char_start = 0; // Track start of the current line in characters + let mut column_start = 0; + let mut column_end = 0; + + for (idx, c) in text.char_indices() { + if chars_counted == start_char { + start_byte = idx; + column_start = chars_counted - current_line_char_start; + } + if chars_counted == end_char { + end_byte = idx; + // Calculate column_end based on replacement_text + let replacement_lines: Vec<&str> = replacement_text.split('\n').collect(); + if replacement_lines.len() > 1 { + // If replacement text spans multiple lines, adjust line and column_end accordingly + line += replacement_lines.len() - 1; + column_end = replacement_lines.last().unwrap().chars().count(); + } else { + // Single line replacement, adjust column_end based on replacement text length + column_end = column_start + replacement_text.chars().count(); + } + break; // Found both start and end + } + if c == '\n' { + line += 1; + current_line_char_start = chars_counted + 1; // Next character starts a new line + } + chars_counted += 1; + } + + // Adjust end_byte based on the byte length of the replacement text + if start_byte != end_byte { + // Ensure there's a range to replace + end_byte = start_byte + replacement_text.len(); + } else if chars_counted < text.chars().count() && end_char == chars_counted { + // For insertions at the end of text + end_byte += replacement_text.len(); + } + + let start_point = tree_sitter::Point::new(line, column_start); + let end_point = tree_sitter::Point::new(line, column_end); + + // Calculate the new end byte after the insertion + let new_end_byte = start_byte + replacement_text.len(); + + // Calculate the new end position + let new_lines = replacement_text.matches('\n').count(); // Count how many new lines are in the inserted text + let last_line_length = replacement_text + .lines() + .last() + .unwrap_or("") + .chars() + .count(); // Length of the last line in the insertion + + let new_end_position = if new_lines > 0 { + // If there are new lines, the row is offset by the number of new lines, and the column is the length of the last line + tree_sitter::Point::new(start_point.row + new_lines, last_line_length) + } else { + // If there are no new lines, the row remains the same, and the column is offset by the length of the insertion + tree_sitter::Point::new(start_point.row, start_point.column + last_line_length) + }; + + InputEdit { + start_byte, + old_end_byte: end_byte, + new_end_byte, + start_position: start_point, + old_end_position: end_point, + new_end_position, + } +} diff --git a/crates/pg_workspace/src/typecheck.rs b/crates/pg_workspace/src/typecheck.rs new file mode 100644 index 00000000..a2dbf837 --- /dev/null +++ b/crates/pg_workspace/src/typecheck.rs @@ -0,0 +1,57 @@ +use std::sync::Arc; + +use dashmap::DashMap; +use pg_base_db::StatementRef; +use pg_diagnostics::{Diagnostic, Severity}; +use pg_typecheck::{check_sql, PgSeverity, TypeError, TypecheckerParams}; +use text_size::TextRange; + +pub struct Typechecker { + errors: DashMap>>, +} + +impl Typechecker { + pub fn new() -> Typechecker { + Typechecker { + errors: DashMap::new(), + } + } + + pub fn clear_errors(&self) { + self.errors.clear(); + } + + pub fn diagnostics(&self, statement: &StatementRef, at_range: TextRange) -> Vec { + let mut diagnostics = Vec::new(); + if let Some(errs) = self.errors.get(statement) { + diagnostics.extend(errs.iter().map(|e| Diagnostic { + description: None, + source: "typecheck".to_string(), + range: e.range.map(|r| r + at_range.start()).unwrap_or(at_range), + severity: match e.severity { + PgSeverity::Error => Severity::Error, + PgSeverity::Fatal => Severity::Error, + PgSeverity::Panic => Severity::Error, + PgSeverity::Warning => Severity::Warning, + PgSeverity::Notice => Severity::Information, + PgSeverity::Debug => Severity::Information, + PgSeverity::Info => Severity::Information, + PgSeverity::Log => Severity::Information, + }, + message: e.message.to_owned(), + })); + } + diagnostics + } + + pub fn run_typecheck(&self, statement: &StatementRef, params: TypecheckerParams<'_>) { + self.errors.insert( + statement.clone(), + Arc::new(async_std::task::block_on(check_sql(params))), + ); + } + + pub fn clear_statement_errors(&self, statement: &StatementRef) { + self.errors.remove(statement); + } +} diff --git a/crates/postgres_lsp/Cargo.toml b/crates/postgres_lsp/Cargo.toml deleted file mode 100644 index 1220fda3..00000000 --- a/crates/postgres_lsp/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "postgres_lsp" -version = "0.0.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -env_logger = "0.9.0" -tokio = { version = "1.17.0", features = ["full"] } -tower-lsp = { version = "0.19.0", features = ["proposed"]} -dashmap = "5.1.0" -ropey = "1.5.0" -serde_json = "1.0.78" -serde = { version = "1.0", features = ["derive"] } -log = "0.4.18" - -parser.workspace = true diff --git a/crates/postgres_lsp/src/main.rs b/crates/postgres_lsp/src/main.rs deleted file mode 100644 index f02f946b..00000000 --- a/crates/postgres_lsp/src/main.rs +++ /dev/null @@ -1,308 +0,0 @@ -mod semantic_token; -mod utils; - -use dashmap::DashMap; -use parser::{parse_source, Parse}; -use ropey::Rope; -use semantic_token::{ImCompleteSemanticToken, LEGEND_TYPE}; -use serde_json::Value; -use tower_lsp::jsonrpc::Result; -use tower_lsp::lsp_types::*; -use tower_lsp::{Client, LanguageServer, LspService, Server}; - -use crate::semantic_token::semantic_token_from_syntax_kind; -use crate::utils::offset_to_position; - -#[derive(Debug)] -struct Backend { - client: Client, - parse_map: DashMap, - document_map: DashMap, - semantic_token_map: DashMap>, -} - -#[tower_lsp::async_trait] -impl LanguageServer for Backend { - async fn initialize(&self, _: InitializeParams) -> Result { - self.client - .log_message(MessageType::INFO, "initializing!") - .await; - Ok(InitializeResult { - server_info: None, - offset_encoding: None, - capabilities: ServerCapabilities { - // inlay_hint_provider: Some(OneOf::Left(true)), - text_document_sync: Some(TextDocumentSyncCapability::Kind( - TextDocumentSyncKind::FULL, - )), - // completion_provider: Some(CompletionOptions { - // resolve_provider: Some(false), - // trigger_characters: Some(vec![".".to_string()]), - // work_done_progress_options: Default::default(), - // all_commit_characters: None, - // completion_item: None, - // }), - // execute_command_provider: Some(ExecuteCommandOptions { - // commands: vec!["dummy.do_something".to_string()], - // work_done_progress_options: Default::default(), - // }), - workspace: Some(WorkspaceServerCapabilities { - workspace_folders: Some(WorkspaceFoldersServerCapabilities { - supported: Some(true), - change_notifications: Some(OneOf::Left(true)), - }), - file_operations: None, - }), - semantic_tokens_provider: Some( - SemanticTokensServerCapabilities::SemanticTokensRegistrationOptions( - SemanticTokensRegistrationOptions { - text_document_registration_options: { - TextDocumentRegistrationOptions { - document_selector: Some(vec![DocumentFilter { - language: Some("nrs".to_string()), - scheme: Some("file".to_string()), - pattern: None, - }]), - } - }, - semantic_tokens_options: SemanticTokensOptions { - work_done_progress_options: WorkDoneProgressOptions::default(), - legend: SemanticTokensLegend { - token_types: LEGEND_TYPE.into(), - token_modifiers: vec![], - }, - range: Some(true), - full: Some(SemanticTokensFullOptions::Bool(true)), - }, - static_registration_options: StaticRegistrationOptions::default(), - }, - ), - ), - // definition: Some(GotoCapability::default()), - // definition_provider: Some(OneOf::Left(true)), - // references_provider: Some(OneOf::Left(true)), - // rename_provider: Some(OneOf::Left(true)), - ..ServerCapabilities::default() - }, - }) - } - - async fn initialized(&self, _: InitializedParams) { - self.client - .log_message(MessageType::INFO, "initialized!") - .await; - } - - async fn shutdown(&self) -> Result<()> { - Ok(()) - } - - async fn did_open(&self, params: DidOpenTextDocumentParams) { - self.client - .log_message(MessageType::INFO, "file opened!") - .await; - self.on_change(TextDocumentItem { - uri: params.text_document.uri, - text: params.text_document.text, - version: params.text_document.version, - }) - .await - } - - async fn did_change(&self, mut params: DidChangeTextDocumentParams) { - self.client - .log_message(MessageType::INFO, "file changed!") - .await; - self.on_change(TextDocumentItem { - uri: params.text_document.uri, - text: std::mem::take(&mut params.content_changes[0].text), - version: params.text_document.version, - }) - .await - } - - async fn did_save(&self, _: DidSaveTextDocumentParams) { - self.client - .log_message(MessageType::INFO, "file saved!") - .await; - } - async fn did_close(&self, _: DidCloseTextDocumentParams) { - self.client - .log_message(MessageType::INFO, "file closed!") - .await; - } - - async fn semantic_tokens_full( - &self, - params: SemanticTokensParams, - ) -> Result> { - let uri = params.text_document.uri.to_string(); - self.client - .log_message(MessageType::LOG, "semantic_token_full") - .await; - let semantic_tokens = || -> Option> { - let mut im_complete_tokens = self.semantic_token_map.get_mut(&uri)?; - let rope = self.document_map.get(&uri)?; - im_complete_tokens.sort_by(|a, b| a.start.cmp(&b.start)); - let mut pre_line = 0; - let mut pre_start = 0; - let semantic_tokens = im_complete_tokens - .iter() - .filter_map(|token| { - let line = rope.try_byte_to_line(token.start).ok()? as u32; - let first = rope.try_line_to_char(line as usize).ok()? as u32; - let start = rope.try_byte_to_char(token.start).ok()? as u32 - first; - let delta_line = line - pre_line; - let delta_start = if delta_line == 0 { - start - pre_start - } else { - start - }; - let ret = Some(SemanticToken { - delta_line, - delta_start, - length: token.length as u32, - token_type: token.token_type as u32, - token_modifiers_bitset: 0, - }); - pre_line = line; - pre_start = start; - ret - }) - .collect::>(); - Some(semantic_tokens) - }(); - self.client - .log_message( - MessageType::LOG, - format!("semantic_tokens: {:?}", semantic_tokens), - ) - .await; - if let Some(semantic_token) = semantic_tokens { - return Ok(Some(SemanticTokensResult::Tokens(SemanticTokens { - result_id: None, - data: semantic_token, - }))); - } - Ok(None) - } - - async fn semantic_tokens_range( - &self, - _: SemanticTokensRangeParams, - ) -> Result> { - return Ok(None); - } - - async fn did_change_configuration(&self, _: DidChangeConfigurationParams) { - self.client - .log_message(MessageType::INFO, "configuration changed!") - .await; - } - - async fn did_change_workspace_folders(&self, _: DidChangeWorkspaceFoldersParams) { - self.client - .log_message(MessageType::INFO, "workspace folders changed!") - .await; - } - - async fn did_change_watched_files(&self, _: DidChangeWatchedFilesParams) { - self.client - .log_message(MessageType::INFO, "watched files have changed!") - .await; - } - - async fn execute_command(&self, _: ExecuteCommandParams) -> Result> { - self.client - .log_message(MessageType::INFO, "command executed!") - .await; - - match self.client.apply_edit(WorkspaceEdit::default()).await { - Ok(res) if res.applied => self.client.log_message(MessageType::INFO, "applied").await, - Ok(_) => self.client.log_message(MessageType::INFO, "rejected").await, - Err(err) => self.client.log_message(MessageType::ERROR, err).await, - } - - Ok(None) - } -} - -struct TextDocumentItem { - uri: Url, - text: String, - version: i32, -} -impl Backend { - async fn on_change(&self, params: TextDocumentItem) { - self.client - .log_message(MessageType::INFO, format!("on_change {:?}", params.uri)) - .await; - let rope = ropey::Rope::from_str(¶ms.text); - self.document_map - .insert(params.uri.to_string(), rope.clone()); - - let rope = ropey::Rope::from_str(¶ms.text); - - let result = parse_source(¶ms.text); - - dbg!(&result.cst); - - // update semantic tokens - let semantic_tokens = result - .cst - .descendants_with_tokens() - .filter_map(|item| match semantic_token_from_syntax_kind(item.kind()) { - Some(token_type) => Some(ImCompleteSemanticToken { - start: item.text_range().start().into(), - token_type, - length: item.text_range().len().into(), - }), - None => None, - }) - .collect::>(); - - // publish diagnostics - // - let diagnostics = result - .errors - .iter() - .map(|error| { - Diagnostic::new_simple( - Range { - start: offset_to_position(error.range().start().into(), &rope).unwrap(), - end: offset_to_position(error.range().start().into(), &rope).unwrap(), - }, - error.to_string(), - ) - }) - .collect::>(); - - self.client - .publish_diagnostics(params.uri.clone(), diagnostics, Some(params.version)) - .await; - - self.semantic_token_map - .insert(params.uri.to_string(), semantic_tokens); - - self.parse_map.insert(params.uri.to_string(), result); - } -} - -#[tokio::main] -async fn main() { - env_logger::init(); - - let stdin = tokio::io::stdin(); - let stdout = tokio::io::stdout(); - - let (service, socket) = LspService::build(|client| Backend { - client, - // ast_map: DashMap::new(), - document_map: DashMap::new(), - parse_map: DashMap::new(), - semantic_token_map: DashMap::new(), - }) - .finish(); - - Server::new(stdin, stdout, socket).serve(service).await; -} diff --git a/crates/postgres_lsp/src/semantic_token.rs b/crates/postgres_lsp/src/semantic_token.rs deleted file mode 100644 index b9c77c7d..00000000 --- a/crates/postgres_lsp/src/semantic_token.rs +++ /dev/null @@ -1,83 +0,0 @@ -use parser::SyntaxKind; -use tower_lsp::lsp_types::SemanticTokenType; - -/// Semantic token types that are used for highlighting -pub const LEGEND_TYPE: &[SemanticTokenType] = &[ - // For identifiers that declare or reference a namespace, module, or package. - SemanticTokenType::NAMESPACE, - // For identifiers that declare or reference a class type. - SemanticTokenType::CLASS, - // For identifiers that declare or reference an enumeration type. - SemanticTokenType::ENUM, - // For identifiers that declare or reference an interface type. - // SemanticTokenType::INTERFACE, - // For identifiers that declare or reference a struct type. - // SemanticTokenType::STRUCT, - // For identifiers that declare or reference a type parameter. - SemanticTokenType::TYPE_PARAMETER, - // For identifiers that declare or reference a type that is not covered above. - SemanticTokenType::TYPE, - // For identifiers that declare or reference a function or method parameters. - SemanticTokenType::PARAMETER, - // For identifiers that declare or reference a local or global variable. - SemanticTokenType::VARIABLE, - // For identifiers that declare or reference a member property, member field, or member variable. - SemanticTokenType::PROPERTY, - // For identifiers that declare or reference an enumeration property, constant, or member. - SemanticTokenType::ENUM_MEMBER, - // For identifiers that declare or reference decorators and annotations. - // SemanticTokenType::DECORATOR, - // For identifiers that declare an event property. - SemanticTokenType::EVENT, - // For identifiers that declare a function. - SemanticTokenType::FUNCTION, - // For identifiers that declare a member function or method. - SemanticTokenType::METHOD, - // For identifiers that declare a macro. - // SemanticTokenType::MACRO, - // For tokens that represent a comment. - SemanticTokenType::COMMENT, - // For tokens that represent a string literal. - SemanticTokenType::STRING, - // For tokens that represent a language keyword. - SemanticTokenType::KEYWORD, - // For tokens that represent a number literal. - SemanticTokenType::NUMBER, - // For tokens that represent a regular expression literal. - SemanticTokenType::REGEXP, - // For tokens that represent an operator. - SemanticTokenType::OPERATOR, -]; - -#[derive(Debug, Clone)] -pub struct ImCompleteSemanticToken { - pub start: usize, - pub length: usize, - pub token_type: usize, -} - -pub fn semantic_token_from_syntax_kind(syntax: SyntaxKind) -> Option { - let token_type = match syntax { - SyntaxKind::Ascii37 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii42 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii43 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii44 => Some(SemanticTokenType::PROPERTY), - SyntaxKind::Ascii45 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii47 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii60 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii62 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Ascii63 => Some(SemanticTokenType::OPERATOR), - SyntaxKind::Sconst => Some(SemanticTokenType::STRING), - SyntaxKind::Comment => Some(SemanticTokenType::COMMENT), - SyntaxKind::Select => Some(SemanticTokenType::KEYWORD), - SyntaxKind::From => Some(SemanticTokenType::KEYWORD), - SyntaxKind::Where => Some(SemanticTokenType::KEYWORD), - SyntaxKind::ColumnRef => Some(SemanticTokenType::PROPERTY), - SyntaxKind::RangeVar => Some(SemanticTokenType::CLASS), - _ => None, - }; - if let Some(token_type) = token_type { - return LEGEND_TYPE.iter().position(|item| item == &token_type); - } - None -} diff --git a/crates/postgres_lsp/src/utils.rs b/crates/postgres_lsp/src/utils.rs deleted file mode 100644 index 38278305..00000000 --- a/crates/postgres_lsp/src/utils.rs +++ /dev/null @@ -1,9 +0,0 @@ -use ropey::Rope; -use tower_lsp::lsp_types::Position; - -pub fn offset_to_position(offset: usize, rope: &Rope) -> Option { - let line = rope.try_char_to_line(offset).ok()?; - let first_char_of_line = rope.try_line_to_char(line).ok()?; - let column = offset - first_char_of_line; - Some(Position::new(line as u32, column as u32)) -} diff --git a/crates/schema_cache/src/schema_cache.rs b/crates/schema_cache/src/schema_cache.rs deleted file mode 100644 index 149d1819..00000000 --- a/crates/schema_cache/src/schema_cache.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::future::join; - -use sqlx::postgres::PgPool; - -use crate::schemas::Schema; -use crate::tables::Table; - -#[derive(Debug, Clone, Default)] -pub struct SchemaCache { - pub schemas: Vec, - pub tables: Vec
, -} - -impl SchemaCache { - pub async fn load(pool: &PgPool) -> SchemaCache { - let (schemas, tables) = join!(Schema::load(pool), Table::load(pool)).await; - - SchemaCache { schemas, tables } - } - - /// Applies an AST node to the repository - /// - /// For example, alter table add column will add the column to the table if it does not exist - /// yet - pub fn mutate(&mut self) { - unimplemented!(); - } -} - -pub trait SchemaCacheItem { - type Item; - - async fn load(pool: &PgPool) -> Vec; -} diff --git a/lib/line_index/Cargo.toml b/lib/line_index/Cargo.toml new file mode 100644 index 00000000..3fdeb0b7 --- /dev/null +++ b/lib/line_index/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "line_index" +version = "0.0.0" +edition = "2021" + +[dependencies] +text-size = "1.1.1" + +[lib] +doctest = false diff --git a/lib/line_index/src/lib.rs b/lib/line_index/src/lib.rs new file mode 100644 index 00000000..6b61bf11 --- /dev/null +++ b/lib/line_index/src/lib.rs @@ -0,0 +1,217 @@ +// The following code has been copied from rust-analyzer. + +//! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)` +//! representation. +use std::{collections::HashMap, iter}; + +use text_size::TextRange; +use text_size::TextSize; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LineIndex { + /// Offset the the beginning of each line, zero-based + pub newlines: Vec, + /// List of non-ASCII characters on each line + pub(crate) utf16_lines: HashMap>, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct LineColUtf16 { + /// Zero-based + pub line: u32, + /// Zero-based + pub col: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct LineCol { + /// Zero-based + pub line: u32, + /// Zero-based utf8 offset + pub col: u32, +} + +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +pub(crate) struct Utf16Char { + /// Start offset of a character inside a line, zero-based + pub(crate) start: TextSize, + /// End offset of a character inside a line, zero-based + pub(crate) end: TextSize, +} + +impl Utf16Char { + /// Returns the length in 8-bit UTF-8 code units. + fn len(&self) -> TextSize { + self.end - self.start + } + + /// Returns the length in 16-bit UTF-16 code units. + fn len_utf16(&self) -> usize { + if self.len() == TextSize::from(4) { + 2 + } else { + 1 + } + } +} + +impl LineIndex { + pub fn new(text: &str) -> LineIndex { + let mut utf16_lines = HashMap::default(); + let mut utf16_chars = Vec::new(); + + let mut newlines = vec![0.into()]; + let mut curr_row = 0.into(); + let mut curr_col = 0.into(); + let mut line = 0; + for c in text.chars() { + let c_len = TextSize::of(c); + curr_row += c_len; + if c == '\n' { + newlines.push(curr_row); + + // Save any utf-16 characters seen in the previous line + if !utf16_chars.is_empty() { + utf16_lines.insert(line, utf16_chars); + utf16_chars = Vec::new(); + } + + // Prepare for processing the next line + curr_col = 0.into(); + line += 1; + continue; + } + + if !c.is_ascii() { + utf16_chars.push(Utf16Char { + start: curr_col, + end: curr_col + c_len, + }); + } + + curr_col += c_len; + } + + // Save any utf-16 characters seen in the last line + if !utf16_chars.is_empty() { + utf16_lines.insert(line, utf16_chars); + } + + LineIndex { + newlines, + utf16_lines, + } + } + + pub fn line_col(&self, offset: TextSize) -> LineCol { + let line = partition_point(&self.newlines, |&it| it <= offset) - 1; + let line_start_offset = self.newlines[line]; + let col = offset - line_start_offset; + LineCol { + line: line as u32, + col: col.into(), + } + } + + pub fn offset(&self, line_col: LineCol) -> Option { + Some(self.newlines.get(line_col.line as usize)? + TextSize::from(line_col.col)) + } + + pub fn to_utf16(&self, line_col: LineCol) -> Option { + let col = self.utf8_to_utf16_col(line_col.line, line_col.col.into()); + Some(LineColUtf16 { + line: line_col.line, + col: col as u32, + }) + } + + pub fn to_utf8(&self, line_col: LineColUtf16) -> Option { + let col = self.utf16_to_utf8_col(line_col.line, line_col.col); + Some(LineCol { + line: line_col.line, + col: col.into(), + }) + } + + pub fn lines(&self, range: TextRange) -> impl Iterator + '_ { + let lo = partition_point(&self.newlines, |&it| it < range.start()); + let hi = partition_point(&self.newlines, |&it| it <= range.end()); + let all = iter::once(range.start()) + .chain(self.newlines[lo..hi].iter().copied()) + .chain(iter::once(range.end())); + + all.clone() + .zip(all.skip(1)) + .map(|(lo, hi)| TextRange::new(lo, hi)) + .filter(|it| !it.is_empty()) + } + + fn utf8_to_utf16_col(&self, line: u32, col: TextSize) -> usize { + let mut res: usize = col.into(); + if let Some(utf16_chars) = self.utf16_lines.get(&line) { + for c in utf16_chars { + if c.end <= col { + res -= usize::from(c.len()) - c.len_utf16(); + } else { + // From here on, all utf16 characters come *after* the character we are mapping, + // so we don't need to take them into account + break; + } + } + } + res + } + + fn utf16_to_utf8_col(&self, line: u32, mut col: u32) -> TextSize { + if let Some(utf16_chars) = self.utf16_lines.get(&line) { + for c in utf16_chars { + if col > u32::from(c.start) { + col += u32::from(c.len()) - c.len_utf16() as u32; + } else { + // From here on, all utf16 characters come *after* the character we are mapping, + // so we don't need to take them into account + break; + } + } + } + + col.into() + } +} + +/// Returns `idx` such that: +/// +/// ```text +/// ∀ x in slice[..idx]: pred(x) +/// && ∀ x in slice[idx..]: !pred(x) +/// ``` +/// +/// https://github.com/rust-lang/rust/issues/73831 +fn partition_point(slice: &[T], mut pred: P) -> usize +where + P: FnMut(&T) -> bool, +{ + let mut left = 0; + let mut right = slice.len(); + + while left != right { + let mid = left + (right - left) / 2; + // SAFETY: + // When left < right, left <= mid < right. + // Therefore left always increases and right always decreases, + // and either of them is selected. + // In both cases left <= right is satisfied. + // Therefore if left < right in a step, + // left <= right is satisfied in the next step. + // Therefore as long as left != right, 0 <= left < right <= len is satisfied + // and if this case 0 <= mid < len is satisfied too. + let value = unsafe { slice.get_unchecked(mid) }; + if pred(value) { + left = mid + 1; + } else { + right = mid; + } + } + + left +} diff --git a/crates/tree_sitter_sql/Cargo.toml b/lib/tree_sitter_sql/Cargo.toml similarity index 84% rename from crates/tree_sitter_sql/Cargo.toml rename to lib/tree_sitter_sql/Cargo.toml index a8ca0181..797af669 100644 --- a/crates/tree_sitter_sql/Cargo.toml +++ b/lib/tree_sitter_sql/Cargo.toml @@ -9,7 +9,7 @@ build = "build.rs" cc="*" [dependencies] -tree-sitter = "0.20.10" +tree-sitter.workspace = true [lib] doctest = false diff --git a/crates/tree_sitter_sql/build.rs b/lib/tree_sitter_sql/build.rs similarity index 100% rename from crates/tree_sitter_sql/build.rs rename to lib/tree_sitter_sql/build.rs diff --git a/crates/tree_sitter_sql/src/lib.rs b/lib/tree_sitter_sql/src/lib.rs similarity index 100% rename from crates/tree_sitter_sql/src/lib.rs rename to lib/tree_sitter_sql/src/lib.rs diff --git a/crates/tree_sitter_sql/tree-sitter-sql b/lib/tree_sitter_sql/tree-sitter-sql similarity index 100% rename from crates/tree_sitter_sql/tree-sitter-sql rename to lib/tree_sitter_sql/tree-sitter-sql diff --git a/test-db/seed.sql b/test-db/seed.sql new file mode 100644 index 00000000..97f641b9 --- /dev/null +++ b/test-db/seed.sql @@ -0,0 +1,6 @@ +create table public.contact ( + id serial primary key not null, + created_at timestamp with time zone not null default now(), + username text +); + diff --git a/test.sql b/test.sql new file mode 100644 index 00000000..e8405740 --- /dev/null +++ b/test.sql @@ -0,0 +1,7 @@ +select id, name, test1231234123, unknown from co; + +select 14433313331333 + +alter table test drop column id; + +select lower('test');