diff --git a/Cargo.lock b/Cargo.lock index 69e41799..d334374a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -26,6 +35,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + [[package]] name = "atty" version = "0.2.14" @@ -110,6 +125,29 @@ dependencies = [ "which", ] +[[package]] +name = "bindgen" +version = "0.66.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.101", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -145,6 +183,18 @@ dependencies = [ "iovec", ] +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" + [[package]] name = "cc" version = "1.0.99" @@ -337,6 +387,33 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "dir-test" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c013fe825864f3e4593f36426c1fa7a74f5603f13ca8d1af7a990c1cd94a79" +dependencies = [ + "dir-test-macros", +] + +[[package]] +name = "dir-test-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42f54d7b4a6bc2400fe5b338e35d1a335787585375322f49c5d5fe7b243da7e" +dependencies = [ + "glob", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "drop_bomb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" + [[package]] name = "dtoa" version = "0.4.8" @@ -370,6 +447,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.10" @@ -411,6 +494,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" version = "1.0.24" @@ -515,11 +604,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" dependencies = [ "byteorder", - "bytes", + "bytes 0.4.12", "fnv", "futures", "http", - "indexmap", + "indexmap 1.9.1", "log", "slab", "string", @@ -532,6 +621,12 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" + [[package]] name = "heck" version = "0.3.3" @@ -541,6 +636,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -565,7 +666,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" dependencies = [ - "bytes", + "bytes 0.4.12", "fnv", "itoa 0.4.8", ] @@ -576,7 +677,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "http", "tokio-buf", @@ -594,7 +695,7 @@ version = "0.12.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "futures-cpupool", "h2", @@ -624,7 +725,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "hyper", "native-tls", @@ -660,7 +761,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg 1.1.0", - "hashbrown", + "hashbrown 0.12.1", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.3", ] [[package]] @@ -692,6 +803,24 @@ dependencies = [ "libc", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -749,13 +878,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "lexer" -version = "0.0.0" -dependencies = [ - "insta", -] - [[package]] name = "libc" version = "0.2.167" @@ -777,7 +899,7 @@ name = "libpg_query-sys" version = "0.4.0" source = "git+https://github.com/chdsbd/libpg_query-sys.git?rev=ac223c7b197459d657d166449ccf99883f23bbcb#ac223c7b197459d657d166449ccf99883f23bbcb" dependencies = [ - "bindgen", + "bindgen 0.64.0", "cc", "fs_extra", "glob", @@ -900,6 +1022,12 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + [[package]] name = "native-tls" version = "0.2.10" @@ -1111,12 +1239,50 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap 2.9.0", +] + +[[package]] +name = "pg_query" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f71c7c56dfe299ec6f98aa210aa23458be3b0610c485be60a5873c2f3627c40e" +dependencies = [ + "bindgen 0.66.1", + "cc", + "fs_extra", + "glob", + "itertools 0.10.5", + "prost", + "prost-build", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "pkg-config" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn 2.0.101", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1150,6 +1316,58 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes 1.10.1", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +dependencies = [ + "heck 0.5.0", + "itertools 0.14.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.101", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + [[package]] name = "publicsuffix" version = "1.5.6" @@ -1301,18 +1519,32 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "remove_dir_all" @@ -1330,7 +1562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" dependencies = [ "base64 0.10.1", - "bytes", + "bytes 0.4.12", "cookie", "cookie_store", "encoding_rs", @@ -1640,13 +1872,32 @@ dependencies = [ "serde_repr", ] +[[package]] +name = "squawk_lexer" +version = "0.0.0" +dependencies = [ + "insta", +] + +[[package]] +name = "squawk_parser" +version = "0.0.0" +dependencies = [ + "camino", + "dir-test", + "drop_bomb", + "insta", + "pg_query", + "squawk_lexer", +] + [[package]] name = "string" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" dependencies = [ - "bytes", + "bytes 0.4.12", ] [[package]] @@ -1672,7 +1923,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro-error", "proc-macro2", "quote", @@ -1834,7 +2085,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "mio", "num_cpus", @@ -1853,7 +2104,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ - "bytes", + "bytes 0.4.12", "either", "futures", ] @@ -1884,7 +2135,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "log", ] @@ -1924,7 +2175,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ - "bytes", + "bytes 0.4.12", "futures", "iovec", "mio", diff --git a/Cargo.toml b/Cargo.toml index 5b15e8d3..82c6aa96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,11 +28,16 @@ simplelog = "0.12.0" structopt = "0.3" tempfile = "3.2.0" toml = "0.5.9" +dir-test = "0.4" +drop_bomb = "0.1.5" +camino = "1.1.9" +pg_query = "6.1.0" # local squawk-parser = { version = "0.0.0", path = "./crates/parser" } squawk-linter = { version = "0.0.0", path = "./crates/linter" } squawk-github = { version = "0.0.0", path = "./crates/github" } +squawk_lexer = { version = "0.0.0", path = "./crates/squawk_lexer" } [workspace.lints.clippy] collapsible_else_if = "allow" @@ -40,9 +45,11 @@ collapsible_if = "allow" needless_return = "allow" doc_markdown = "deny" manual_let_else = "deny" +explicit_iter_loop = "deny" [profile.dev] debug = 0 [profile.dev.package] insta.opt-level = 3 +similar.opt-level = 3 diff --git a/crates/squawk_lexer/Cargo.toml b/crates/squawk_lexer/Cargo.toml index 699c9077..fc64e5ce 100644 --- a/crates/squawk_lexer/Cargo.toml +++ b/crates/squawk_lexer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lexer" +name = "squawk_lexer" version = "0.0.0" description = "TBD" diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__bitstring.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__bitstring.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__bitstring.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__bitstring.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__block_comment.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__block_comment.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__block_comment.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__block_comment.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__block_comment_unterminated.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__block_comment_unterminated.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__block_comment_unterminated.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__block_comment_unterminated.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quote_mismatch_tags_complex.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quote_mismatch_tags_complex.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quote_mismatch_tags_complex.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quote_mismatch_tags_complex.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quote_mismatch_tags_simple.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quote_mismatch_tags_simple.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quote_mismatch_tags_simple.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quote_mismatch_tags_simple.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quoting.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quoting.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__dollar_quoting.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__dollar_quoting.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__lex_statement.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__lex_statement.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__lex_statement.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__lex_statement.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__line_comment.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__line_comment.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__line_comment.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__line_comment.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__line_comment_whitespace.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__line_comment_whitespace.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__line_comment_whitespace.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__line_comment_whitespace.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__numeric.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__numeric.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__numeric_non_decimal.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric_non_decimal.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__numeric_non_decimal.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric_non_decimal.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__numeric_with_seperators.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric_with_seperators.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__numeric_with_seperators.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__numeric_with_seperators.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__params.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__params.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__params.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__params.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__quoted_ident.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__quoted_ident.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__quoted_ident.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__quoted_ident.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__select_with_period.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__select_with_period.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__select_with_period.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__select_with_period.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__string.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__string.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__string_unicode_escape.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string_unicode_escape.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__string_unicode_escape.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string_unicode_escape.snap diff --git a/crates/squawk_lexer/src/snapshots/lexer__tests__string_with_escapes.snap b/crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string_with_escapes.snap similarity index 100% rename from crates/squawk_lexer/src/snapshots/lexer__tests__string_with_escapes.snap rename to crates/squawk_lexer/src/snapshots/squawk_lexer__tests__string_with_escapes.snap diff --git a/crates/squawk_parser/Cargo.toml b/crates/squawk_parser/Cargo.toml new file mode 100644 index 00000000..5a356a64 --- /dev/null +++ b/crates/squawk_parser/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "squawk_parser" +version = "0.0.0" +description = "TBD" + +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[lib] +doctest = false + +[dependencies] +squawk_lexer.workspace = true +drop_bomb.workspace = true + +[dev-dependencies] +insta.workspace = true +dir-test.workspace = true +camino.workspace = true +pg_query.workspace = true + +[lints] +workspace = true diff --git a/crates/squawk_parser/README.md b/crates/squawk_parser/README.md new file mode 100644 index 00000000..3f71c581 --- /dev/null +++ b/crates/squawk_parser/README.md @@ -0,0 +1,191 @@ +# parser + +> Adapted from [rust-analyzer](https://github.com/rust-lang/rust-analyzer) + +via: https://www.postgresql.org/docs/17/sql-commands.html + +| cmd | supported? | description | +| -------------------------------- | ---------- | -------------------------------------------------------------------------------------- | +| ABORT | y | abort the current transaction | +| ALTER AGGREGATE | y | change the definition of an aggregate function | +| ALTER COLLATION | y | change the definition of a collation | +| ALTER CONVERSION | y | change the definition of a conversion | +| ALTER DATABASE | y | change a database | +| ALTER DEFAULT PRIVILEGES | y | define default access privileges | +| ALTER DOMAIN | y | change the definition of a domain | +| ALTER EVENT TRIGGER | y | change the definition of an event trigger | +| ALTER EXTENSION | y | change the definition of an extension | +| ALTER FOREIGN DATA WRAPPER | y | change the definition of a foreign-data wrapper | +| ALTER FOREIGN TABLE | y | change the definition of a foreign table | +| ALTER FUNCTION | y | change the definition of a function | +| ALTER GROUP | y | change role name or membership | +| ALTER INDEX | y | change the definition of an index | +| ALTER LANGUAGE | y | change the definition of a procedural language | +| ALTER LARGE OBJECT | y | change the definition of a large object | +| ALTER MATERIALIZED VIEW | y | change the definition of a materialized view | +| ALTER OPERATOR | y | change the definition of an operator | +| ALTER OPERATOR CLASS | y | change the definition of an operator class | +| ALTER OPERATOR FAMILY | y | change the definition of an operator family | +| ALTER POLICY | y | change the definition of a row-level security policy | +| ALTER PROCEDURE | y | change the definition of a procedure | +| ALTER PUBLICATION | y | change the definition of a publication | +| ALTER ROLE | y | change a database role | +| ALTER ROUTINE | y | change the definition of a routine | +| ALTER RULE | y | change the definition of a rule | +| ALTER SCHEMA | y | change the definition of a schema | +| ALTER SEQUENCE | y | change the definition of a sequence generator | +| ALTER SERVER | y | change the definition of a foreign server | +| ALTER STATISTICS | y | change the definition of an extended statistics object | +| ALTER SUBSCRIPTION | y | change the definition of a subscription | +| ALTER SYSTEM | y | change a server configuration parameter | +| ALTER TABLE | y | change the definition of a table | +| ALTER TABLESPACE | y | change the definition of a tablespace | +| ALTER TEXT SEARCH CONFIGURATION | y | change the definition of a text search configuration | +| ALTER TEXT SEARCH DICTIONARY | y | change the definition of a text search dictionary | +| ALTER TEXT SEARCH PARSER | y | change the definition of a text search parser | +| ALTER TEXT SEARCH TEMPLATE | y | change the definition of a text search template | +| ALTER TRIGGER | y | change the definition of a trigger | +| ALTER TYPE | y | change the definition of a type | +| ALTER USER | y | change a database role | +| ALTER USER MAPPING | y | change the definition of a user mapping | +| ALTER VIEW | y | change the definition of a view | +| ANALYZE | y | collect statistics about a database | +| BEGIN | y | start a transaction block | +| CALL | y | invoke a procedure | +| CHECKPOINT | y | force a write-ahead log checkpoint | +| CLOSE | y | close a cursor | +| CLUSTER | y | cluster a table according to an index | +| COMMENT | y | define or change the comment of an object | +| COMMIT | y | commit the current transaction | +| COMMIT PREPARED | y | commit a transaction that was earlier prepared for two-phase commit | +| COPY | y | copy data between a file and a table | +| CREATE ACCESS METHOD | y | define a new access method | +| CREATE AGGREGATE | y | define a new aggregate function | +| CREATE CAST | y | define a new cast | +| CREATE COLLATION | y | define a new collation | +| CREATE CONVERSION | y | define a new encoding conversion | +| CREATE DATABASE | y | create a new database | +| CREATE DOMAIN | y | define a new domain | +| CREATE EVENT TRIGGER | y | define a new event trigger | +| CREATE EXTENSION | y | install an extension | +| CREATE FOREIGN DATA WRAPPER | y | define a new foreign-data wrapper | +| CREATE FOREIGN TABLE | y | define a new foreign table | +| CREATE FUNCTION | y | define a new function | +| CREATE GROUP | y | define a new database role | +| CREATE INDEX | y | define a new index | +| CREATE LANGUAGE | y | define a new procedural language | +| CREATE MATERIALIZED VIEW | y | define a new materialized view | +| CREATE OPERATOR | y | define a new operator | +| CREATE OPERATOR CLASS | y | define a new operator class | +| CREATE OPERATOR FAMILY | y | define a new operator family | +| CREATE POLICY | y | define a new row-level security policy for a table | +| CREATE PROCEDURE | y | define a new procedure | +| CREATE PUBLICATION | y | define a new publication | +| CREATE ROLE | y | define a new database role | +| CREATE RULE | y | define a new rewrite rule | +| CREATE SCHEMA | y | define a new schema | +| CREATE SEQUENCE | y | define a new sequence generator | +| CREATE SERVER | y | define a new foreign server | +| CREATE STATISTICS | y | define extended statistics | +| CREATE SUBSCRIPTION | y | define a new subscription | +| CREATE TABLE | y | define a new table | +| CREATE TABLE AS | y | define a new table from the results of a query | +| CREATE TABLESPACE | y | define a new tablespace | +| CREATE TEXT SEARCH CONFIGURATION | y | define a new text search configuration | +| CREATE TEXT SEARCH DICTIONARY | y | define a new text search dictionary | +| CREATE TEXT SEARCH PARSER | y | define a new text search parser | +| CREATE TEXT SEARCH TEMPLATE | y | define a new text search template | +| CREATE TRANSFORM | y | define a new transform | +| CREATE TRIGGER | y | define a new trigger | +| CREATE TYPE | y | define a new data type | +| CREATE USER | y | define a new database role | +| CREATE USER MAPPING | y | define a new mapping of a user to a foreign server | +| CREATE VIEW | y | define a new view | +| DEALLOCATE | y | deallocate a prepared statement | +| DECLARE | y | define a cursor | +| DELETE | y | delete rows of a table | +| DISCARD | y | discard session state | +| DO | y | execute an anonymous code block | +| DROP ACCESS METHOD | y | remove an access method | +| DROP AGGREGATE | y | remove an aggregate function | +| DROP CAST | y | remove a cast | +| DROP COLLATION | y | remove a collation | +| DROP CONVERSION | y | remove a conversion | +| DROP DATABASE | y | remove a database | +| DROP DOMAIN | y | remove a domain | +| DROP EVENT TRIGGER | y | remove an event trigger | +| DROP EXTENSION | y | remove an extension | +| DROP FOREIGN DATA WRAPPER | y | remove a foreign-data wrapper | +| DROP FOREIGN TABLE | y | remove a foreign table | +| DROP FUNCTION | y | remove a function | +| DROP GROUP | y | remove a database role | +| DROP INDEX | y | remove an index | +| DROP LANGUAGE | y | remove a procedural language | +| DROP MATERIALIZED VIEW | y | remove a materialized view | +| DROP OPERATOR | y | remove an operator | +| DROP OPERATOR CLASS | y | remove an operator class | +| DROP OPERATOR FAMILY | y | remove an operator family | +| DROP OWNED | y | remove database objects owned by a database role | +| DROP POLICY | y | remove a row-level security policy from a table | +| DROP PROCEDURE | y | remove a procedure | +| DROP PUBLICATION | y | remove a publication | +| DROP ROLE | y | remove a database role | +| DROP ROUTINE | y | remove a routine | +| DROP RULE | y | remove a rewrite rule | +| DROP SCHEMA | y | remove a schema | +| DROP SEQUENCE | y | remove a sequence | +| DROP SERVER | y | remove a foreign server descriptor | +| DROP STATISTICS | y | remove extended statistics | +| DROP SUBSCRIPTION | y | remove a subscription | +| DROP TABLE | y | remove a table | +| DROP TABLESPACE | y | remove a tablespace | +| DROP TEXT SEARCH CONFIGURATION | y | remove a text search configuration | +| DROP TEXT SEARCH DICTIONARY | y | remove a text search dictionary | +| DROP TEXT SEARCH PARSER | y | remove a text search parser | +| DROP TEXT SEARCH TEMPLATE | y | remove a text search template | +| DROP TRANSFORM | y | remove a transform | +| DROP TRIGGER | y | remove a trigger | +| DROP TYPE | y | remove a data type | +| DROP USER | y | remove a database role | +| DROP USER MAPPING | y | remove a user mapping for a foreign server | +| DROP VIEW | y | remove a view | +| END | y | commit the current transaction | +| EXECUTE | y | execute a prepared statement | +| EXPLAIN | y | show the execution plan of a statement | +| FETCH | y | retrieve rows from a query using a cursor | +| GRANT | y | define access privileges | +| IMPORT FOREIGN SCHEMA | y | import table definitions from a foreign server | +| INSERT | y | create new rows in a table | +| LISTEN | y | listen for a notification | +| LOAD | y | load a shared library file | +| LOCK | y | lock a table | +| MERGE | y | conditionally insert, update, or delete rows of a table | +| MOVE | y | position a cursor | +| NOTIFY | y | generate a notification | +| PREPARE | y | prepare a statement for execution | +| PREPARE TRANSACTION | y | prepare the current transaction for two-phase commit | +| REASSIGN OWNED | y | change the ownership of database objects owned by a database role | +| REFRESH MATERIALIZED VIEW | y | replace the contents of a materialized view | +| REINDEX | y | rebuild indexes | +| RELEASE SAVEPOINT | y | release a previously defined savepoint | +| RESET | y | restore the value of a run-time parameter to the default value | +| REVOKE | y | remove access privileges | +| ROLLBACK | y | abort the current transaction | +| ROLLBACK PREPARED | y | cancel a transaction that was earlier prepared for two-phase commit | +| ROLLBACK TO SAVEPOINT | y | roll back to a savepoint | +| SAVEPOINT | y | define a new savepoint within the current transaction | +| SECURITY LABEL | y | define or change a security label applied to an object | +| SELECT | y | retrieve rows from a table or view | +| SELECT INTO | y | define a new table from the results of a query | +| SET | y | change a run-time parameter | +| SET CONSTRAINTS | y | set constraint check timing for the current transaction | +| SET ROLE | y | set the current user identifier of the current session | +| SET SESSION AUTHORIZATION | y | set the session user identifier and the current user identifier of the current session | +| SET TRANSACTION | y | set the characteristics of the current transaction | +| SHOW | y | show the value of a run-time parameter | +| START TRANSACTION | y | start a transaction block | +| TRUNCATE | y | empty a table or set of tables | +| UNLISTEN | y | stop listening for a notification | +| UPDATE | y | update rows of a table | +| VACUUM | y | garbage-collect and optionally analyze a database | +| VALUES | y | compute a set of rows | diff --git a/crates/squawk_parser/src/event.rs b/crates/squawk_parser/src/event.rs new file mode 100644 index 00000000..cbcb7ef1 --- /dev/null +++ b/crates/squawk_parser/src/event.rs @@ -0,0 +1,172 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/event.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//! This module provides a way to construct a `File`. +//! It is intended to be completely decoupled from the +//! parser, so as to allow to evolve the tree representation +//! and the parser algorithm independently. + +use std::mem; + +use crate::{output::Output, syntax_kind::SyntaxKind}; + +/// `Parser` produces a flat list of `Event`s. +/// They are converted to a tree-structure in +/// a separate pass, via `SyntaxTreeBuilder`. +#[derive(Debug)] +pub(crate) enum Event { + /// This event signifies the start of the node. + /// It should be either abandoned (in which case the + /// `kind` is `TOMBSTONE`, and the event is ignored), + /// or completed via a `Finish` event. + /// + /// All tokens between a `Start` and a `Finish` would + /// become the children of the respective node. + /// + /// For left-recursive syntactic constructs, the parser produces + /// a child node before it sees a parent. `forward_parent` + /// saves the position of current event's parent. + /// + /// Consider this path + /// + /// `foo::bar` + /// + /// The events for it would look like this: + /// + /// ```text + /// START(PATH) IDENT('foo') FINISH START(PATH) T![::] IDENT('bar') FINISH + /// | /\ + /// | | + /// +------forward-parent------+ + /// ``` + /// + /// And the tree would look like this + /// + /// ```text + /// +--PATH---------+ + /// | | | + /// | | | + /// | '::' 'bar' + /// | + /// PATH + /// | + /// 'foo' + /// ``` + /// + /// See also `CompletedMarker::precede`. + Start { + kind: SyntaxKind, + forward_parent: Option, + }, + + /// Complete the previous `Start` event + Finish, + + /// Produce a single leaf-element. + /// `n_raw_tokens` is used to glue complex contextual tokens. + /// For example, lexer tokenizes `>>` as `>`, `>`, and + /// `n_raw_tokens = 2` is used to produced a single `>>`. + Token { + kind: SyntaxKind, + n_raw_tokens: u8, + }, + /// When we parse `foo.0.0` or `foo. 0. 0` the lexer will hand us a float literal + /// instead of an integer literal followed by a dot as the lexer has no contextual knowledge. + /// This event instructs whatever consumes the events to split the float literal into + /// the corresponding parts. + FloatSplitHack { + ends_in_dot: bool, + }, + Error { + msg: String, + }, +} + +impl Event { + pub(crate) fn tombstone() -> Self { + Event::Start { + kind: SyntaxKind::TOMBSTONE, + forward_parent: None, + } + } +} + +/// Generate the syntax tree with the control of events. +pub(super) fn process(mut events: Vec) -> Output { + let mut res = Output::default(); + let mut forward_parents = Vec::new(); + + for i in 0..events.len() { + match mem::replace(&mut events[i], Event::tombstone()) { + Event::Start { + kind, + forward_parent, + } => { + // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, + // in the normal control flow, the parent-child relation: `A -> B -> C`, + // while with the magic forward_parent, it writes: `C <- B <- A`. + + // append `A` into parents. + forward_parents.push(kind); + let mut idx = i; + let mut fp = forward_parent; + while let Some(fwd) = fp { + idx += fwd as usize; + // append `A`'s forward_parent `B` + fp = match mem::replace(&mut events[idx], Event::tombstone()) { + Event::Start { + kind, + forward_parent, + } => { + forward_parents.push(kind); + forward_parent + } + _ => unreachable!(), + }; + // append `B`'s forward_parent `C` in the next stage. + } + + for kind in forward_parents.drain(..).rev() { + if kind != SyntaxKind::TOMBSTONE { + res.enter_node(kind); + } + } + } + Event::Finish => res.leave_node(), + Event::Token { kind, n_raw_tokens } => { + res.token(kind, n_raw_tokens); + } + Event::FloatSplitHack { ends_in_dot } => { + res.float_split_hack(ends_in_dot); + let ev = mem::replace(&mut events[i + 1], Event::tombstone()); + assert!(matches!(ev, Event::Finish), "{ev:?}"); + } + Event::Error { msg } => res.error(msg), + } + } + + res +} diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs new file mode 100644 index 00000000..bea9d51d --- /dev/null +++ b/crates/squawk_parser/src/grammar.rs @@ -0,0 +1,13674 @@ +// Modeled after rust-analyzer's grammar, but SQL instead of Rust! +// https://github.com/rust-lang/rust-analyzer/tree/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/grammar + +use crate::{ + syntax_kind::{ + SyntaxKind::{self, *}, + ALL_KEYWORDS, BARE_LABEL_KEYWORDS, COLUMN_OR_TABLE_KEYWORDS, RESERVED_KEYWORDS, + TYPE_KEYWORDS, UNRESERVED_KEYWORDS, + }, + token_set::TokenSet, + CompletedMarker, Marker, Parser, +}; + +const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[ + R_PAREN, // is this bracket stuff right? + R_BRACK, // guessing here + SEMICOLON, + // handles cases like: + // select 1 select 2 + // which should be written as: + // select 1; select 2; + SELECT_KW, +]); + +fn literal(p: &mut Parser<'_>) -> Option { + if !p.at_ts(LITERAL_FIRST) { + return None; + } + let m = p.start(); + p.bump_any(); + Some(m.complete(p, LITERAL)) +} + +// array[1,2,3] +// array(select 1) +fn array_expr(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + let m = m.unwrap_or_else(|| p.start()); + // `[` or `(` + let closing = if p.eat(L_PAREN) { + R_PAREN + } else { + p.expect(L_BRACK); + R_BRACK + }; + while !p.at(EOF) && !p.at(closing) { + if p.at_ts(SELECT_FIRST) && (select_stmt(p, None).is_none() || p.at(EOF) || p.at(closing)) { + break; + } + if expr(p).is_none() { + break; + } + if p.at(COMMA) && p.nth_at(1, closing) { + p.err_and_bump("unexpected trailing comma"); + break; + } + if !p.at(closing) && !p.expect(COMMA) { + break; + } + } + p.expect(closing); + m.complete(p, ARRAY_EXPR) +} + +fn paren_select(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if !p.eat(L_PAREN) { + m.abandon(p); + return None; + } + while !p.at(EOF) && !p.at(R_PAREN) { + // saw_expr = true; + // we want to check for select stuff before we get the the expr stuff maybe? Although select is an expr so maybe fine? but it's not prefix or postfix so maybe right here is good? + // + if p.at_ts(SELECT_FIRST) && (select_stmt(p, None).is_none() || p.at(EOF) || p.at(R_PAREN)) { + break; + } + if paren_select(p).is_none() { + break; + } + if !p.at(R_PAREN) { + break; + } + } + p.expect(R_PAREN); + Some(m.complete(p, PAREN_EXPR)) +} + +const SELECT_FIRST: TokenSet = TokenSet::new(&[SELECT_KW, TABLE_KW, WITH_KW, VALUES_KW]); + +fn tuple_expr(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(L_PAREN) || p.at(ROW_KW)); + let m = p.start(); + p.eat(ROW_KW); + p.expect(L_PAREN); + let mut saw_comma = false; + let mut saw_expr = false; + if p.eat(COMMA) { + p.error("expected expression in tuple_expr"); + saw_comma = true; + } + while !p.at(EOF) && !p.at(R_PAREN) { + saw_expr = true; + // we want to check for select stuff before we get the the expr stuff maybe? Although select is an expr so maybe fine? but it's not prefix or postfix so maybe right here is good? + // + if p.at_ts(SELECT_FIRST) && (select_stmt(p, None).is_none() || p.at(EOF) || p.at(R_PAREN)) { + break; + } + if expr(p).is_none() { + break; + } + if !p.at(R_PAREN) { + saw_comma = true; + p.expect(COMMA); + } + } + p.expect(R_PAREN); + let cm = m.complete( + p, + if saw_expr && !saw_comma { + PAREN_EXPR + } else { + TUPLE_EXPR + }, + ); + // TODO: needs to be reworked + if p.at_ts(COMPOUND_SELECT_FIRST) { + return compound_select(p, cm); + } + cm +} + +// Define SQL-style CASE clause. +// - Full specification +// CASE WHEN a = b THEN c ... ELSE d END +// - Implicit argument +// CASE a WHEN b THEN c ... ELSE d END +// +// case_expr: CASE case_arg when_clause_list case_default END_P +// +// when_clause_list: +// when_clause +// | when_clause_list when_clause +// +// when_clause: +// WHEN a_expr THEN a_expr +fn case_expr(p: &mut Parser<'_>) -> CompletedMarker { + let m = p.start(); + p.expect(CASE_KW); + if !p.at(WHEN_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + while !p.at(EOF) { + when_clause(p); + if !p.at(WHEN_KW) { + break; + } + } + // case_default + // | ELSE a_expr + // | /* empty */ + if p.eat(ELSE_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(END_KW); + m.complete(p, CASE_EXPR) +} + +// when_clause: +// WHEN a_expr THEN a_expr +fn when_clause(p: &mut Parser<'_>) -> CompletedMarker { + let m = p.start(); + p.expect(WHEN_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(THEN_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + m.complete(p, WHEN_CLAUSE) +} + +const EXTRACT_ARG_FIRST_: TokenSet = + TokenSet::new(&[YEAR_KW, MONTH_KW, DAY_KW, HOUR_KW, MINUTE_KW, SECOND_KW]).union(STRING_FIRST); + +// IDENT | YEAR_P | MONTH_P | DAY_P | HOUR_P | MINUTE_P | SECOND_P | Sconst +const EXTRACT_ARG_FIRST: TokenSet = IDENTS.union(EXTRACT_ARG_FIRST_); +fn extract_arg(p: &mut Parser<'_>) -> bool { + if p.at_ts(EXTRACT_ARG_FIRST) { + p.bump_any(); + true + } else { + p.error(format!( + "expected ident, year, month, day, hour, minute, second, or string, got {:?}", + p.current() + )); + false + } +} + +fn extract_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(EXTRACT_KW)); + custom_fn(p, EXTRACT_KW, |p| { + extract_arg(p); + p.expect(FROM_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + }) +} + +// | OVERLAY '(' overlay_list ')' +// overlay_list: +// | a_expr PLACING a_expr FROM a_expr FOR a_expr +// | a_expr PLACING a_expr FROM a_expr +// | OVERLAY '(' func_arg_list_opt ') +fn overlay_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(OVERLAY_KW)); + custom_fn(p, OVERLAY_KW, |p| { + if p.at(R_PAREN) { + return; + } + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.eat(PLACING_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(FROM_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.eat(FOR_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + } else if p.eat(COMMA) { + while !p.at(EOF) { + if expr(p).is_none() { + p.error("expected an expression"); + } + if !p.eat(COMMA) { + break; + } + } + } + }) +} + +// POSITION '(' position_list ')' +// position_list: +// b_expr IN_P b_expr +// +// Presently, AND, NOT, IS, and IN are the a_expr keywords that would +// cause trouble in the places where b_expr is used. +fn position_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(POSITION_KW)); + fn b_expr(r: &mut Parser<'_>) -> Option { + expr_bp( + r, + 1, + &Restrictions { + in_disabled: true, + ..Restrictions::default() + }, + ) + } + custom_fn(p, POSITION_KW, |p| { + if b_expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(IN_KW); + if b_expr(p).is_none() { + p.error("expected an expression"); + } + }) +} + +fn trim_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(TRIM_KW)); + custom_fn(p, TRIM_KW, |p| { + if p.eat(BOTH_KW) { + if p.eat(FROM_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + } else { + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.eat(FROM_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + } + } else if p.eat(LEADING_KW) || p.eat(TRAILING_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + } else if expr(p).is_none() { + p.error("expected an expression"); + } + }) +} + +// SUBSTRING '(' substr_list ')' +// substr_list: +// | a_expr FROM a_expr FOR a_expr +// | a_expr FOR a_expr FROM a_expr +// | a_expr FROM a_expr +// | a_expr FOR a_expr +// | a_expr SIMILAR a_expr ESCAPE a_expr +// +// SUBSTRING '(' func_arg_list_opt ')' +fn substring_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SUBSTRING_KW)); + custom_fn(p, SUBSTRING_KW, |p| { + if expr(p).is_none() { + p.error("expected an expression"); + } + match p.current() { + // FOR a_expr FROM a_expr + // FOR a_expr + FOR_KW => { + p.bump(FOR_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + // [ from expr ] + if p.eat(FROM_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + } + // FROM a_expr + // FROM a_expr FOR a_expr + FROM_KW => { + p.bump(FROM_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + // [ for expr ] + if p.eat(FOR_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + } + // SIMILAR a_expr ESCAPE a_expr + SIMILAR_KW => { + p.bump(SIMILAR_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(ESCAPE_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + } + _ if p.eat(COMMA) => { + // normal function call + while !p.at(EOF) { + if expr(p).is_none() { + p.error("expected an expression"); + } + if !p.eat(COMMA) { + break; + } + } + } + _ => {} + } + }) +} + +fn opt_json_encoding_clause(p: &mut Parser<'_>) { + if p.eat(ENCODING_KW) { + name_ref(p); + } +} + +// json_format_clause_opt: +// json_format_clause +// | /* EMPTY */ +// +// json_format_clause: +// FORMAT_LA JSON ENCODING name +// | FORMAT_LA JSON +fn opt_json_format_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if p.eat(FORMAT_KW) { + p.expect(JSON_KW); + opt_json_encoding_clause(p); + Some(m.complete(p, JSON_FORMAT_CLAUSE)) + } else { + m.abandon(p); + None + } +} + +// json_returning_clause_opt: +// RETURNING Typename json_format_clause_opt +// | /* EMPTY */ +fn opt_json_returning_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if p.eat(RETURNING_KW) { + type_name(p); + opt_json_format_clause(p); + Some(m.complete(p, JSON_RETURNING_CLAUSE)) + } else { + m.abandon(p); + None + } +} + +// json_object_constructor_null_clause_opt: +// | NULL_P ON NULL_P +// | ABSENT ON NULL_P +// | /* EMPTY */ +fn opt_json_null_clause(p: &mut Parser<'_>) { + let m = p.start(); + if p.at(NULL_KW) || p.at(ABSENT_KW) { + p.bump_any(); + p.expect(ON_KW); + p.expect(NULL_KW); + m.complete(p, JSON_NULL_CLAUSE); + } else { + m.abandon(p); + } +} + +// json_key_uniqueness_constraint_opt: +// | WITH UNIQUE KEYS +// | WITH UNIQUE +// | WITHOUT UNIQUE KEYS +// | WITHOUT UNIQUE +// | /* EMPTY */ +fn opt_json_key_unique_constraint(p: &mut Parser<'_>) { + if p.at(WITH_KW) || p.at(WITHOUT_KW) { + let m = p.start(); + p.bump_any(); + p.expect(UNIQUE_KW); + p.eat(KEYS_KW); + m.complete(p, JSON_KEYS_UNIQUE_CLAUSE); + } +} + +// json_object( func_arg_list ) +// func_arg_list: func_arg_expr +// | func_arg_list ',' func_arg_expr +// +// func_arg_expr: a_expr +// | param_name COLON_EQUALS a_expr +// | param_name EQUALS_GREATER a_expr +// +// param_name: +// | type_function_name +// +// json_object( +// json_name_and_value_list +// json_object_constructor_null_clause_opt +// json_key_uniqueness_constraint_opt +// json_returning_clause_opt +// ) +// json_name_and_value_list: +// | json_name_and_value +// | json_name_and_value_list ',' json_name_and_value +// +// json_object( json_returning_clause_opt ) +fn json_object_fn_arg_list(p: &mut Parser<'_>) { + // json_object() + if p.at(R_PAREN) { + return; + } + // json_object(RETURNING Typename json_format_clause_opt) + if p.at(RETURNING_KW) { + opt_json_returning_clause(p); + return; + } + while !p.at(EOF) && !p.at(R_PAREN) { + // TODO: I think we need to be more strict here + // json_object(c_expr , + // json_object(a_expr : + // json_object(a_expr value + if json_object_arg(p).is_none() { + p.error("expected expression"); + } + // if we're at a the end of the params or the start of the optional + // null_clause break + if p.at(R_PAREN) + || p.at(NULL_KW) + || p.at(ABSENT_KW) + || p.at(WITH_KW) + || p.at(WITHOUT_KW) + || p.at(RETURNING_KW) + { + break; + } else if p.at(COMMA) { + // we're in a function arg + // + // we can't have trailing commas + if p.nth_at(1, R_PAREN) { + p.error("unexpected closing comma"); + } + p.bump(COMMA); + continue; + } else { + p.error("expected a comma"); + } + } + opt_json_null_clause(p); + opt_json_key_unique_constraint(p); + opt_json_returning_clause(p); +} + +fn json_object_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_OBJECT_KW)); + custom_fn(p, JSON_OBJECT_KW, |p| { + json_object_fn_arg_list(p); + }) +} + +/// +fn json_table_fn(p: &mut Parser<'_>) -> CompletedMarker { + custom_fn(p, JSON_TABLE_KW, |p| { + json_table_arg_list(p); + }) +} + +fn custom_fn( + p: &mut Parser<'_>, + kind: SyntaxKind, + mut body: impl FnMut(&mut Parser<'_>), +) -> CompletedMarker { + assert!(p.at(kind)); + let m = p.start(); + let name_ref = p.start(); + p.expect(kind); + name_ref.complete(p, NAME_REF); + let args = p.start(); + p.expect(L_PAREN); + body(p); + p.expect(R_PAREN); + args.complete(p, ARG_LIST); + m.complete(p, CALL_EXPR) +} + +// JSON_TABLE ( +// context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...] ] +// COLUMNS ( json_table_column [, ...] ) +// [ { ERROR | EMPTY [ARRAY]} ON ERROR ] +// ) +fn json_table_arg_list(p: &mut Parser<'_>) { + // context_item + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + p.expect(COMMA); + // path_expression + if expr(p).is_none() { + p.error("expected expression"); + } + // [ AS json_path_name ] + if p.eat(AS_KW) { + name(p); + } + // [ PASSING { value AS varname } [, ...] ] + if p.eat(PASSING_KW) { + while !p.at(EOF) { + // value + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + p.expect(AS_KW); + col_label(p); + if !p.eat(COMMA) { + break; + } + } + } + // COLUMNS ( json_table_column [, ...] ) + if p.eat(COLUMNS_KW) { + p.expect(L_PAREN); + while !p.at(EOF) { + json_table_column(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + // [ { ERROR | EMPTY [ARRAY]} ON ERROR ] + if p.eat(ERROR_KW) { + p.expect(ON_KW); + p.expect(ERROR_KW); + } else if p.eat(EMPTY_KW) { + p.eat(ARRAY_KW); + p.expect(ON_KW); + p.expect(ERROR_KW); + } +} + +// where json_table_column is: +// | name FOR ORDINALITY +// | name type +// [ FORMAT JSON [ENCODING UTF8]] +// [ PATH path_expression ] +// [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ] +// [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ] +// [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON EMPTY ] +// [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON ERROR ] +// | name type EXISTS [ PATH path_expression ] +// [ { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR ] +// | NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] ) +fn json_table_column(p: &mut Parser<'_>) { + // NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] ) + if p.eat(NESTED_KW) { + p.eat(PATH_KW); + // path_expression + if expr(p).is_none() { + p.error("expected expression"); + } + // [ AS json_path_name ] + if p.eat(AS_KW) { + name(p); + } + p.expect(COLUMNS_KW); + p.expect(L_PAREN); + while !p.at(EOF) { + json_table_column(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } else { + name(p); + // FOR ORDINALITY + if p.eat(FOR_KW) { + p.expect(ORDINALITY_KW); + } else { + type_name(p); + // name type EXISTS [ PATH path_expression ] + if p.eat(EXISTS_KW) { + // [ PATH path_expression ] + if p.eat(PATH_KW) { + // path_expression + if expr(p).is_none() { + p.error("expected expression"); + } + } + // [ { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR ] + if p.at(ERROR_KW) || p.at(TRUE_KW) || p.at(FALSE_KW) || p.at(UNKNOWN_KW) { + p.expect(ON_KW); + p.expect(ERROR_KW); + } + } else { + // [ FORMAT JSON [ENCODING UTF8]] + opt_json_format_clause(p); + // [ PATH path_expression ] + if p.eat(PATH_KW) { + // path_expression + if expr(p).is_none() { + p.error("expected expression"); + } + } + // [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ] + if p.at(WITHOUT_KW) || p.at(WITH_KW) { + if p.eat(WITH_KW) { + let _ = p.eat(CONDITIONAL_KW) || p.eat(UNCONDITIONAL_KW); + } else { + p.bump(WITHOUT_KW); + } + p.eat(ARRAY_KW); + p.expect(WRAPPER_KW); + } + // [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ] + if p.eat(KEEP_KW) || p.eat(OMIT_KW) { + p.expect(QUOTES_KW); + if p.eat(ON_KW) { + p.expect(SCALAR_KW); + p.expect(STRING_KW); + } + } + // [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON EMPTY ] + // [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON ERROR ] + if p.at(ERROR_KW) || p.at(NULL_KW) || p.at(EMPTY_KW) || p.at(DEFAULT_KW) { + // EMPTY { [ARRAY] | OBJECT } + if p.eat(EMPTY_KW) { + let _ = p.eat(ARRAY_KW) || p.expect(OBJECT_KW); + // DEFAULT + } else if p.eat(DEFAULT_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + // ERROR | NULL + } else { + p.bump_any(); + } + p.expect(ON_KW); + let _ = p.eat(EMPTY_KW) || p.expect(ERROR_KW); + } + } + } + } +} + +// json_array ( +// [ { value_expression [ FORMAT JSON ] } [, ...] ] +// [ { NULL | ABSENT } ON NULL ] +// [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ] +// ) +// json_array ( +// [ query_expression ] +// [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ] +// ) +fn json_array_fn_arg_list(p: &mut Parser<'_>) { + // () + if p.at(R_PAREN) { + return; + } + // 1, 2, 3, 4 + while !p.at(EOF) && !p.at(R_PAREN) && !p.at(RETURNING_KW) { + if p.at_ts(SELECT_FIRST) { + if select_stmt(p, None).is_none() || p.at(EOF) || p.at(R_PAREN) { + break; + } + opt_json_format_clause(p); + } else { + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + } + if !p.eat(COMMA) { + break; + } + } + opt_json_null_clause(p); + // (RETURNING Typename json_format_clause_opt) + if opt_json_returning_clause(p).is_none() && opt_json_format_clause(p).is_none() { + opt_json_encoding_clause(p); + } +} + +fn json_array_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_ARRAY_KW)); + custom_fn(p, JSON_ARRAY_KW, |p| { + json_array_fn_arg_list(p); + }) +} + +/// +fn some_any_all_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SOME_KW) || p.at(ANY_KW) || p.at(ALL_KW)); + let m = p.start(); + // TODO: this can only be in the conext of a binary expression, so we should + // have some validation for that. + let m1 = p.start(); + // SOME | ANY | ALL + p.bump_any(); + m1.complete(p, NAME_REF); + // args + p.expect(L_PAREN); + if p.at_ts(SELECT_FIRST) { + select_stmt(p, None); + } else { + if expr(p).is_none() { + p.error("expected expression or select"); + } + } + p.expect(R_PAREN); + m.complete(p, CALL_EXPR) +} + +// literal, path, tuple, array +fn atom_expr(p: &mut Parser<'_>) -> Option { + if let Some(m) = literal(p) { + return Some(m); + } + let done = match (p.current(), p.nth(1)) { + (PARAM, _) => { + let m = p.start(); + p.bump(PARAM); + m.complete(p, LITERAL) + } + (VALUES_KW, _) => values_clause(p, None), + (EXTRACT_KW, L_PAREN) => extract_fn(p), + (JSON_EXISTS_KW, L_PAREN) => json_exists_fn(p), + (JSON_ARRAY_KW, L_PAREN) => json_array_fn(p), + (JSON_OBJECT_KW, L_PAREN) => json_object_fn(p), + (JSON_QUERY_KW, L_PAREN) => json_query_fn(p), + (JSON_SERIALIZE_KW, L_PAREN) => json_serialize_fn(p), + (JSON_VALUE_KW, L_PAREN) => json_value_fn(p), + (JSON_KW, L_PAREN) => json_fn(p), + (SUBSTRING_KW, L_PAREN) => substring_fn(p), + (POSITION_KW, L_PAREN) => position_fn(p), + (OVERLAY_KW, L_PAREN) => overlay_fn(p), + (TRIM_KW, L_PAREN) => trim_fn(p), + (XMLROOT_KW, L_PAREN) => xmlroot_fn(p), + (XMLSERIALIZE_KW, L_PAREN) => xmlserialize_fn(p), + (XMLELEMENT_KW, L_PAREN) => xmlelement_fn(p), + (XMLEXISTS_KW, L_PAREN) => xmlexists_fn(p), + (XMLPARSE_KW, L_PAREN) => xmlparse_fn(p), + (XMLPI_KW, L_PAREN) => xmlpi_fn(p), + (SOME_KW | ALL_KW | ANY_KW, L_PAREN) => some_any_all_fn(p), + (EXISTS_KW, L_PAREN) => exists_fn(p), + _ if p.at_ts(NAME_REF_FIRST) => name_ref_(p)?, + (L_PAREN, _) => tuple_expr(p), + (ARRAY_KW, L_BRACK | L_PAREN) => { + let m = p.start(); + p.bump(ARRAY_KW); + array_expr(p, Some(m)) + } + // nested array exprs: + // array[[1,2],[3,4]] + (L_BRACK, _) => array_expr(p, None), + (ROW_KW, L_PAREN) => tuple_expr(p), + (CASE_KW, _) => case_expr(p), + _ => { + p.err_and_bump("expected expression in atom_expr"); + return None; + } + }; + Some(done) +} + +fn exists_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(EXISTS_KW)); + custom_fn(p, EXISTS_KW, |p| { + if p.at_ts(SELECT_FIRST) { + select_stmt(p, None); + } else { + p.error("expected select") + } + }) +} + +// XMLPI '(' NAME_P ColLabel ',' a_expr ')' +// XMLPI '(' NAME_P ColLabel ')' +fn xmlpi_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLPI_KW)); + custom_fn(p, XMLPI_KW, |p| { + p.expect(NAME_KW); + col_label(p); + if p.eat(COMMA) && expr(p).is_none() { + p.error("expected expr"); + } + }) +} + +// XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')' +// document_or_content: +// | DOCUMENT_P +// | CONTENT_P +// xml_whitespace_option: +// | PRESERVE WHITESPACE_P +// | STRIP_P WHITESPACE_P +// | /*EMPTY*/ +fn xmlparse_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLPARSE_KW)); + custom_fn(p, XMLPARSE_KW, |p| { + if p.at(DOCUMENT_KW) || p.at(CONTENT_KW) { + p.bump_any(); + } else { + p.error("expected DOCUMENT or CONTENT"); + } + if expr(p).is_none() { + p.error("expected expression"); + } + if p.eat(PRESERVE_KW) || p.eat(STRIP_KW) { + p.expect(WHITESPACE_KW); + } + }) +} + +fn opt_xml_passing_mech(p: &mut Parser<'_>) -> bool { + if p.eat(BY_KW) { + if !p.eat(REF_KW) && !p.eat(VALUE_KW) { + p.error("expected REF or VALUE"); + } + true + } else { + false + } +} + +// XMLEXISTS '(' c_expr xmlexists_argument ')' +// xmlexists_argument: +// | PASSING c_expr +// | PASSING c_expr xml_passing_mech +// | PASSING xml_passing_mech c_expr +// | PASSING xml_passing_mech c_expr xml_passing_mech +// xml_passing_mech: +// | BY REF_P +// | BY VALUE_P +fn xmlexists_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLEXISTS_KW)); + custom_fn(p, XMLEXISTS_KW, |p| { + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(PASSING_KW); + opt_xml_passing_mech(p); + if expr(p).is_none() { + p.error("expected expression"); + } + opt_xml_passing_mech(p); + }) +} + +// XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')' +// XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')' +// XMLELEMENT '(' NAME_P ColLabe ',' expr_list ')' +// XMLELEMENT '(' NAME_P ColLabel ')' +// xml_attributes: +// XMLATTRIBUTES '(' xml_attribute_list ')' +// xml_attribute_list: +// | xml_attribute_el +// | xml_attribute_list ',' xml_attribute_el +// xml_attribute_el: +// | a_expr AS ColLabel +// | a_expr +fn xmlelement_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLELEMENT_KW)); + custom_fn(p, XMLELEMENT_KW, |p| { + p.expect(NAME_KW); + col_label(p); + if p.eat(COMMA) { + if p.eat(XMLATTRIBUTES_KW) { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if expr(p).is_none() { + p.error("expected expression"); + } + if p.eat(AS_KW) { + col_label(p); + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + if p.eat(COMMA) && !expr_list(p) { + p.error("expected expression list"); + } + } else if !expr_list(p) { + p.error("expected expression list"); + } + } + }) +} + +// XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')' +// xml_indent_option: +// | INDENT +// | NO INDENT +// | /*EMPTY*/ +fn xmlserialize_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLSERIALIZE_KW)); + custom_fn(p, XMLSERIALIZE_KW, |p| { + if p.at(DOCUMENT_KW) || p.at(CONTENT_KW) { + p.bump_any(); + } else { + p.error("expected DOCUMENT or CONTENT"); + } + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(AS_KW); + simple_type_name(p); + if p.eat(NO_KW) { + p.expect(INDENT_KW); + } else { + p.eat(INDENT_KW); + } + }) +} + +// XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')' +// xml_root_version: +// | VERSION_P a_expr +// | VERSION_P NO VALUE_P +// opt_xml_root_standalone: +// | ',' STANDALONE_P YES_P +// | ',' STANDALONE_P NO +// | ',' STANDALONE_P NO VALUE_P +// | /*EMPTY*/ +fn xmlroot_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(XMLROOT_KW)); + custom_fn(p, XMLROOT_KW, |p| { + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(COMMA); + p.expect(VERSION_KW); + if p.eat(NO_KW) { + p.expect(VALUE_KW); + } else if expr(p).is_none() { + p.error("expected expression"); + } + if p.eat(COMMA) { + p.expect(STANDALONE_KW); + if p.eat(NO_KW) { + p.eat(VALUE_KW); + } else { + p.expect(YES_KW); + } + } + }) +} + +// JSON '(' json_value_expr json_key_uniqueness_constraint_opt ')' +fn json_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_KW)); + custom_fn(p, JSON_KW, |p| { + // json_value_expr + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + opt_json_key_unique_constraint(p); + }) +} + +// JSON_VALUE '(' +// json_value_expr ',' a_expr json_passing_clause_opt +// json_returning_clause_opt +// json_behavior_clause_opt +// ')' +fn json_value_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_VALUE_KW)); + custom_fn(p, JSON_VALUE_KW, |p| { + // json_value_expr + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + p.expect(COMMA); + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_passing_clause(p); + opt_json_returning_clause(p); + opt_json_behavior_clause(p); + }) +} + +// JSON_SERIALIZE '(' json_value_expr json_returning_clause_opt ')' +fn json_serialize_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_SERIALIZE_KW)); + custom_fn(p, JSON_SERIALIZE_KW, |p| { + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + opt_json_returning_clause(p); + }) +} + +// JSON_QUERY ( +// context_item, path_expression +// [ PASSING { value AS varname } [, ...]] +// [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ] +// [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ] +// [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ] +// [ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON EMPTY ] +// [ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON ERROR ] +// ) +fn json_query_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_QUERY_KW)); + custom_fn(p, JSON_QUERY_KW, |p| { + // context_item + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + p.expect(COMMA); + // path_expression + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_passing_clause(p); + opt_json_returning_clause(p); + opt_json_wrapper_behavior(p); + opt_json_quotes_clause(p); + opt_json_behavior_clause(p); + }) +} + +fn opt_json_quotes_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if p.eat(KEEP_KW) || p.eat(OMIT_KW) { + p.expect(QUOTES_KW); + if p.eat(ON_KW) { + p.expect(SCALAR_KW); + p.expect(STRING_KW); + } + Some(m.complete(p, JSON_QUOTES_CLAUSE)) + } else { + m.abandon(p); + None + } +} + +fn opt_json_behavior_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if opt_json_behavior(p) { + p.expect(ON_KW); + if !p.eat(ERROR_KW) { + p.expect(EMPTY_KW); + if !opt_json_behavior(p) { + p.error("expected json behavior"); + } + p.expect(ON_KW); + p.expect(ERROR_KW); + } + Some(m.complete(p, JSON_BEHAVIOR_CLAUSE)) + } else { + m.abandon(p); + None + } +} + +fn opt_json_wrapper_behavior(p: &mut Parser<'_>) -> Option { + let m = p.start(); + match (p.current(), p.nth(1)) { + // WITHOUT WRAPPER + // WITHOUT ARRAY + // WITH WRAPPER + (WITHOUT_KW, WRAPPER_KW) | (WITH_KW, WRAPPER_KW) | (WITHOUT_KW, ARRAY_KW) => { + p.bump_any(); + p.bump_any(); + } + // WITH ARRAY WRAPPER + (WITH_KW, ARRAY_KW) => { + p.bump_any(); + p.bump_any(); + p.expect(WRAPPER_KW); + } + // WITH UNCONDITIONAL ARRAY WRAPPER + // WITH UNCONDITIONAL WRAPPER + // WITH CONDITIONAL ARRAY WRAPPER + // WITH CONDITIONAL WRAPPER + (WITH_KW, UNCONDITIONAL_KW) | (WITH_KW, CONDITIONAL_KW) => { + p.bump_any(); + p.bump_any(); + p.eat(ARRAY_KW); + p.expect(WRAPPER_KW); + } + _ => { + m.abandon(p); + return None; + } + } + Some(m.complete(p, JSON_WRAPPER_BEHAVIOR_CLAUSE)) +} + +// json_exists ( +// context_item, +// path_expression +// [ PASSING { value AS varname } [, ...]] +// [{ TRUE | FALSE | UNKNOWN | ERROR } ON ERROR ] +// ) +fn json_exists_fn(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(JSON_EXISTS_KW)); + custom_fn(p, JSON_EXISTS_KW, |p| { + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_format_clause(p); + p.expect(COMMA); + if expr(p).is_none() { + p.error("expected expression"); + } + opt_json_passing_clause(p); + opt_json_on_error_clause(p); + }) +} + +fn opt_json_on_error_clause(p: &mut Parser<'_>) { + let m = p.start(); + if opt_json_behavior(p) { + p.expect(ON_KW); + p.expect(ERROR_KW); + m.complete(p, JSON_ON_ERROR_CLAUSE); + } else { + m.abandon(p); + } +} + +fn opt_json_behavior(p: &mut Parser<'_>) -> bool { + match p.current() { + DEFAULT_KW => { + p.bump(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected expression"); + } + } + ERROR_KW | NULL_KW | TRUE_KW | FALSE_KW | UNKNOWN_KW => { + p.bump_any(); + } + EMPTY_KW => { + p.bump(EMPTY_KW); + let _ = p.eat(ARRAY_KW) || p.eat(OBJECT_KW); + } + _ => return false, + } + true +} + +fn json_args(p: &mut Parser<'_>) { + while !p.at(EOF) { + if expr(p).is_none() { + p.error("expected expr"); + } + opt_json_format_clause(p); + p.expect(AS_KW); + col_label(p); + if !p.eat(COMMA) { + break; + } + } +} + +fn opt_json_passing_clause(p: &mut Parser<'_>) { + let m = p.start(); + if p.eat(PASSING_KW) { + json_args(p); + m.complete(p, JSON_PASSING_CLAUSE); + } else { + m.abandon(p); + } +} + +// unary / prefix stuff +fn lhs(p: &mut Parser<'_>, r: &Restrictions) -> Option { + let m; + let (kind, prefix_bp) = match p.current() { + MINUS | PLUS => { + m = p.start(); + p.bump_any(); + (PREFIX_EXPR, 13) + } + _ if p.at_ts(OPERATOR_FIRST) && p.at(CUSTOM_OP) => { + m = p.start(); + p.bump(CUSTOM_OP); + (PREFIX_EXPR, 7) + } + NOT_KW if !r.not_disabled => { + m = p.start(); + p.bump_any(); + (PREFIX_EXPR, 3) + } + CAST_KW | TREAT_KW => { + m = p.start(); + p.bump_any(); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(AS_KW); + type_name(p); + p.expect(R_PAREN); + let cm = m.complete(p, CAST_EXPR); + return Some(cm); + } + OPERATOR_KW if p.at(OPERATOR_CALL) => { + m = p.start(); + p.expect(OPERATOR_CALL); + (PREFIX_EXPR, 7) + } + _ => { + let lhs = atom_expr(p)?; + let cm = postfix_expr(p, lhs, true); + return Some(cm); + } + }; + // parse the interior of the unary expression + let _ = expr_bp(p, prefix_bp, &Restrictions::default()); + let cm = m.complete(p, kind); + Some(cm) +} + +fn postfix_expr( + p: &mut Parser<'_>, + mut lhs: CompletedMarker, + allow_calls: bool, +) -> CompletedMarker { + loop { + lhs = match p.current() { + | NOT_KW if p.nth_at(1, BETWEEN_KW) => between_expr(p, lhs), + | BETWEEN_KW => between_expr(p, lhs), + L_PAREN if allow_calls => call_expr_args(p, lhs), + L_BRACK /* if allow_calls */ => index_expr(p, lhs), + DOT => match postfix_dot_expr::(p, lhs, allow_calls) { + Ok(it) => it, + Err(it) => { + lhs = it; + break; + } + }, + AT_KW if p.nth_at(1, LOCAL_KW) => { + let m = lhs.precede(p); + p.bump(AT_KW); + p.bump(LOCAL_KW); + lhs = m.complete(p, POSTFIX_EXPR); + break; + } + ISNULL_KW => { + let m = lhs.precede(p); + p.bump(ISNULL_KW); + lhs = m.complete(p, POSTFIX_EXPR); + break; + } + _ => break, + }; + } + lhs +} + +/// The `parser` passed this is required to at least consume one token if it returns `true`. +/// If the `parser` returns false, parsing will stop. +fn delimited( + p: &mut Parser<'_>, + bra: SyntaxKind, + ket: SyntaxKind, + delim: SyntaxKind, + unexpected_delim_message: impl Fn() -> String, + first_set: TokenSet, + mut parser: impl FnMut(&mut Parser<'_>) -> bool, +) { + p.bump(bra); + while !p.at(ket) && !p.at(EOF) { + if p.at(delim) { + // Recover if an argument is missing and only got a delimiter, + // e.g. `(a, , b)`. + // Wrap the erroneous delimiter in an error node so that fixup logic gets rid of it. + // FIXME: Ideally this should be handled in fixup in a structured way, but our list + // nodes currently have no concept of a missing node between two delimiters. + // So doing it this way is easier. + let m = p.start(); + p.error(unexpected_delim_message()); + p.bump(delim); + m.complete(p, ERROR); + continue; + } + if !parser(p) { + break; + } + // f(a,) + // ^ + if p.at(delim) && p.nth_at(1, ket) { + p.err_and_bump("unexpected trailing comma"); + break; + } + if !p.eat(delim) { + if p.at_ts(first_set) { + p.error(format!("expected {delim:?}")); + } else { + break; + } + } + } + p.expect(ket); +} + +fn name_ref(p: &mut Parser<'_>) -> Option { + opt_name_ref(p).or_else(|| { + p.error("expected name"); + None + }) +} + +fn opt_name_ref(p: &mut Parser<'_>) -> Option { + name_ref_(p) +} + +fn name(p: &mut Parser<'_>) { + if opt_name(p).is_none() { + p.error("expected name"); + } +} + +fn opt_name(p: &mut Parser<'_>) -> Option { + if !p.at_ts(NAME_FIRST) { + return None; + } + let m = p.start(); + p.bump_any(); + Some(m.complete(p, NAME)) +} + +/// ```sql +/// create type a . b as (); +/// -- ^ ^ ^ then name_ref +/// -- | | +/// -- | ^ then name +/// -- | +/// ``` +fn path_segment(p: &mut Parser<'_>, kind: SyntaxKind) { + let m = p.start(); + // TODO: does this need to be flagged? + if current_operator(p).is_some() { + // skip + } else if p.at_ts(COL_LABEL_FIRST) { + let m = p.start(); + p.bump_any(); + let kind = if p.at(DOT) { NAME_REF } else { kind }; + m.complete(p, kind); + } else { + p.error(format!("expected name, got {:?}", p.current())); + m.abandon(p); + return; + } + m.complete(p, PATH_SEGMENT); +} + +fn opt_path(p: &mut Parser<'_>, kind: SyntaxKind) -> Option { + if !p.at_ts(COL_LABEL_FIRST) { + return None; + } + let m = p.start(); + path_segment(p, kind); + let qual = m.complete(p, PATH); + Some(path_for_qualifier(p, qual, kind)) +} + +fn path_name(p: &mut Parser<'_>) { + if opt_path(p, NAME).is_none() { + p.error("expected path name"); + } +} + +fn opt_path_name_ref(p: &mut Parser<'_>) -> Option { + opt_path(p, NAME_REF) +} + +fn path_name_ref(p: &mut Parser<'_>) { + if opt_path_name_ref(p).is_none() { + p.error("expected path name"); + } +} + +fn path_for_qualifier( + p: &mut Parser<'_>, + mut qual: CompletedMarker, + kind: SyntaxKind, +) -> CompletedMarker { + loop { + if p.at(DOT) { + let path = qual.precede(p); + p.bump(DOT); + path_segment(p, kind); + let path = path.complete(p, PATH); + qual = path; + } else { + return qual; + } + } +} + +fn opt_percent_type(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if p.eat(PERCENT) { + p.expect(TYPE_KW); + Some(m.complete(p, PERCENT_TYPE_CLAUSE)) + } else { + m.abandon(p); + None + } +} + +fn opt_array_index(p: &mut Parser<'_>) -> bool { + if p.eat(L_BRACK) { + if !p.at(R_BRACK) { + let _ = expr(p); + } + p.expect(R_BRACK); + true + } else { + false + } +} + +fn type_mods( + p: &mut Parser<'_>, + m: Marker, + type_args_enabled: bool, + kind: SyntaxKind, +) -> Option { + if opt_percent_type(p).is_some() { + return Some(m.complete(p, PERCENT_TYPE)); + } + if p.at(L_PAREN) && type_args_enabled { + p.bump(L_PAREN); + let type_args = p.start(); + while !p.at(EOF) && !p.at(R_PAREN) { + let arg = p.start(); + if expr(p).is_none() { + arg.abandon(p); + break; + } + arg.complete(p, ARG); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + type_args.complete(p, ARG_LIST); + } + let cm = m.complete(p, kind); + if !p.at(L_BRACK) && !p.at(ARRAY_KW) { + return Some(cm); + } + let m = cm.precede(p); + // TODO: we should probably mimic the INDEX_EXPR but be stricter + if p.eat(ARRAY_KW) { + opt_array_index(p); + } else { + let mut found_one_array_bracks = false; + while !p.at(EOF) && p.at(L_BRACK) { + if opt_array_index(p) { + found_one_array_bracks = true; + } + } + if !found_one_array_bracks { + p.error("expected L_BRACK for ARRAY_TYPE"); + } + } + Some(m.complete(p, ARRAY_TYPE)) +} + +fn char_type(p: &mut Parser<'_>) -> SyntaxKind { + assert!(p.at(CHARACTER_KW) || p.at(CHAR_KW) || p.at(NCHAR_KW) || p.at(VARCHAR_KW)); + if p.eat(VARCHAR_KW) { + return CHAR_TYPE; + } + p.bump_any(); + p.eat(VARYING_KW); + CHAR_TYPE +} +/* +SimpleTypename ('[' (Iconst) ']') +SET OF SimpleTypename ('[' (Iconst) ']') +SimpleTypename array '[' Iconst ']' +SET OF SimpleTypename array '[' Iconst ']' +SimpleTypename array +SET OF SimpleTypename array + +where +SimpleTypename is: + GenericType + | Numeric + | Bit + | Character + | ConstDatetime + | ConstInterval opt_interval + | ConstInterval '(' Iconst ')' + | JsonType + +*/ +#[must_use] +fn opt_type_name_with(p: &mut Parser<'_>, type_args_enabled: bool) -> Option { + let m = p.start(); + let wrapper_type = match p.current() { + BIT_KW => { + p.bump(BIT_KW); + p.eat(VARYING_KW); + BIT_TYPE + } + NATIONAL_KW if matches!(p.nth(1), CHAR_KW | CHARACTER_KW) => { + p.bump(NATIONAL_KW); + char_type(p) + } + CHARACTER_KW | CHAR_KW | NCHAR_KW | VARCHAR_KW => char_type(p), + TIMESTAMP_KW | TIME_KW => { + let name_ref = p.start(); + p.bump_any(); + name_ref.complete(p, NAME_REF); + if p.eat(L_PAREN) { + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_PAREN); + } + let m = p.start(); + if p.at(WITH_KW) || p.at(WITHOUT_KW) { + let kind = if p.eat(WITH_KW) { + WITH_TIMEZONE + } else { + p.bump(WITHOUT_KW); + WITHOUT_TIMEZONE + }; + p.expect(TIME_KW); + p.expect(ZONE_KW); + m.complete(p, kind); + } else { + m.abandon(p); + } + TIME_TYPE + } + INTERVAL_KW => { + p.bump(INTERVAL_KW); + opt_interval_trailing(p); + INTERVAL_TYPE + } + DOUBLE_KW => { + p.bump(DOUBLE_KW); + p.expect(PRECISION_KW); + DOUBLE_TYPE + } + _ if p.at_ts(TYPE_KEYWORDS) || p.at(IDENT) => { + path_name_ref(p); + PATH_TYPE + } + _ => { + m.abandon(p); + return None; + } + }; + type_mods(p, m, type_args_enabled, wrapper_type) +} + +fn opt_type_name(p: &mut Parser<'_>) -> bool { + opt_type_name_with(p, true).is_some() +} + +fn type_name(p: &mut Parser<'_>) { + if !opt_type_name(p) { + p.error("expected type name"); + } +} + +fn simple_type_name(p: &mut Parser<'_>) { + if opt_type_name_with(p, false).is_none() { + p.error("expected simple type name"); + } +} + +// json_name_and_value: +// | c_expr VALUE_P json_value_expr +// | a_expr ':' json_value_expr +// +// json_value_expr: +// a_expr json_format_clause_opt +fn json_key_value(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(COLON) || p.at(VALUE_KW)); + let m = lhs.precede(p); + p.bump_any(); + if expr(p).is_none() { + p.error("expected expr"); + } + opt_json_format_clause(p); + m.complete(p, JSON_KEY_VALUE) +} + +fn named_arg(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(FAT_ARROW) || p.at(COLONEQ)); + let m = lhs.precede(p); + if p.at(COLONEQ) { + p.bump(COLONEQ); + } else { + p.bump(FAT_ARROW); + } + if expr(p).is_none() { + p.error("expected expr"); + } + m.complete(p, NAMED_ARG) +} + +fn cast_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(COLON2)); + let m = lhs.precede(p); + p.bump(COLON2); + type_name(p); + m.complete(p, CAST_EXPR) +} + +fn arg_expr(p: &mut Parser<'_>) -> Option { + // https://www.postgresql.org/docs/17/typeconv-func.html + p.eat(VARIADIC_KW); + let r = Restrictions { + order_by_allowed: true, + ..Restrictions::default() + }; + expr_bp(p, 1, &r) +} + +fn arg_list(p: &mut Parser<'_>) { + assert!(p.at(L_PAREN)); + let m = p.start(); + // sum(*), count(*), max(*) + if p.nth_at(1, STAR) { + p.bump(L_PAREN); + p.expect(STAR); + p.expect(R_PAREN); + m.complete(p, ARG_LIST); + return; + } + if p.nth_at(1, DISTINCT_KW) || p.nth_at(1, ALL_KW) { + p.bump(L_PAREN); + p.bump_any(); + if arg_expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + m.complete(p, ARG_LIST); + return; + } + delimited( + p, + L_PAREN, + R_PAREN, + COMMA, + || "expected expression".into(), + EXPR_FIRST.union(ATTRIBUTE_FIRST), + |p| arg_expr(p).is_some(), + ); + m.complete(p, ARG_LIST); +} + +fn interval_second(p: &mut Parser<'_>) { + p.expect(SECOND_KW); + if p.eat(L_PAREN) { + // TODO: int expr + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_PAREN); + } +} + +fn opt_interval_trailing(p: &mut Parser<'_>) { + match (p.current(), p.nth(1)) { + (DAY_KW, TO_KW) => { + p.bump(DAY_KW); + p.bump(TO_KW); + match p.current() { + HOUR_KW => { + p.bump(HOUR_KW); + } + MINUTE_KW => { + p.bump(MINUTE_KW); + } + SECOND_KW => { + interval_second(p); + } + _ => p.error("expected HOUR, MINUTE, or SECOND"), + } + } + (DAY_KW, _) => p.bump(DAY_KW), + (HOUR_KW, TO_KW) => { + p.bump(HOUR_KW); + p.bump(TO_KW); + if !p.eat(MINUTE_KW) { + interval_second(p); + } + } + (HOUR_KW, _) => p.bump(HOUR_KW), + (MINUTE_KW, TO_KW) => { + p.bump(MINUTE_KW); + p.bump(TO_KW); + interval_second(p); + } + (MINUTE_KW, _) => p.bump(MINUTE_KW), + (MONTH_KW, _) => p.bump(MONTH_KW), + (YEAR_KW, TO_KW) => { + p.bump(YEAR_KW); + p.bump(TO_KW); + p.expect(MONTH_KW); + } + (YEAR_KW, _) => { + p.bump(YEAR_KW); + } + (SECOND_KW, _) => { + interval_second(p); + } + _ => (), + } +} + +fn name_ref_(p: &mut Parser<'_>) -> Option { + if !p.at_ts(NAME_REF_FIRST) { + return None; + } + let m = p.start(); + let mut is_interval_cast = false; + if p.eat(COLLATION_KW) { + p.expect(FOR_KW); + // timestamp with time zone / time with time zone + } else if p.eat(TIMESTAMP_KW) || p.eat(TIME_KW) { + if p.eat(WITH_KW) { + p.expect(TIME_KW); + p.expect(ZONE_KW); + } + } else if p.eat(INTERVAL_KW) { + is_interval_cast = true; + } else { + p.bump_any(); + } + let cm = m.complete(p, NAME_REF); + // A path followed by a literal is a type cast so we insert a CAST_EXPR + // preceding it to wrap the previously parsed data. + // e.g., `select numeric '12312'` + if !p.at(NULL_KW) && !p.at(DEFAULT_KW) && literal(p).is_some() { + if is_interval_cast { + opt_interval_trailing(p); + } + Some(cm.precede(p).complete(p, CAST_EXPR)) + } else { + Some(cm) + } +} + +fn between_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(NOT_KW) || p.at(BETWEEN_KW)); + // TODO: does this precede stuff matter? + let m = lhs.precede(p); + p.eat(NOT_KW); + p.expect(BETWEEN_KW); + p.eat(SYMMETRIC_KW); + if bexpr(p).is_none() { + p.error("expected an expression"); + } + p.expect(AND_KW); + if bexpr(p).is_none() { + p.error("expected an expression"); + } + m.complete(p, BETWEEN_EXPR) +} + +fn call_expr_args(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(L_PAREN)); + let m = lhs.precede(p); + arg_list(p); + // postgres has: + // func_expr: func_application within_group_clause filter_clause over_clause + if p.at(WITHIN_KW) { + let m = p.start(); + p.expect(WITHIN_KW); + p.expect(GROUP_KW); + p.expect(L_PAREN); + opt_order_by_clause(p); + p.expect(R_PAREN); + m.complete(p, WITHIN_CLAUSE); + } + if p.at(FILTER_KW) { + let m = p.start(); + p.expect(FILTER_KW); + p.expect(L_PAREN); + p.expect(WHERE_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_PAREN); + m.complete(p, FILTER_CLAUSE); + } + if p.at(OVER_KW) { + // OVER window_name + // OVER ( window_definition ) + let m = p.start(); + p.expect(OVER_KW); + if p.eat(L_PAREN) { + window_definition(p); + p.expect(R_PAREN); + } else { + name_ref(p); + } + m.complete(p, OVER_CLAUSE); + } + m.complete(p, CALL_EXPR) +} + +// foo[] +// foo[:b] +// foo[a:] +// foo[a:b] +// foo[:] +fn index_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(L_BRACK)); + let m = lhs.precede(p); + p.bump(L_BRACK); + if !p.eat(R_BRACK) { + // foo[expr] + // foo[:b] + // foo[:] + if p.eat(COLON) { + // foo[:] + if p.eat(R_BRACK) { + return m.complete(p, INDEX_EXPR); + } else { + // foo[:b] + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_BRACK); + return m.complete(p, INDEX_EXPR); + } + } + // foo[a] + // foo[a:] + // foo[a:b] + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.eat(COLON) { + // foo[a:] + if p.eat(R_BRACK) { + return m.complete(p, INDEX_EXPR); + } + // foo[a:b] + if expr(p).is_none() { + p.error("expected an expression"); + } + } + p.expect(R_BRACK); + } + m.complete(p, INDEX_EXPR) +} + +fn name_ref_or_index(p: &mut Parser<'_>) { + assert!(p.at(IDENT) || p.at_ts(TYPE_KEYWORDS) || p.at_ts(ALL_KEYWORDS) || p.at(INT_NUMBER)); + let m = p.start(); + p.bump_any(); + m.complete(p, NAME_REF); +} + +// TODO: do we need this float recovery stuff? +fn field_expr( + p: &mut Parser<'_>, + lhs: Option, + allow_calls: bool, +) -> Result { + if !FLOAT_RECOVERY { + assert!(p.at(DOT)); + } + let m = match lhs { + Some(lhs) => lhs.precede(p), + None => p.start(), + }; + if !FLOAT_RECOVERY { + p.bump(DOT); + } + if p.at(IDENT) || p.at_ts(TYPE_KEYWORDS) || p.at(INT_NUMBER) || p.at_ts(ALL_KEYWORDS) { + name_ref_or_index(p); + } else if p.at(FLOAT_NUMBER) { + return match p.split_float(m) { + (true, m) => { + let lhs = m.complete(p, FIELD_EXPR); + postfix_dot_expr::(p, lhs, allow_calls) + } + (false, m) => Ok(m.complete(p, FIELD_EXPR)), + }; + } else if p.eat(STAR) || opt_operator(p) { + // + } else { + p.error(format!( + "expected field name or number, got {:?}", + p.current() + )); + } + Ok(m.complete(p, FIELD_EXPR)) +} + +fn postfix_dot_expr( + p: &mut Parser<'_>, + lhs: CompletedMarker, + allow_calls: bool, +) -> Result { + if !FLOAT_RECOVERY { + assert!(p.at(DOT)); + } + field_expr::(p, Some(lhs), allow_calls).map(|m| { + // A field followed by a literal is a type cast so we insert a CAST_EXPR + // preceding it to wrap the previously parsed data. + if !p.at(NULL_KW) && !p.at(DEFAULT_KW) && literal(p).is_some() { + m.precede(p).complete(p, CAST_EXPR) + } else { + m + } + }) +} + +#[must_use] +fn expr(p: &mut Parser) -> Option { + expr_bp(p, 1, &Restrictions::default()) +} + +// Based on the Postgres grammar b_expr, it's expr without `AND`, `NOT`, `IS`, +// and `IN` +#[must_use] +fn bexpr(p: &mut Parser<'_>) -> Option { + expr_bp( + p, + 1, + &Restrictions { + in_disabled: true, + is_disabled: true, + not_disabled: true, + and_disabled: true, + ..Restrictions::default() + }, + ) +} + +fn json_object_arg(p: &mut Parser) -> Option { + expr_bp( + p, + 1, + &Restrictions { + json_field_arg_allowed: true, + ..Restrictions::default() + }, + ) +} + +enum Associativity { + Left, + Right, +} + +/// Binding powers of operators for a Pratt parser. +/// +/// See +fn current_op(p: &Parser<'_>, r: &Restrictions) -> (u8, SyntaxKind, Associativity) { + use Associativity::*; + const NOT_AN_OP: (u8, SyntaxKind, Associativity) = (0, AT, Left); + // For binding power, checkout: + // https://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-PRECEDENCE + // https://github.com/postgres/postgres/blob/30f017626308a06cf0c0c82a706a1ba1b07df34a/src/backend/parser/gram.y#L817-L898 + match p.current() { + // or + OR_KW => (1, OR_KW, Left), + // >= + R_ANGLE if p.at(GTEQ) => (5, GTEQ, Left), // symbol + // > + R_ANGLE if p.next_not_joined_op(0) => (5, R_ANGLE, Left), // symbol + // Later on we return a NAMED_ARG for this instead of BIN_EXPR + // => + EQ if p.at(FAT_ARROW) => (7, FAT_ARROW, Right), // symbol + // = + EQ if p.next_not_joined_op(0) => (5, EQ, Right), // symbol + // in + IN_KW if !r.in_disabled => (6, IN_KW, Right), + // <> + L_ANGLE if p.at(NEQB) => (5, NEQB, Left), // symbol + // <= + L_ANGLE if p.at(LTEQ) => (5, LTEQ, Left), // symbol + // < + L_ANGLE if p.next_not_joined_op(0) => (5, L_ANGLE, Left), // symbol + // + + PLUS if p.next_not_joined_op(0) => (8, PLUS, Left), // symbol + // overlaps + OVERLAPS_KW => (7, OVERLAPS_KW, Left), + // like + LIKE_KW => (6, LIKE_KW, Left), + // not like + NOT_KW if !r.not_disabled && p.at(NOT_LIKE) => (6, NOT_LIKE, Left), + // not in + NOT_KW if !r.not_disabled && p.at(NOT_IN) => (6, NOT_IN, Left), + // is distinct from + IS_KW if !r.is_disabled && p.at(IS_DISTINCT_FROM) => (4, IS_DISTINCT_FROM, Left), + // is not distinct from + IS_KW if !r.is_disabled && p.at(IS_NOT_DISTINCT_FROM) => (4, IS_NOT_DISTINCT_FROM, Left), + // at time zone + AT_KW if p.at(AT_TIME_ZONE) => (11, AT_TIME_ZONE, Left), + // similar to + SIMILAR_KW if p.at(SIMILAR_TO) => (6, SIMILAR_TO, Left), + // is not + IS_KW if p.at(IS_NOT) => (4, IS_NOT, Left), + // operator(pg_catalog.+) + OPERATOR_KW if p.at(OPERATOR_CALL) => (7, OPERATOR_CALL, Left), + // is + IS_KW if !r.is_disabled => (4, IS_KW, Left), + // ^ + CARET if p.next_not_joined_op(0) => (10, CARET, Left), // symbol + // % + PERCENT if p.next_not_joined_op(0) => (9, PERCENT, Left), // symbol + // and + AND_KW if !r.and_disabled => (2, AND_KW, Left), + // / + SLASH if p.next_not_joined_op(0) => (9, SLASH, Left), // symbol + // * + STAR if p.next_not_joined_op(0) => (9, STAR, Left), // symbol + // != + BANG if p.at(NEQ) => (5, NEQ, Left), // symbol + // collate + COLLATE_KW => (12, COLLATE_KW, Left), + // - + MINUS if p.next_not_joined_op(0) => (8, MINUS, Left), // symbol + // Later on we return a NAMED_ARG for this instead of BIN_EXPR + // := + COLON if p.at(COLONEQ) => (5, COLONEQ, Right), // symbol + // :: + COLON if p.at(COLON2) => (15, COLON2, Left), // symbol + // Only used in json_object, like json_object('a' value 1) instead of json_object('a': 1) + // value + VALUE_KW if r.json_field_arg_allowed => (7, VALUE_KW, Right), + // Later on we return a FIELD_ARG instead of BIN_EXPR + // a: b + COLON if r.json_field_arg_allowed => (7, COLON, Right), + _ if p.at_ts(OPERATOR_FIRST) => (7, CUSTOM_OP, Right), + _ => NOT_AN_OP, + } +} + +// tokens thare in bin expr and also in bare_labels +const OVERLAPPING_TOKENS: TokenSet = TokenSet::new(&[OR_KW, AND_KW, IS_KW, COLLATE_KW]); + +#[derive(Default)] +struct Restrictions { + order_by_allowed: bool, + json_field_arg_allowed: bool, + in_disabled: bool, + is_disabled: bool, + not_disabled: bool, + and_disabled: bool, +} + +#[must_use] +fn expr_bp(p: &mut Parser<'_>, bp: u8, r: &Restrictions) -> Option { + let m = p.start(); + if !p.at_ts(EXPR_FIRST) { + p.err_recover( + &format!("expected an expression, found {:?}", p.current()), + EXPR_RECOVERY_SET, + ); + m.abandon(p); + return None; + } + let mut lhs = match lhs(p, r) { + Some(lhs) => lhs.extend_to(p, m), + None => { + m.abandon(p); + return None; + } + }; + // if we're dealing with a bare column label, there's some operator keywords + // that are allowed that can trip us up, e.g, + // + // select 1 not; + // + // to solve this we check if the token following the possible operator looks + // like an expr, in which case we assume we're dealing with a binary expr, + // otherwise we assume it's a bare column label. + if p.at_ts(OVERLAPPING_TOKENS) + && !p.nth_at_ts(1, EXPR_FIRST) + // could be start of `is distinct from` + && !(p.at(IS_KW) && p.nth_at(1, DISTINCT_KW)) + { + col_label(p); + return Some(lhs); + } + if r.order_by_allowed && p.at(ORDER_KW) { + opt_order_by_clause(p); + } + loop { + let (op_bp, op, associativity) = current_op(p, r); + if op_bp < bp { + break; + } + match op { + COLON2 => { + lhs = cast_expr(p, lhs); + continue; + } + FAT_ARROW | COLONEQ => { + lhs = named_arg(p, lhs); + continue; + } + COLON | VALUE_KW => { + lhs = json_key_value(p, lhs); + continue; + } + _ => {} + } + let m = lhs.precede(p); + p.bump(op); + let op_bp = match associativity { + Associativity::Left => op_bp + 1, + Associativity::Right => op_bp, + }; + let _ = expr_bp(p, op_bp, r); + lhs = m.complete(p, BIN_EXPR); + } + Some(lhs) +} + +fn expr_list(p: &mut Parser) -> bool { + let mut found_expr = false; + while !p.at(COMMA) { + if expr(p).is_none() { + break; + } + found_expr = true; + if !p.eat(COMMA) { + break; + } + } + found_expr +} + +const COMPOUND_SELECT_FIRST: TokenSet = TokenSet::new(&[UNION_KW, INTERSECT_KW, EXCEPT_KW]); + +// with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( select | values | insert | update | delete | merge ) +// [ SEARCH { BREADTH | DEPTH } FIRST BY column_name [, ...] SET search_seq_col_name ] +// [ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ] +fn with_query(p: &mut Parser<'_>) -> Option { + let m = p.start(); + name(p); + opt_column_list_with(p, ColumnDefKind::Name); + p.expect(AS_KW); + // [ [ NOT ] MATERIALIZED ] + if p.eat(NOT_KW) { + p.expect(MATERIALIZED_KW); + } else { + p.eat(MATERIALIZED_KW); + } + p.expect(L_PAREN); + match p.current() { + DELETE_KW => { + delete_stmt(p, None); + } + SELECT_KW | TABLE_KW | VALUES_KW => { + select_stmt(p, None); + } + INSERT_KW => { + insert_stmt(p, None); + } + UPDATE_KW => { + update_stmt(p, None); + } + MERGE_KW => { + merge_stmt(p, None); + } + WITH_KW => { + with_stmt(p, None); + } + _ => { + p.error(format!( + "expected DELETE, SELECT, TABLE, VALUES, INSERT, WITH, or UPDATE, got: {:?}", + p.current() + )); + } + } + p.expect(R_PAREN); + // [ SEARCH { BREADTH | DEPTH } FIRST BY column_name [, ...] SET search_seq_col_name ] + if p.eat(SEARCH_KW) { + if !p.eat(BREADTH_KW) { + p.expect(DEPTH_KW); + } + p.expect(FIRST_KW); + p.expect(BY_KW); + while !p.at(EOF) && !p.at(COMMA) { + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(SET_KW); + name_ref(p); + } + // [ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ] + if p.eat(CYCLE_KW) { + while !p.at(EOF) && !p.at(COMMA) { + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(SET_KW); + name_ref(p); + if p.eat(TO_KW) { + // TODO: we should limit this more + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(DEFAULT_KW); + // TODO: we should limit this more + if expr(p).is_none() { + p.error("expected an expression"); + } + } + p.expect(USING_KW); + name_ref(p); + } + Some(m.complete(p, WITH_TABLE)) +} + +const WITH_STMT_FOLLOW: TokenSet = TokenSet::new(&[ + DELETE_KW, SELECT_KW, TABLE_KW, INSERT_KW, UPDATE_KW, MERGE_KW, +]); + +// [ WITH [ RECURSIVE ] with_query [, ...] ] +fn with_query_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + p.expect(WITH_KW); + p.eat(RECURSIVE_KW); + while !p.at(EOF) { + if with_query(p).is_none() { + p.error("expected with_query"); + } + if p.at(COMMA) && p.nth_at_ts(1, WITH_STMT_FOLLOW) { + p.err_and_bump("unexpected comma"); + break; + } + if !p.eat(COMMA) { + break; + } + } + Some(m.complete(p, WITH_CLAUSE)) +} + +fn select_clause(p: &mut Parser<'_>) -> CompletedMarker { + let m = p.start(); + // normal select stmts + p.expect(SELECT_KW); + // select 1 + 1; + // ^ + // select all + // ^^^ + // select distinct + // ^^^^^^^^ + opt_all_or_distinct(p); + opt_target_list(p); + m.complete(p, SELECT_CLAUSE) +} + +fn compound_select(p: &mut Parser<'_>, cm: CompletedMarker) -> CompletedMarker { + assert!(p.at_ts(COMPOUND_SELECT_FIRST)); + let m = cm.precede(p); + p.bump_any(); + if !p.eat(ALL_KW) { + p.eat(DISTINCT_KW); + } + select_stmt(p, None); + m.complete(p, COMPOUND_SELECT) +} + +// error recovery: +// - +/// +fn select_stmt(p: &mut Parser, m: Option) -> Option { + assert!(p.at_ts(SELECT_FIRST)); + let m = m.unwrap_or_else(|| p.start()); + // table [only] name [*] + if p.eat(TABLE_KW) { + relation_name(p); + return Some(m.complete(p, SELECT)); + } + // with aka cte + // [ WITH [ RECURSIVE ] with_query [, ...] ] + if p.at(WITH_KW) { + return with_stmt(p, Some(m)); + } + if p.at(VALUES_KW) { + let cm = values_clause(p, Some(m)); + if p.at_ts(COMPOUND_SELECT_FIRST) { + return Some(compound_select(p, cm)); + } else { + return Some(cm); + } + } + select_clause(p); + let is_select_into = opt_into_clause(p).is_some(); + opt_from_clause(p); + opt_where_clause(p); + opt_group_by_clause(p); + opt_having_clause(p); + opt_window_clause(p); + if p.at_ts(COMPOUND_SELECT_FIRST) { + let cm = m.complete(p, SELECT); + return Some(compound_select(p, cm)); + } + opt_order_by_clause(p); + let mut has_locking_clause = false; + while p.at(FOR_KW) { + if opt_locking_clause(p).is_some() { + has_locking_clause = true; + } + } + opt_limit_clause(p); + opt_offset_clause(p); + opt_fetch_clause(p); + if !has_locking_clause { + while p.at(FOR_KW) { + opt_locking_clause(p); + } + } + Some(m.complete( + p, + if is_select_into { + SELECT_INTO_STMT + } else { + SELECT + }, + )) +} + +// INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] new_table +fn opt_into_clause(p: &mut Parser<'_>) -> Option { + if p.at(INTO_KW) { + let m = p.start(); + p.bump(INTO_KW); + let _ = opt_temp(p) || p.eat(UNLOGGED_KW); + p.eat(TABLE_KW); + path_name(p); + Some(m.complete(p, INTO_CLAUSE)) + } else { + None + } +} + +fn lock_strength(p: &mut Parser<'_>) -> bool { + // NO KEY UPDATE + if p.eat(NO_KW) { + p.expect(KEY_KW); + p.expect(UPDATE_KW) + // KEY SHARE + } else if p.eat(KEY_KW) { + p.expect(SHARE_KW) + // SHARE + } else if !p.eat(SHARE_KW) { + // UPDATE + p.expect(UPDATE_KW) + } else { + false + } +} + +fn opt_locking_clause(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if !p.eat(FOR_KW) { + m.abandon(p); + return None; + } + lock_strength(p); + if p.eat(OF_KW) { + while !p.at(EOF) && !p.at(SEMICOLON) { + if expr(p).is_none() { + p.error("expected an expression"); + } + if !p.eat(COMMA) { + break; + } + } + } + if p.eat(SKIP_KW) { + p.expect(LOCKED_KW) + } else { + p.eat(NOWAIT_KW) + }; + Some(m.complete(p, LOCKING_CLAUSE)) +} + +// FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } +fn opt_fetch_clause(p: &mut Parser<'_>) -> bool { + if !p.eat(FETCH_KW) { + return false; + } + // { FIRST | NEXT } + if p.at(FIRST_KW) || p.at(NEXT_KW) { + p.bump_any(); + } else { + p.error("expected first or next"); + } + // [ count ] + if expr(p).is_none() { + p.error("expected an expression"); + } + // { ROW | ROWS } + if !p.eat(ROW_KW) { + p.expect(ROWS_KW); + } + // { ONLY | WITH TIES } + if p.eat(WITH_KW) { + p.expect(TIES_KW); + } else { + p.expect(ONLY_KW); + } + true +} + +fn opt_order_by_clause(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if !p.eat(ORDER_KW) { + m.abandon(p); + return false; + } + p.expect(BY_KW); + while !p.at(EOF) { + if expr(p).is_none() { + p.error("expected an expression"); + } + // ASC | DESC | USING operator + if p.at(ASC_KW) || p.at(DESC_KW) { + p.bump_any(); + } else if p.eat(USING_KW) { + operator(p); + } + // NULLS {FIRST | LAST} + if p.eat(NULLS_KW) { + if p.at(FIRST_KW) || p.at(LAST_KW) { + p.bump_any(); + } else { + p.error("expected FIRST or LAST following NULLS"); + } + } + if !p.eat(COMMA) { + break; + } + } + m.complete(p, ORDER_BY_CLAUSE); + true +} + +const JOIN_TYPE_FIRST: TokenSet = TokenSet::new(&[INNER_KW, JOIN_KW, LEFT_KW, RIGHT_KW, FULL_KW]); + +// where join_type is: +// [ INNER ] JOIN +// LEFT [ OUTER ] JOIN +// RIGHT [ OUTER ] JOIN +// FULL [ OUTER ] JOIN +fn join_type(p: &mut Parser<'_>) -> bool { + assert!(p.at_ts(JOIN_TYPE_FIRST)); + if p.eat(INNER_KW) { + p.expect(JOIN_KW) + } else if p.eat(LEFT_KW) || p.eat(RIGHT_KW) || p.eat(FULL_KW) { + p.eat(OUTER_KW); + p.expect(JOIN_KW) + } else { + p.expect(JOIN_KW) + } +} + +const JOIN_FIRST: TokenSet = TokenSet::new(&[NATURAL_KW, CROSS_KW]).union(JOIN_TYPE_FIRST); + +fn opt_from_clause(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if !p.eat(FROM_KW) { + m.abandon(p); + return false; + } + while !p.at(EOF) { + if !opt_from_item(p) { + m.complete(p, FROM_CLAUSE); + return false; + } + // foo, bar, buzz + // ^ + if !p.eat(COMMA) { + break; + } + } + m.complete(p, FROM_CLAUSE); + true +} + +// https://github.com/postgres/postgres/blob/b3219c69fc1e161df8d380c464b3f2cce3b6cab9/src/backend/parser/gram.y#L18042 +const COL_NAME_KEYWORD_FIRST: TokenSet = TokenSet::new(&[ + BETWEEN_KW, + BIGINT_KW, + BIT_KW, + BOOLEAN_KW, + CHAR_KW, + CHARACTER_KW, + COALESCE_KW, + DEC_KW, + DECIMAL_KW, + EXISTS_KW, + EXTRACT_KW, + FLOAT_KW, + GREATEST_KW, + GROUPING_KW, + INOUT_KW, + INT_KW, + INTEGER_KW, + INTERVAL_KW, + JSON_KW, + JSON_ARRAY_KW, + JSON_ARRAYAGG_KW, + JSON_EXISTS_KW, + JSON_OBJECT_KW, + JSON_OBJECTAGG_KW, + JSON_QUERY_KW, + JSON_SCALAR_KW, + JSON_SERIALIZE_KW, + JSON_TABLE_KW, + JSON_VALUE_KW, + LEAST_KW, + MERGE_ACTION_KW, + NATIONAL_KW, + NCHAR_KW, + NONE_KW, + NORMALIZE_KW, + NULLIF_KW, + NUMERIC_KW, + OUT_KW, + OVERLAY_KW, + POSITION_KW, + PRECISION_KW, + REAL_KW, + ROW_KW, + SETOF_KW, + SMALLINT_KW, + SUBSTRING_KW, + TIME_KW, + TIMESTAMP_KW, + TREAT_KW, + TRIM_KW, + VALUES_KW, + VARCHAR_KW, + XMLATTRIBUTES_KW, + XMLCONCAT_KW, + XMLELEMENT_KW, + XMLEXISTS_KW, + XMLFOREST_KW, + XMLNAMESPACES_KW, + XMLPARSE_KW, + XMLPI_KW, + XMLROOT_KW, + XMLSERIALIZE_KW, + XMLTABLE_KW, +]); + +// https://github.com/postgres/postgres/blob/2421e9a51d20bb83154e54a16ce628f9249fa907/src/backend/parser/gram.y#L15798C13-L16258 +// Generated via the above grammar, but we only take the keywords that are +// single items. So `CURRENT_DATE` but not `COLLATION FOR '(' a_expr ')'` +const FUNC_EXPR_COMMON_SUBEXPR_FIRST: TokenSet = TokenSet::new(&[ + CURRENT_DATE_KW, + CURRENT_TIME_KW, + CURRENT_TIMESTAMP_KW, + LOCALTIME_KW, + LOCALTIMESTAMP_KW, + CURRENT_ROLE_KW, + CURRENT_USER_KW, + SESSION_USER_KW, + SYSTEM_USER_KW, + USER_KW, + CURRENT_CATALOG_KW, + CURRENT_SCHEMA_KW, +]); + +const FROM_ITEM_KEYWORDS_FIRST: TokenSet = TokenSet::new(&[]) + .union(UNRESERVED_KEYWORDS) + .union(COL_NAME_KEYWORD_FIRST) + .union(FUNC_EXPR_COMMON_SUBEXPR_FIRST); + +const FROM_ITEM_FIRST: TokenSet = TokenSet::new(&[ + ONLY_KW, // optional + IDENT, // table_name, with_query_name, function_name + L_PAREN, // nested select stmt + LATERAL_KW, // optional + ROWS_KW, // rows from +]) +.union(FROM_ITEM_KEYWORDS_FIRST); + +fn from_item_name(p: &mut Parser<'_>) { + match name_ref_(p).map(|lhs| postfix_expr(p, lhs, true)) { + Some(val) => match val.kind() { + CALL_EXPR => { + // [ WITH ORDINALITY ] + // [ [ AS ] alias [ ( column_alias [, ...] ) ] ] + // [ AS ] alias ( column_definition [, ...] ) + // AS ( column_definition [, ...] ) + // TODO: we should use this to inform parsing down below + if p.eat(WITH_KW) { + p.expect(ORDINALITY_KW); + } + opt_alias(p); + } + NAME_REF | FIELD_EXPR => { + // [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] + // [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] + // + // [ [ AS ] alias [ ( column_alias [, ...] ) ] ] + // we're at a table_name + p.eat(STAR); + opt_alias(p); + // [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] + if p.eat(TABLESAMPLE_KW) { + call_expr(p); + if p.eat(REPEATABLE_KW) { + p.eat(R_PAREN); + if expr(p).is_none() { + p.error("expected a seed"); + } + p.eat(L_PAREN); + } + } + } + got => { + p.error(format!("expected a name, got {:?}", got)); + } + }, + None => p.error("expected name"), + } +} + +fn data_source(p: &mut Parser<'_>) { + p.eat(ONLY_KW); + p.eat(LATERAL_KW); + match p.current() { + L_PAREN => { + p.bump(L_PAREN); + // we're at the start of a nested select statement + select_stmt(p, None); + p.expect(R_PAREN); + opt_alias(p); + } + JSON_TABLE_KW => { + json_table_fn(p); + opt_alias(p); + } + ROWS_KW => { + p.bump(ROWS_KW); + p.expect(FROM_KW); + p.expect(L_PAREN); + call_expr(p); + // TODO: we should restrict this more + opt_alias(p); + p.expect(R_PAREN); + // [ WITH ORDINALITY ] + if p.eat(WITH_KW) { + p.expect(ORDINALITY_KW); + } + // TODO: we should only alow col_alias, not def + opt_alias(p); + } + IDENT => from_item_name(p), + _ if p.at_ts(FROM_ITEM_KEYWORDS_FIRST) => from_item_name(p), + _ => {} + } +} + +// USING data_source ON join_condition +fn merge_using_clause(p: &mut Parser<'_>) { + let m1 = p.start(); + p.expect(USING_KW); + data_source(p); + p.expect(ON_KW); + // join_condition + if expr(p).is_none() { + p.error("expected an expression"); + } + m1.complete(p, USING_CLAUSE); +} + +// where from_item can be one of: +// +// [ LATERAL ] ( select ) [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// +// [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] +// +// with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// +// [ LATERAL ] function_name ( [ argument [, ...] ] ) +// [ WITH ORDINALITY ] +// [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// [ LATERAL ] function_name ( [ argument [, ...] ] ) +// [ AS ] alias ( column_definition [, ...] ) +// [ LATERAL ] function_name ( [ argument [, ...] ] ) +// AS ( column_definition [, ...] ) +// +// [ LATERAL ] ROWS FROM( +// function_name ( [ argument [, ...] ] ) [ AS ( column_definition [, ...] ) ] [, ...] +// ) +// [ WITH ORDINALITY ] +// [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// +// from_item join_type from_item { ON join_condition | USING ( join_column [, ...] ) [ AS join_using_alias ] } +// from_item NATURAL join_type from_item +// from_item CROSS JOIN from_item +// +// join_type is one of: +// +// [ INNER ] JOIN +// LEFT [ OUTER ] JOIN +// RIGHT [ OUTER ] JOIN +// FULL [ OUTER ] JOIN +// +#[must_use] +fn opt_from_item(p: &mut Parser<'_>) -> bool { + if !p.at_ts(FROM_ITEM_FIRST) { + return false; + } + data_source(p); + while p.at_ts(JOIN_FIRST) { + join(p); + } + true +} + +// we have a from_item +// +// join_type from_item { ON join_condition | USING ( join_column [, ...] ) [ AS join_using_alias ] } +// NATURAL join_type from_item +// CROSS JOIN from_item +// +// where join_type is: +// +// [ INNER ] JOIN +// LEFT [ OUTER ] JOIN +// RIGHT [ OUTER ] JOIN +// FULL [ OUTER ] JOIN +fn join(p: &mut Parser<'_>) { + assert!(p.at_ts(JOIN_FIRST)); + let m = p.start(); + if p.eat(NATURAL_KW) { + if !join_type(p) { + p.error("expected join type"); + } + if !opt_from_item(p) { + p.error("expected from_item"); + } + } else if p.eat(CROSS_KW) { + p.expect(JOIN_KW); + if !opt_from_item(p) { + p.error("expected from_item"); + } + } else { + if !join_type(p) { + p.error("expected join type"); + } + if !opt_from_item(p) { + p.error("expected from_item"); + } + if p.eat(ON_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + } else { + { + let m = p.start(); + // USING ( join_column [, ...] ) + p.expect(USING_KW); + if p.at(L_PAREN) { + tuple_expr(p); + } else { + p.error("expected L_PAREN"); + } + m.complete(p, USING_CLAUSE); + } + { + let m = p.start(); + // [ AS join_using_alias ] + if p.eat(AS_KW) { + name(p); + m.complete(p, ALIAS); + } else { + m.abandon(p); + } + } + } + } + m.complete(p, JOIN); +} + +#[must_use] +fn opt_numeric_literal(p: &mut Parser<'_>) -> Option { + if p.at_ts(NUMERIC_FIRST) { + let m = p.start(); + p.bump_any(); + Some(m.complete(p, LITERAL)) + } else if p.at(MINUS) && p.nth_at_ts(1, NUMERIC_FIRST) { + // TODO: is this a good idea? + expr(p) + } else { + None + } +} + +const SEQUENCE_OPTION_FIRST: TokenSet = TokenSet::new(&[ + AS_KW, + CACHE_KW, + INCREMENT_KW, + SEQUENCE_KW, + RESTART_KW, + LOGGED_KW, + UNLOGGED_KW, + START_KW, + OWNED_KW, + OWNED_KW, + MAXVALUE_KW, + MINVALUE_KW, + NO_KW, + CYCLE_KW, +]); + +// [ AS data_type ] +// [ CACHE cache ] +// [ INCREMENT [ BY ] increment ] +// [ SEQUENCE NAME name ] +// [ RESTART [ [ WITH ] NUMERIC ] ] +// [ LOGGED UNLOGGED ] +// [ START [ WITH ] start ] +// [ OWNED BY { table_name.column_name | NONE } ] +// [ MAXVALUE maxvalue ] +// [ MINVALUE maxvalue ] +// [ NO MINVALUE | NO CYCLE | NO MAXVALUE ] +// [ CYCLE ] +fn opt_sequence_option(p: &mut Parser<'_>) -> bool { + if !p.at_ts(SEQUENCE_OPTION_FIRST) { + return false; + } + match p.current() { + AS_KW => { + p.bump(AS_KW); + type_name(p); + } + INCREMENT_KW => { + p.bump(INCREMENT_KW); + p.eat(BY_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + } + SEQUENCE_KW => { + p.bump(SEQUENCE_KW); + p.expect(NAME_KW); + name_ref(p); + } + RESTART_KW => { + p.bump(RESTART_KW); + if p.eat(WITH_KW) { + if opt_numeric_literal(p).is_none() { + p.error("expected numeric"); + } + } else { + let _ = opt_numeric_literal(p); + } + } + LOGGED_KW | UNLOGGED_KW => { + p.bump_any(); + } + START_KW => { + p.bump(START_KW); + p.eat(WITH_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric"); + } + } + OWNED_KW => { + p.bump(OWNED_KW); + p.expect(BY_KW); + if !p.eat(NONE_KW) { + path_name_ref(p); + } + } + MINVALUE_KW | MAXVALUE_KW | CACHE_KW => { + p.bump_any(); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric"); + } + } + NO_KW => { + p.bump(NO_KW); + if !p.eat(MINVALUE_KW) && !p.eat(CYCLE_KW) && !p.eat(MAXVALUE_KW) { + p.error("expected MINVALUE, MAXVALUE, or CYCLE"); + } + } + CYCLE_KW => { + p.bump(CYCLE_KW); + } + _ => return false, + } + true +} + +fn opt_sequence_options(p: &mut Parser<'_>) -> bool { + if p.at(L_PAREN) { + let m = p.start(); + p.bump(L_PAREN); + while !p.at(EOF) { + // TODO: make sure we have at least one + if !opt_sequence_option(p) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, SEQUENCE_OPTION_LIST); + true + } else { + false + } +} + +// storage_parameter [= value] +fn storage_parameter(p: &mut Parser<'_>) -> bool { + // storage_parameter + path_name_ref(p); + // [= value] + if p.eat(EQ) && !def_arg(p) { + p.error("expected a value for storage parameter"); + return false; + } + true +} + +enum ColumnDefKind { + Name, + Ref, + WithData, +} + +// select * from f() as t(a, b); +// ^^^^^^ +// select * from f() as t(a int, b text, c text collate foo.bar.buzz); +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// [ ( column_name [, ... ] ) ] +fn opt_column_list_with(p: &mut Parser<'_>, kind: ColumnDefKind) -> bool { + if !p.at(L_PAREN) { + return false; + } + let m = p.start(); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if p.at(COMMA) { + p.err_and_bump("missing column"); + continue; + } + if !p.at_ts(COLUMN_FIRST) { + break; + } + column(p, &kind); + if p.at(COMMA) && p.nth_at(1, R_PAREN) { + p.err_and_bump("unexpected trailing comma"); + } + if !p.eat(COMMA) { + if p.at_ts(COLUMN_FIRST) && !(p.at(WITHOUT_KW) && p.nth_at(1, OVERLAPS_KW)) { + p.error("expected COMMA"); + } else { + break; + } + } + } + opt_without_overlaps(p); + p.expect(R_PAREN); + m.complete(p, COLUMN_LIST); + return true; +} + +fn column(p: &mut Parser<'_>, kind: &ColumnDefKind) -> CompletedMarker { + assert!(p.at_ts(COLUMN_FIRST)); + let m = p.start(); + // https://www.depesz.com/2024/10/03/waiting-for-postgresql-18-add-temporal-foreign-key-contraints/ + // TODO: add validation to ensure this is in the right position + p.eat(PERIOD_KW); + match kind { + ColumnDefKind::Name => name(p), + ColumnDefKind::Ref => { + // support parsing things like: + // INSERT INTO tictactoe (game, board[1:3][1:3]) + name_ref(p).map(|lhs| postfix_expr(p, lhs, true)); + } + ColumnDefKind::WithData => { + name(p); + if !p.at(COMMA) && !p.at(R_PAREN) { + if !opt_type_name(p) { + return m.complete(p, COLUMN); + } + opt_collate(p); + } + } + } + m.complete(p, COLUMN) +} + +// [ ( column_name [, ... ] ) ] +fn opt_column_list(p: &mut Parser<'_>) -> bool { + opt_column_list_with(p, ColumnDefKind::Ref) +} + +fn column_list(p: &mut Parser<'_>) { + if !opt_column_list(p) { + p.error("expected column list"); + } +} + +fn opt_include_columns(p: &mut Parser<'_>) -> Option { + if p.at(INCLUDE_KW) { + let m = p.start(); + p.bump(INCLUDE_KW); + column_list(p); + Some(m.complete(p, CONSTRAINT_INCLUDE_CLAUSE)) + } else { + None + } +} + +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +fn opt_with_params(p: &mut Parser<'_>) -> Option { + if p.at(WITH_KW) { + let m = p.start(); + p.bump(WITH_KW); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !storage_parameter(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + Some(m.complete(p, CONSTRAINT_STORAGE_PARAMS)) + } else { + None + } +} + +// index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +// [ INCLUDE ( column_name [, ... ] ) ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ USING INDEX TABLESPACE tablespace_name ] +#[must_use] +fn opt_index_parameters(p: &mut Parser<'_>) -> bool { + opt_include_columns(p); + opt_with_params(p); + if p.at(USING_KW) { + let m = p.start(); + p.bump(USING_KW); + p.expect(INDEX_KW); + p.expect(TABLESPACE_KW); + name_ref(p); + m.complete(p, CONSTRAINT_INDEX_TABLESPACE); + } + true +} + +// referential_action in a FOREIGN KEY/REFERENCES constraint is: +// { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } +fn referential_action(p: &mut Parser<'_>) -> bool { + if p.eat(NO_KW) { + p.expect(ACTION_KW) + } else if opt_cascade_or_restrict(p) { + true + } else if p.at(SET_KW) && p.nth_at(1, NULL_KW) { + p.expect(SET_KW); + p.expect(NULL_KW); + opt_column_list(p); + true + } else if p.eat(SET_KW) { + p.expect(DEFAULT_KW); + if p.eat(L_PAREN) { + // column_name [, ... ] + while !p.at(EOF) && !p.at(COMMA) { + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + return p.expect(R_PAREN); + } + true + } else { + false + } +} + +const COLUMN_CONSTRAINT_FIRST: TokenSet = TokenSet::new(&[ + CONSTRAINT_KW, + NOT_KW, + NULL_KW, + CHECK_KW, + DEFAULT_KW, + GENERATED_KW, + UNIQUE_KW, + PRIMARY_KW, + REFERENCES_KW, +]); + +// where column_constraint is: + +// [ CONSTRAINT constraint_name ] +// +// { NOT NULL | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) STORED | +// GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | +// UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | +// PRIMARY KEY index_parameters | +// REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] +// [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } +// +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] +fn opt_column_constraint(p: &mut Parser<'_>) -> Option { + if !p.at_ts(COLUMN_CONSTRAINT_FIRST) { + return None; + } + let m = p.start(); + if p.eat(CONSTRAINT_KW) { + name_ref(p); + } + match opt_constraint_inner(p) { + Some(kind) => { + opt_constraint_options(p); + Some(m.complete(p, kind)) + } + None => { + m.abandon(p); + p.error("expected constraint type"); + None + } + } +} + +// { NOT NULL | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) STORED | +// GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | +// UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | +// PRIMARY KEY index_parameters | +// REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] +// [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } +fn opt_constraint_inner(p: &mut Parser<'_>) -> Option { + let kind = match p.current() { + NOT_KW => { + p.bump(NOT_KW); + p.expect(NULL_KW); + NOT_NULL_CONSTRAINT + } + NULL_KW => { + p.bump(NULL_KW); + NULL_CONSTRAINT + } + CHECK_KW => { + p.bump(CHECK_KW); + p.expect(L_PAREN); + // generation_expr + // The generation expression can refer to other columns in the table, + // but not other generated columns. Any functions and operators used + // must be immutable. References to other tables are not allowed. + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + if p.eat(NO_KW) { + p.expect(INHERIT_KW); + } + CHECK_CONSTRAINT + } + DEFAULT_KW => { + p.bump(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected expr for default"); + } + DEFAULT_CONSTRAINT + } + GENERATED_KW => { + p.bump(GENERATED_KW); + // ALWAYS AS ( generation_expr ) STORED + if p.at(ALWAYS_KW) && p.nth_at(1, AS_KW) && p.nth_at(2, L_PAREN) { + p.expect(ALWAYS_KW); + p.expect(AS_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_PAREN); + p.expect(STORED_KW); + GENERATED_CONSTRAINT + // { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] + } else if p.at(ALWAYS_KW) || p.at(BY_KW) { + if p.eat(BY_KW) { + p.expect(DEFAULT_KW); + } else { + p.expect(ALWAYS_KW); + } + p.expect(AS_KW); + p.expect(IDENTITY_KW); + opt_sequence_options(p); + GENERATED_CONSTRAINT + } else { + p.error("expected generated type"); + return None; + } + } + // UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters + UNIQUE_KW => { + p.bump(UNIQUE_KW); + if p.eat(NULLS_KW) { + p.eat(NOT_KW); + p.expect(DISTINCT_KW); + } + if !opt_index_parameters(p) { + p.error("expected index parameters"); + } + UNIQUE_CONSTRAINT + } + // PRIMARY KEY index_parameters + PRIMARY_KW => { + p.bump(PRIMARY_KW); + p.expect(KEY_KW); + if !opt_index_parameters(p) { + p.error("expected index parameters"); + } + PRIMARY_KEY_CONSTRAINT + } + // REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] + // [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } + REFERENCES_KW => { + p.bump(REFERENCES_KW); + path_name_ref(p); + if p.eat(L_PAREN) { + name_ref(p); + p.expect(R_PAREN); + } + if p.eat(MATCH_KW) { + if p.at(FULL_KW) || p.at(PARTIAL_KW) || p.at(SIMPLE_KW) { + p.bump_any(); + } else { + p.error("expected FULL, PARTIAL, or SIMPLE"); + } + } + // [ ON DELETE referential_action ] + if p.at(ON_KW) && p.nth_at(1, DELETE_KW) { + p.expect(ON_KW); + p.expect(DELETE_KW); + referential_action(p); + } + // [ ON UPDATE referential_action ] + if p.at(ON_KW) && p.nth_at(1, UPDATE_KW) { + p.expect(ON_KW); + p.expect(UPDATE_KW); + referential_action(p); + } + // [ ON DELETE referential_action ] + if p.at(ON_KW) && p.nth_at(1, DELETE_KW) { + p.expect(ON_KW); + p.expect(DELETE_KW); + referential_action(p); + } + REFERENCES_CONSTRAINT + } + _ => { + return None; + } + }; + Some(kind) +} + +const LIKE_OPTION: TokenSet = TokenSet::new(&[ + COMMENTS_KW, + COMPRESSION_KW, + CONSTRAINTS_KW, + DEFAULTS_KW, + GENERATED_KW, + IDENTITY_KW, + INDEXES_KW, + STATISTICS_KW, + STORAGE_KW, + ALL_KW, +]); + +// where like_option is: +// { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } +fn like_option(p: &mut Parser<'_>) -> bool { + if p.at(INCLUDING_KW) || p.at(EXCLUDING_KW) { + p.bump_any(); + if p.at_ts(LIKE_OPTION) { + p.bump_any(); + } else { + p.error("expected like option"); + } + true + } else { + false + } +} + +// index_elem: +// | ColId index_elem_options +// | func_expr_windowless index_elem_options +// | '(' a_expr ')' index_elem_options +fn index_elem(p: &mut Parser<'_>) { + if p.eat(L_PAREN) { + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(R_PAREN); + } else { + if expr(p).is_none() { + p.error("expected expression"); + } + } +} + +#[derive(PartialEq, Eq, Clone, Copy)] +enum ColDefType { + WithData, + ColumnNameOnly, +} + +fn opt_operator(p: &mut Parser<'_>) -> bool { + let (power, kind, _) = current_op(p, &Restrictions::default()); + if power == 0 { + if p.at_ts(OPERATOR_FIRST) { + p.bump_any(); + return true; + } + return false; + } + p.eat(kind) +} + +// optional schema supported +// > +// bar.> +// foo.bar.> +fn operator(p: &mut Parser<'_>) { + opt_path_name_ref(p); + if !opt_operator(p) { + p.error(format!("expected operator, got {:?}", p.current())); + } +} + +pub(crate) fn current_operator(p: &Parser<'_>) -> Option { + let (power, kind, _) = current_op(p, &Restrictions::default()); + if power == 0 { + None + } else { + Some(kind) + } +} + +fn using_index(p: &mut Parser<'_>) { + let m = p.start(); + p.bump(USING_KW); + p.expect(INDEX_KW); + name_ref(p); + m.complete(p, USING_INDEX); +} + +const TABLE_CONSTRAINT_FIRST: TokenSet = TokenSet::new(&[ + CONSTRAINT_KW, + CHECK_KW, + UNIQUE_KW, + PRIMARY_KW, + EXCLUDE_KW, + FOREIGN_KW, +]); + +// and table_constraint is: +// [ CONSTRAINT constraint_name ] +// { CHECK ( expression ) [ NO INHERIT ] | +// UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | +// PRIMARY KEY ( column_name [, ... ] ) index_parameters | +// EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | +// FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] +// [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] +// +// and table_constraint_using_index is: +// [ CONSTRAINT constraint_name ] +// { UNIQUE | PRIMARY KEY } USING INDEX index_name +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] +fn table_constraint(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at_ts(TABLE_CONSTRAINT_FIRST)); + let m = p.start(); + // [ CONSTRAINT constraint_name ] + if p.eat(CONSTRAINT_KW) { + name(p); + } + // CHECK ( expression ) [ NO INHERIT ] + let kind = match p.current() { + CHECK_KW => { + p.bump(CHECK_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expr"); + } + p.expect(R_PAREN); + if p.eat(NO_KW) { + p.expect(INHERIT_KW); + } + CHECK_CONSTRAINT + } + // UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters + // UNIQUE USING INDEX index_name + UNIQUE_KW => { + p.bump(UNIQUE_KW); + // USING INDEX index_name + if p.at(USING_KW) { + using_index(p); + // [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters + } else { + if p.eat(NULLS_KW) { + p.eat(NOT_KW); + p.eat(DISTINCT_KW); + } + column_list(p); + if !opt_index_parameters(p) { + p.error("expected index parameters"); + } + } + UNIQUE_CONSTRAINT + } + // PRIMARY KEY ( column_name [, ... ] ) index_parameters + // PRIMARY KEY USING INDEX index_name + PRIMARY_KW => { + p.bump(PRIMARY_KW); + p.expect(KEY_KW); + // USING INDEX index_name + if p.at(USING_KW) { + using_index(p); + // ( column_name [, ... ] ) index_parameters + } else { + column_list(p); + if !opt_index_parameters(p) { + p.error("expected index parameters"); + } + } + PRIMARY_KEY_CONSTRAINT + } + // EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | + EXCLUDE_KW => { + p.bump(EXCLUDE_KW); + if p.at(USING_KW) { + let m = p.start(); + p.bump(USING_KW); + name_ref(p); + m.complete(p, CONSTRAINT_INDEX_METHOD); + } + let m = p.start(); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + index_elem(p); + p.expect(WITH_KW); + // support: + // with > + // with foo.bar.buzz.> + operator(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CONSTRAINT_EXCLUSIONS); + if !opt_index_parameters(p) { + p.error("expected index parameters"); + } + if p.at(WHERE_KW) { + let m = p.start(); + p.bump(WHERE_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expr"); + } + p.expect(R_PAREN); + m.complete(p, CONSTRAINT_WHERE_CLAUSE); + } + EXCLUDE_CONSTRAINT + } + // FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] + // [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } + _ => { + // must be in a foreign key constraint + p.expect(FOREIGN_KW); + p.expect(KEY_KW); + column_list(p); + p.expect(REFERENCES_KW); + path_name_ref(p); + if p.eat(L_PAREN) { + while !p.at(EOF) && !p.at(COMMA) { + let found_period = p.eat(PERIOD_KW); + name_ref(p); + if found_period { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + if p.eat(MATCH_KW) { + if p.at(FULL_KW) || p.at(PARTIAL_KW) || p.at(SIMPLE_KW) { + p.bump_any(); + } else { + p.error("expected FULL, PARTIAL, or SIMPLE"); + } + } + // [ ON DELETE referential_action ] + if p.eat(ON_KW) { + p.expect(DELETE_KW); + referential_action(p); + } + // [ ON UPDATE referential_action ] + if p.eat(ON_KW) { + p.expect(UPDATE_KW); + referential_action(p); + } + FOREIGN_KEY_CONSTRAINT + } + }; + opt_constraint_options(p); + m.complete(p, kind) +} + +fn opt_without_overlaps(p: &mut Parser<'_>) { + if p.eat(WITHOUT_KW) { + p.expect(OVERLAPS_KW); + } +} + +fn opt_deferrable_constraint_option(p: &mut Parser<'_>) -> Option { + let m = p.start(); + let kind = match (p.current(), p.nth(1)) { + (DEFERRABLE_KW, _) => { + p.bump(DEFERRABLE_KW); + DEFERRABLE_CONSTRAINT_OPTION + } + (NOT_KW, DEFERRABLE_KW) => { + p.bump(NOT_KW); + p.bump(DEFERRABLE_KW); + NOT_DEFERRABLE_CONSTRAINT_OPTION + } + _ => { + m.abandon(p); + return None; + } + }; + Some(m.complete(p, kind)) +} + +fn opt_initally_constraint_option(p: &mut Parser<'_>) -> Option { + let m = p.start(); + let kind = match (p.current(), p.nth(1)) { + (INITIALLY_KW, DEFERRED_KW) => { + p.bump(INITIALLY_KW); + p.bump(DEFERRED_KW); + INITALLY_DEFERRED_CONSTRAINT_OPTION + } + (INITIALLY_KW, IMMEDIATE_KW) => { + p.bump(INITIALLY_KW); + p.bump(IMMEDIATE_KW); + INITIALLY_IMMEDIATE_CONSTRAINT_OPTION + } + _ => { + m.abandon(p); + return None; + } + }; + Some(m.complete(p, kind)) +} + +// [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] +fn opt_constraint_options(p: &mut Parser<'_>) { + let m = p.start(); + let deferrable = opt_deferrable_constraint_option(p); + let initially = opt_initally_constraint_option(p); + + match (deferrable, initially) { + (None, None) => { + m.abandon(p); + return; + } + (Some(deferrable), Some(initially)) => { + if deferrable.kind() == NOT_DEFERRABLE_CONSTRAINT_OPTION + && initially.kind() == INITALLY_DEFERRED_CONSTRAINT_OPTION + { + p.error("constraint declared INITIALLY DEFERRED must be DEFERRABLE"); + } + } + (_, _) => (), + } + m.complete(p, CONSTRAINT_OPTION_LIST); +} + +const COLUMN_NAME_KEYWORDS: TokenSet = TokenSet::new(&[ + BETWEEN_KW, + BIGINT_KW, + BIT_KW, + BOOLEAN_KW, + CHAR_KW, + CHARACTER_KW, + COALESCE_KW, + DEC_KW, + DECIMAL_KW, + EXISTS_KW, + EXTRACT_KW, + FLOAT_KW, + GREATEST_KW, + GROUPING_KW, + INOUT_KW, + INT_KW, + INTEGER_KW, + INTERVAL_KW, + JSON_KW, + JSON_ARRAY_KW, + JSON_ARRAYAGG_KW, + JSON_EXISTS_KW, + JSON_OBJECT_KW, + JSON_OBJECTAGG_KW, + JSON_QUERY_KW, + JSON_SCALAR_KW, + JSON_SERIALIZE_KW, + JSON_TABLE_KW, + JSON_VALUE_KW, + LEAST_KW, + MERGE_ACTION_KW, + NATIONAL_KW, + NCHAR_KW, + NONE_KW, + NORMALIZE_KW, + NULLIF_KW, + NUMERIC_KW, + OUT_KW, + OVERLAY_KW, + POSITION_KW, + PRECISION_KW, + REAL_KW, + ROW_KW, + SETOF_KW, + SMALLINT_KW, + SUBSTRING_KW, + TIME_KW, + TIMESTAMP_KW, + TREAT_KW, + TRIM_KW, + VALUES_KW, + VARCHAR_KW, + XMLATTRIBUTES_KW, + XMLCONCAT_KW, + XMLELEMENT_KW, + XMLEXISTS_KW, + XMLFOREST_KW, + XMLNAMESPACES_KW, + XMLPARSE_KW, + XMLPI_KW, + XMLROOT_KW, + XMLSERIALIZE_KW, + XMLTABLE_KW, +]); + +// column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] +// { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] +// | table_constraint +// | LIKE source_table [ like_option ... ] } +fn col_def(p: &mut Parser<'_>, t: ColDefType) -> Option { + if !(p.at(LIKE_KW) + || p.at_ts(TABLE_CONSTRAINT_FIRST) + // ColId + || p.at_ts(NAME_FIRST)) + { + return None; + } + let m = p.start(); + // LIKE source_table [ like_option ... ] + if t == ColDefType::WithData && p.eat(LIKE_KW) { + path_name_ref(p); + while !p.at(EOF) { + if !like_option(p) { + break; + } + } + return Some(m.complete(p, LIKE_CLAUSE)); + } + if p.at_ts(TABLE_CONSTRAINT_FIRST) { + m.abandon(p); + return Some(table_constraint(p)); + } + name_ref(p); + match t { + ColDefType::WithData => { + type_name(p); + // [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] + if p.eat(STORAGE_KW) && (p.at(DEFAULT_KW) || p.at(IDENT)) { + p.bump_any(); + } + // [ COMPRESSION compression_method ] + if p.eat(COMPRESSION_KW) && (p.at(DEFAULT_KW) || p.at(IDENT)) { + p.bump_any(); + } + opt_collate(p); + } + ColDefType::ColumnNameOnly => { + // [ WITH OPTIONS ] + if p.eat(WITH_KW) { + p.expect(OPTIONS_KW); + } + } + } + // [ column_constraint [ ... ] ] + while !p.at(EOF) { + if opt_column_constraint(p).is_none() { + break; + } + } + Some(m.complete(p, COLUMN)) +} + +// [ AS ] alias [ ( column_alias [, ...] ) ] +// [ AS ] alias ( column_definition [, ...] ) +// AS ( column_definition [, ...] ) +fn opt_alias(p: &mut Parser<'_>) -> Option { + // TODO: we should split this into opt_col_def and opt_col_alias + if !(p.at(AS_KW) || p.at_ts(NAME_FIRST) || p.at(L_PAREN)) { + return None; + } + let m = p.start(); + p.eat(AS_KW); + // table_name(col1, col2, col3) + opt_name(p); + if p.at(L_PAREN) { + if !opt_column_list_with(p, ColumnDefKind::WithData) { + p.error("expected column list"); + } + } + Some(m.complete(p, ALIAS)) +} + +fn opt_where_clause(p: &mut Parser<'_>) -> bool { + if !p.at(WHERE_KW) { + return false; + } + let m = p.start(); + p.bump(WHERE_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + m.complete(p, WHERE_CLAUSE); + true +} + +/// +fn opt_group_by_clause(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if !p.eat(GROUP_KW) { + m.abandon(p); + return false; + } + p.expect(BY_KW); + if p.at(ALL_KW) || p.at(DISTINCT_KW) { + p.bump_any(); + } + // From pg docs: + // An expression used inside a grouping_element can be an input column name, + // or the name or ordinal number of an output column (SELECT list item), or + // an arbitrary expression formed from input-column values. In case of + // ambiguity, a GROUP BY name will be interpreted as an input-column name + // rather than an output column name. + while !p.at(EOF) && !p.at(SEMICOLON) { + // TODO: handle errors? + p.eat(ROLLUP_KW); + p.eat(CUBE_KW); + if p.eat(GROUPING_KW) { + p.expect(SETS_KW); + } + if expr(p).is_none() { + p.error("expected an expression"); + } + if !p.eat(COMMA) { + break; + } + } + m.complete(p, GROUP_BY_CLAUSE); + true +} + +/// +fn opt_having_clause(p: &mut Parser<'_>) -> bool { + if !p.at(HAVING_KW) { + return false; + } + let m = p.start(); + p.bump(HAVING_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + m.complete(p, HAVING_CLAUSE); + true +} + +// frame_start and frame_end can be one of +// UNBOUNDED PRECEDING +// UNBOUNDED FOLLOWING +// CURRENT ROW +// offset PRECEDING +// offset FOLLOWING +fn frame_start_end(p: &mut Parser<'_>) { + if p.eat(UNBOUNDED_KW) { + if p.at(PRECEDING_KW) || p.at(FOLLOWING_KW) { + p.bump_any(); + } else { + p.err_and_bump("expected preceding or following"); + } + } else if p.eat(CURRENT_KW) { + p.expect(ROW_KW); + } else { + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.at(PRECEDING_KW) || p.at(FOLLOWING_KW) { + p.bump_any(); + } else { + p.err_and_bump("expected preceding or following"); + } + } +} + +// and frame_exclusion can be one of +// EXCLUDE CURRENT ROW +// EXCLUDE GROUP +// EXCLUDE TIES +// EXCLUDE NO OTHERS +fn opt_frame_exclusion(p: &mut Parser<'_>) -> bool { + if !p.eat(EXCLUDE_KW) { + return false; + } + if p.eat(CURRENT_KW) { + p.expect(ROW_KW) + } else if p.eat(NO_KW) { + p.expect(OTHERS_KW) + } else if p.at(GROUP_KW) || p.at(TIES_KW) { + p.bump_any(); + true + } else { + p.err_and_bump("expected `group`, `current row`, `ties`, or `no others`"); + false + } +} + +const WINDOW_DEF_START: TokenSet = + TokenSet::new(&[IDENT, PARTITION_KW, ORDER_KW, RANGE_KW, ROWS_KW, GROUPS_KW]); + +// window_definition is +// [ existing_window_name ] +// [ PARTITION BY expression [, ...] ] +// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] +// [ frame_clause ] +// +// The frame_clause can be one of +// { RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ] +// { RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ] +fn window_definition(p: &mut Parser<'_>) -> bool { + if !p.at_ts(WINDOW_DEF_START) { + return false; + } + let m = p.start(); + p.eat(IDENT); + if p.eat(PARTITION_KW) { + p.expect(BY_KW); + if expr(p).is_none() { + p.error("expected an expression"); + } + } + opt_order_by_clause(p); + if p.at(RANGE_KW) || p.at(ROWS_KW) || p.at(GROUPS_KW) { + p.bump_any(); + if p.eat(BETWEEN_KW) { + frame_start_end(p); + p.expect(AND_KW); + frame_start_end(p); + opt_frame_exclusion(p); + } else { + frame_start_end(p); + opt_frame_exclusion(p); + } + } + m.complete(p, WINDOW_DEF); + true +} + +/// +fn opt_window_clause(p: &mut Parser<'_>) -> bool { + if !p.at(WINDOW_KW) { + return false; + } + let m = p.start(); + p.bump(WINDOW_KW); + p.expect(IDENT); + p.expect(AS_KW); + p.expect(L_PAREN); + window_definition(p); + p.expect(R_PAREN); + m.complete(p, WINDOW_CLAUSE); + true +} + +// [ LIMIT { count | ALL } ] +fn opt_limit_clause(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if !p.eat(LIMIT_KW) { + m.abandon(p); + return false; + } + if !p.eat(ALL_KW) && expr(p).is_none() { + p.error("expected an expression"); + } + m.complete(p, LIMIT_CLAUSE); + true +} + +// [ OFFSET start [ ROW | ROWS ] ] +fn opt_offset_clause(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if !p.eat(OFFSET_KW) { + m.abandon(p); + return false; + } + if expr(p).is_none() { + p.error("expected an expression"); + } + if p.at(ROW_KW) || p.at(ROWS_KW) { + p.bump_any(); + } + m.complete(p, OFFSET_CLAUSE); + true +} + +/// all is the default, distinct removes duplicate rows +fn opt_all_or_distinct(p: &mut Parser) { + // TODO: we probably don't want to be so specific here, we can be more + // generous with parsing and handle error reporting later on. + if p.at(ALL_KW) { + p.bump(ALL_KW); + } else if p.at(DISTINCT_KW) { + let m = p.start(); + // ``` + // select DISTINCT [ ON ( expression [, ...] ) ] + // ``` + // + // for example: + // + // ``` + // select distinct name from users + // ``` + // + // or + // + // ``` + // select distinct on (url) url, request_duration + // from logs + // order by url, timestamp desc + // ``` + // + // from: [pg docs](https://www.postgresql.org/docs/current/sql-select.html#SQL-DISTINCT) + // + // `SELECT DISTINCT ON ( expression [, ...] )` keeps only the first row of + // each set of rows where the given expressions evaluate to equal. The + // DISTINCT ON expressions are interpreted using the same rules as for + // ORDER BY (see above). Note that the “first row” of each set is + // unpredictable unless ORDER BY is used to ensure that the desired row + // appears first. + p.bump(DISTINCT_KW); + if p.eat(ON_KW) && !paren_expr_list(p) { + m.abandon(p); + return; + } + m.complete(p, DISTINCT_CLAUSE); + } +} + +fn paren_expr_list(p: &mut Parser<'_>) -> bool { + if !p.eat(L_PAREN) { + return false; + } + if !expr_list(p) { + p.error("expected expression in paren_expr_list"); + false + } else { + p.eat(R_PAREN); + true + } +} + +/// All keywords +const COL_LABEL_FIRST: TokenSet = TokenSet::new(&[IDENT]) + .union(UNRESERVED_KEYWORDS) + .union(COLUMN_NAME_KEYWORDS) + .union(TYPE_FUNC_NAME_KEYWORDS) + .union(RESERVED_KEYWORDS); + +const NAME_FIRST: TokenSet = TokenSet::new(&[IDENT]) + .union(UNRESERVED_KEYWORDS) + .union(COLUMN_NAME_KEYWORDS); + +const BARE_COL_LABEL_FIRST: TokenSet = TokenSet::new(&[IDENT]).union(BARE_LABEL_KEYWORDS); + +const TARGET_LIST_START: TokenSet = TokenSet::new(&[STAR]) + .union(COL_LABEL_FIRST) + .union(EXPR_FIRST) + .union(TYPE_KEYWORDS); + +const LITERAL_FIRST: TokenSet = TokenSet::new(&[ + TRUE_KW, FALSE_KW, NULL_KW, // TODO: should default be in this set? + DEFAULT_KW, +]) +.union(NUMERIC_FIRST) +.union(STRING_FIRST); + +const NUMERIC_FIRST: TokenSet = TokenSet::new(&[INT_NUMBER, FLOAT_NUMBER]); + +const STRING_FIRST: TokenSet = TokenSet::new(&[ + STRING, + BYTE_STRING, + BIT_STRING, + DOLLAR_QUOTED_STRING, + ESC_STRING, +]); + +// via https://www.postgresql.org/docs/17/sql-createoperator.html +// + - * / < > = ~ ! @ # % ^ & | ` ? +pub(crate) const OPERATOR_FIRST: TokenSet = TokenSet::new(&[ + PLUS, MINUS, STAR, SLASH, L_ANGLE, R_ANGLE, EQ, TILDE, BANG, AT, POUND, PERCENT, CARET, AMP, + PIPE, BACKTICK, QUESTION, +]); + +const LHS_FIRST: TokenSet = TokenSet::new(&[ + L_PAREN, L_BRACK, CAST_KW, NOT_KW, IS_KW, PARAM, CASE_KW, ARRAY_KW, ROW_KW, DEFAULT_KW, +]) +.union(OPERATOR_FIRST) +.union(LITERAL_FIRST) +.union(TYPE_KEYWORDS) +.union(IDENTS); + +const IDENTS: TokenSet = TokenSet::new(&[ANY_KW, ALL_KW, SOME_KW, IDENT]).union(FUNC_KEYWORDS); + +const FUNC_KEYWORDS: TokenSet = TokenSet::new(&[ + CURRENT_DATE_KW, + CURRENT_TIME_KW, + CURRENT_TIMESTAMP_KW, + LOCALTIME_KW, + LOCALTIMESTAMP_KW, + CURRENT_ROLE_KW, + CURRENT_USER_KW, + SESSION_USER_KW, + SYSTEM_USER_KW, + USER_KW, + CURRENT_CATALOG_KW, + CURRENT_SCHEMA_KW, +]); + +const NAME_REF_FIRST: TokenSet = TYPE_KEYWORDS.union(IDENTS); + +const EXPR_FIRST: TokenSet = LHS_FIRST; + +// TODO: is this right? copied from rust analyzer +const ATTRIBUTE_FIRST: TokenSet = TokenSet::new(&[POUND, GROUP_KW]); + +const TARGET_FOLLOW: TokenSet = TokenSet::new(&[ + FROM_KW, WHERE_KW, LIMIT_KW, ORDER_KW, OFFSET_KW, GROUP_KW, HAVING_KW, WINDOW_KW, HAVING_KW, + FETCH_KW, FOR_KW, R_PAREN, R_BRACK, +]) +.union(COMPOUND_SELECT_FIRST); + +const TARGET_FIRST: TokenSet = EXPR_FIRST; + +// target_el: +// | a_expr AS ColLabel +// | a_expr BareColLabel +// | a_expr +// | '*' +fn opt_target_el(p: &mut Parser) -> Option { + let m = p.start(); + if p.at_ts(TARGET_FOLLOW) { + m.abandon(p); + return None; + } else if p.at(STAR) && !p.nth_at_ts(1, OPERATOR_FIRST) { + p.bump(STAR); + true + } else if expr(p).is_some() { + opt_as_col_label(p) || p.at(COMMA) + } else { + m.abandon(p); + p.error(format!( + "expected an expression in target_el, found {:?}", + p.current() + )); + return None; + }; + Some(m.complete(p, TARGET)) +} + +fn opt_as_col_label(p: &mut Parser<'_>) -> bool { + if p.eat(AS_KW) { + if p.at_ts(COL_LABEL_FIRST) { + col_label(p); + true + } else { + p.err_and_bump(&format!("expected column label, got {:?}", p.current())); + false + } + } else { + if p.at(FORMAT_KW) && p.nth_at(1, JSON_KW) { + return true; + } + if p.at_ts(BARE_COL_LABEL_FIRST) { + col_label(p); + } + true + } +} + +fn opt_target_list(p: &mut Parser) -> Option { + if !p.at_ts(TARGET_LIST_START) { + return None; + } + let m = p.start(); + while !p.at(EOF) && !p.at(SEMICOLON) { + if opt_target_el(p).is_some() { + if p.at(COMMA) && matches!(p.nth(1), SEMICOLON | EOF) { + p.err_and_bump("unexpected trailing comma"); + break; + } + if !p.eat(COMMA) { + if p.at(FORMAT_KW) && p.nth_at(1, JSON_KW) { + break; + } + if p.at(RETURNING_KW) && p.nth_at(1, TEXT_KW) { + break; + } + if p.at_ts(TARGET_FIRST) { + p.error("missing comma"); + } else { + break; + } + } + } + } + Some(m.complete(p, TARGET_LIST)) +} + +fn opt_if_not_exists(p: &mut Parser<'_>) -> Option { + if p.at(IF_KW) { + let m = p.start(); + p.bump(IF_KW); + p.expect(NOT_KW); + p.expect(EXISTS_KW); + Some(m.complete(p, IF_NOT_EXISTS)) + } else { + None + } +} + +fn opt_if_exists(p: &mut Parser<'_>) -> Option { + if p.at(IF_KW) { + let m = p.start(); + p.bump(IF_KW); + p.expect(EXISTS_KW); + Some(m.complete(p, IF_EXISTS)) + } else { + None + } +} + +// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +/// +fn drop_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, TABLE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TABLE_KW); + opt_if_exists(p); + while !p.at(EOF) { + path_name_ref(p); + if !p.eat(COMMA) { + break; + } + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_TABLE) +} + +// { column_name | ( expression ) } +// [ COLLATE collation ] +// [ opclass ] +// +// if we pass allow_extra_params: +// { column_name | ( expression ) } +// [ COLLATE collation ] +// [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] +// [ ASC | DESC ] +// [ NULLS { FIRST | LAST } ] +// +// part_elem: +// | ColId opt_collate opt_qualified_name +// | func_expr_windowless opt_collate opt_qualified_name +// | '(' a_expr ')' opt_collate opt_qualified_name +fn part_elem(p: &mut Parser<'_>, allow_extra_params: bool) -> bool { + // TODO: this can be more strict + if expr(p).is_none() { + p.error("expected expr") + } + opt_collate(p); + // [ opclass ] + p.eat(IDENT); + if allow_extra_params { + // [ ( opclass_parameter = value [, ... ] ) ] + if p.eat(L_PAREN) { + // TODO: + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + // [ ASC | DESC ] + let _ = p.eat(ASC_KW) || p.eat(DESC_KW); + // [ NULLS { FIRST | LAST } ] + if p.eat(NULLS_KW) { + let _ = p.eat(FIRST_KW) || p.expect(LAST_KW); + } + } + true +} + +fn table_args(p: &mut Parser<'_>, t: ColDefType) -> Option { + let m = p.start(); + match t { + ColDefType::WithData => { + p.expect(L_PAREN); + } + ColDefType::ColumnNameOnly => { + if !p.eat(L_PAREN) { + m.abandon(p); + return None; + } + } + } + while !p.at(EOF) && !p.at(R_PAREN) { + col_def(p, t); + if p.at(COMMA) && p.nth_at(1, R_PAREN) { + p.err_and_bump("unexpected trailing comma"); + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + Some(m.complete(p, TABLE_ARGS)) +} + +// { FOR VALUES partition_bound_spec | DEFAULT } +fn partition_option(p: &mut Parser<'_>) { + if p.eat(FOR_KW) { + p.expect(VALUES_KW); + // FOR VALUES WITH (modulus 5, remainder 0) + if p.eat(WITH_KW) { + p.expect(L_PAREN); + p.expect(IDENT); + p.expect(INT_NUMBER); + p.expect(COMMA); + p.expect(IDENT); + p.expect(INT_NUMBER); + p.expect(R_PAREN); + // FOR VALUES IN '(' expr_list ')' + } else if p.eat(IN_KW) { + p.expect(L_PAREN); + if !expr_list(p) { + p.error("expected expr list"); + } + p.expect(R_PAREN); + // FOR VALUES FROM '(' expr_list ')' TO '(' expr_list ')' + } else if p.eat(FROM_KW) { + p.expect(L_PAREN); + if !expr_list(p) { + p.error("expected expr list"); + } + p.expect(R_PAREN); + p.expect(TO_KW); + p.expect(L_PAREN); + if !expr_list(p) { + p.error("expected expr list"); + } + p.expect(R_PAREN); + } + // DEFAULT + } else { + p.expect(DEFAULT_KW); + } +} + +fn opt_inherits_tables(p: &mut Parser<'_>) { + if p.eat(INHERITS_KW) { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(COMMA) { + path_name_ref(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } +} + +// CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ +// { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] +// | table_constraint +// | LIKE source_table [ like_option ... ] } +// [, ... ] +// ] ) +// [ INHERITS ( parent_table [, ... ] ) ] +// [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] +// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] +// [ TABLESPACE tablespace_name ] +// +// CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name +// OF type_name [ ( +// { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ] +// | table_constraint } +// [, ... ] +// ) ] +// [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] +// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] +// [ TABLESPACE tablespace_name ] +// +// CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name +// PARTITION OF parent_table [ ( +// { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ] +// | table_constraint } +// [, ... ] +// ) ] { FOR VALUES partition_bound_spec | DEFAULT } +// [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] +// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] +// [ TABLESPACE tablespace_name ] +fn create_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.expect(CREATE_KW); + // [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] + if !p.eat(UNLOGGED_KW) { + // [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } + let require_temp = p.eat(GLOBAL_KW) || p.eat(LOCAL_KW); + if require_temp { + if !opt_temp(p) { + p.error("expected temp or temporary"); + } + } else { + opt_temp(p); + } + } + p.expect(TABLE_KW); + opt_if_not_exists(p); + path_name(p); + let mut col_def_t = ColDefType::WithData; + let mut is_partition = false; + // OF type_name + if p.eat(OF_KW) { + simple_type_name(p); + col_def_t = ColDefType::ColumnNameOnly; + // PARTITION OF parent_table + } else if p.eat(PARTITION_KW) { + p.expect(OF_KW); + path_name_ref(p); + col_def_t = ColDefType::ColumnNameOnly; + is_partition = true; + } + if p.at(L_PAREN) { + table_args(p, col_def_t); + } + if is_partition { + partition_option(p); + } + // [ INHERITS ( parent_table [, ... ] ) ] + if col_def_t == ColDefType::WithData { + opt_inherits_tables(p); + } + // [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] + if p.eat(PARTITION_KW) { + p.expect(BY_KW); + // name + if p.at_ts(TYPE_KEYWORDS) || p.at(IDENT) { + p.bump_any(); + } + // ( + // { column_name | ( expression ) } + // [ COLLATE collation ] + // [ opclass ] + // [, ... ] + // ) + partition_items(p, false); + } + // [ USING method ] + if p.eat(USING_KW) { + path_name_ref(p); + } + // [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] + if opt_with_params(p).is_none() { + if p.eat(WITHOUT_KW) { + p.expect(OIDS_KW); + } + } + // [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] + if p.eat(ON_KW) { + p.expect(COMMIT_KW); + if p.eat(PRESERVE_KW) || p.eat(DELETE_KW) { + p.expect(ROWS_KW); + } else if !p.eat(DROP_KW) { + p.error("expected PRESERVE ROWS, DELETE ROWS, or DROP"); + } + } + // [ TABLESPACE tablespace_name ] + if p.eat(TABLESPACE_KW) { + name_ref(p); + } + // AS query + // [ WITH [ NO ] DATA ] + if p.eat(AS_KW) { + // query + if p.at_ts(SELECT_FIRST) { + select_stmt(p, None); + } else if p.at(EXECUTE_KW) { + execute_stmt(p); + } else { + p.error("expected SELECT, TABLE, VALUES, or EXECUTE"); + } + if p.eat(WITH_KW) { + p.eat(NO_KW); + p.expect(DATA_KW); + } + return m.complete(p, CREATE_TABLE_AS_STMT); + } + m.complete(p, CREATE_TABLE) +} + +// COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] +// COMMIT PREPARED transaction_id +// +// https://www.postgresql.org/docs/17/sql-commit.html +fn commit_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(COMMIT_KW) || p.at(END_KW)); + let m = p.start(); + p.bump_any(); + // PREPARED transaction_id + if p.eat(PREPARED_KW) { + string_literal(p); + } else { + // [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] + let _ = p.eat(WORK_KW) || p.eat(TRANSACTION_KW); + if p.eat(AND_KW) { + p.eat(NO_KW); + p.expect(CHAIN_KW); + } + } + m.complete(p, COMMIT_STMT) +} + +const TRANSACTION_MODE_FIRST: TokenSet = + TokenSet::new(&[ISOLATION_KW, READ_KW, NOT_KW, DEFERRABLE_KW]); + +// where transaction_mode is one of: +// ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } +// READ WRITE | READ ONLY +// [ NOT ] DEFERRABLE +fn opt_transaction_mode(p: &mut Parser<'_>) -> bool { + if !p.at_ts(TRANSACTION_MODE_FIRST) { + return false; + } + // ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } + if p.eat(ISOLATION_KW) { + p.expect(LEVEL_KW); + if p.eat(SERIALIZABLE_KW) { + true + } else if p.eat(REPEATABLE_KW) { + p.expect(READ_KW) + } else if p.eat(READ_KW) { + p.eat(UNCOMMITTED_KW) || p.expect(COMMITTED_KW) + } else { + false + } + // READ WRITE | READ ONLY + } else if p.eat(READ_KW) { + p.eat(WRITE_KW) || p.expect(ONLY_KW) + // [ NOT ] DEFERRABLE + } else { + p.eat(NOT_KW); + p.expect(DEFERRABLE_KW) + } +} + +// [ transaction_mode [, ...] ] +fn opt_transaction_mode_list(p: &mut Parser<'_>) { + while !p.at(EOF) { + if !opt_transaction_mode(p) { + break; + } + if !p.eat(COMMA) && !p.at_ts(TRANSACTION_MODE_FIRST) { + break; + } + } +} + +// BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ] +// +// START TRANSACTION [ transaction_mode [, ...] ] +// +// where transaction_mode is one of: +// ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } +// READ WRITE | READ ONLY +// [ NOT ] DEFERRABLE +// +// https://www.postgresql.org/docs/17/sql-begin.html +// https://www.postgresql.org/docs/17/sql-start-transaction.html +fn begin_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(BEGIN_KW) || p.at(START_KW)); + let m = p.start(); + // BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ] + if p.eat(BEGIN_KW) { + // [ WORK | TRANSACTION ] + let _ = p.eat(WORK_KW) || p.eat(TRANSACTION_KW); + opt_transaction_mode_list(p); + } else { + // START TRANSACTION [ transaction_mode [, ...] ] + p.bump(START_KW); + p.expect(TRANSACTION_KW); + opt_transaction_mode_list(p); + } + m.complete(p, BEGIN_STMT) +} + +// Sconst +fn opt_string_literal(p: &mut Parser<'_>) -> Option { + if p.at_ts(STRING_FIRST) { + let m = p.start(); + p.bump_any(); + Some(m.complete(p, LITERAL)) + } else { + None + } +} + +fn string_literal(p: &mut Parser<'_>) { + if opt_string_literal(p).is_none() { + p.error("expected string literal"); + } +} + +fn opt_bool_literal(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if p.eat(TRUE_KW) || p.eat(FALSE_KW) { + m.complete(p, LITERAL); + true + } else { + m.abandon(p); + false + } +} + +// PREPARE TRANSACTION transaction_id +// +// https://www.postgresql.org/docs/17/sql-prepare-transaction.html +fn prepare_transaction_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(PREPARE_KW)); + let m = p.start(); + p.bump(PREPARE_KW); + p.expect(TRANSACTION_KW); + string_literal(p); + m.complete(p, PREPARE_TRANSACTION_STMT) +} + +// SAVEPOINT savepoint_name +// +// https://www.postgresql.org/docs/17/sql-savepoint.html +fn savepoint_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SAVEPOINT_KW)); + let m = p.start(); + p.bump(SAVEPOINT_KW); + if name_ref_(p).is_none() { + p.error("expected a name"); + } + m.complete(p, SAVEPOINT_STMT) +} + +// RELEASE [ SAVEPOINT ] savepoint_name +// +// https://www.postgresql.org/docs/17/sql-release-savepoint.html +fn release_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(RELEASE_KW)); + let m = p.start(); + p.bump(RELEASE_KW); + p.eat(SAVEPOINT_KW); + if name_ref_(p).is_none() { + p.error("expected a name"); + } + m.complete(p, RELEASE_SAVEPOINT_STMT) +} + +// ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] +// ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] +// ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name +// ROLLBACK PREPARED transaction_id +// +// https://www.postgresql.org/docs/17/sql-rollback.html +// https://www.postgresql.org/docs/17/sql-abort.html +// https://www.postgresql.org/docs/17/sql-rollback-to.html +// https://www.postgresql.org/docs/17/sql-rollback-prepared.html +fn rollback_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ROLLBACK_KW) || p.at(ABORT_KW)); + let m = p.start(); + let is_rollback = p.at(ROLLBACK_KW); + p.bump_any(); + if p.eat(PREPARED_KW) { + string_literal(p); + return m.complete(p, ROLLBACK_STMT); + } + let _ = p.eat(WORK_KW) || p.eat(TRANSACTION_KW); + if is_rollback && p.eat(TO_KW) { + p.eat(SAVEPOINT_KW); + if name_ref_(p).is_none() { + p.error("expected a name"); + } + } else if p.eat(AND_KW) { + p.eat(NO_KW); + p.expect(CHAIN_KW); + } + m.complete(p, ROLLBACK_STMT) +} + +struct StmtRestrictions { + begin_end_allowed: bool, +} + +fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option { + match (p.current(), p.nth(1)) { + (ABORT_KW, _) => Some(rollback_stmt(p)), + (ALTER_KW, AGGREGATE_KW) => Some(alter_aggregate_stmt(p)), + (ALTER_KW, COLLATION_KW) => Some(alter_collation_stmt(p)), + (ALTER_KW, CONVERSION_KW) => Some(alter_conversion_stmt(p)), + (ALTER_KW, DATABASE_KW) => Some(alter_database_stmt(p)), + (ALTER_KW, DEFAULT_KW) if p.nth_at(2, PRIVILEGES_KW) => { + Some(alter_default_privileges_stmt(p)) + } + (ALTER_KW, DOMAIN_KW) => Some(alter_domain_stmt(p)), + (ALTER_KW, EVENT_KW) if p.nth_at(2, TRIGGER_KW) => Some(alter_event_trigger_stmt(p)), + (ALTER_KW, EXTENSION_KW) => Some(alter_extension_stmt(p)), + (ALTER_KW, FOREIGN_KW) if p.nth_at(2, DATA_KW) => Some(alter_foreign_data_wrapper_stmt(p)), + (ALTER_KW, FOREIGN_KW) if p.nth_at(2, TABLE_KW) => Some(alter_foreign_table_stmt(p)), + (ALTER_KW, FUNCTION_KW) => Some(alter_function_stmt(p)), + (ALTER_KW, GROUP_KW) => Some(alter_group_stmt(p)), + (ALTER_KW, INDEX_KW) => Some(alter_index_stmt(p)), + (ALTER_KW, LARGE_KW) if p.nth_at(2, OBJECT_KW) => Some(alter_large_object_stmt(p)), + (ALTER_KW, MATERIALIZED_KW) if p.nth_at(2, VIEW_KW) => { + Some(alter_materialized_view_stmt(p)) + } + (ALTER_KW, OPERATOR_KW) if p.nth_at(2, CLASS_KW) => Some(alter_operator_class_stmt(p)), + (ALTER_KW, OPERATOR_KW) if p.nth_at(2, FAMILY_KW) => Some(alter_operator_family_stmt(p)), + (ALTER_KW, OPERATOR_KW) => Some(alter_operator_stmt(p)), + (ALTER_KW, POLICY_KW) => Some(alter_policy_stmt(p)), + (ALTER_KW, PROCEDURAL_KW | LANGUAGE_KW) => Some(alter_language_stmt(p)), + (ALTER_KW, PROCEDURE_KW) => Some(alter_procedure_stmt(p)), + (ALTER_KW, PUBLICATION_KW) => Some(alter_publication_stmt(p)), + (ALTER_KW, ROLE_KW) => Some(alter_role_stmt(p)), + (ALTER_KW, ROUTINE_KW) => Some(alter_routine_stmt(p)), + (ALTER_KW, RULE_KW) => Some(alter_rule_stmt(p)), + (ALTER_KW, SCHEMA_KW) => Some(alter_schema_stmt(p)), + (ALTER_KW, SEQUENCE_KW) => Some(alter_sequence_stmt(p)), + (ALTER_KW, SERVER_KW) => Some(alter_server_stmt(p)), + (ALTER_KW, STATISTICS_KW) => Some(alter_statistics_stmt(p)), + (ALTER_KW, SUBSCRIPTION_KW) => Some(alter_subscription_stmt(p)), + (ALTER_KW, SYSTEM_KW) => Some(alter_system_stmt(p)), + (ALTER_KW, TABLE_KW) => Some(alter_table_stmt(p)), + (ALTER_KW, TABLESPACE_KW) => Some(alter_tablespace_stmt(p)), + (ALTER_KW, TEXT_KW) if p.nth_at(2, SEARCH_KW) => match p.nth(3) { + CONFIGURATION_KW => Some(alter_text_search_configuration(p)), + DICTIONARY_KW => Some(alter_text_search_dict_stmt(p)), + PARSER_KW => Some(alter_text_search_parser_stmt(p)), + TEMPLATE_KW => Some(alter_text_search_template_stmt(p)), + _ => { + p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE"); + None + } + }, + (ALTER_KW, TRIGGER_KW) => Some(alter_trigger_stmt(p)), + (ALTER_KW, TYPE_KW) => Some(alter_type_stmt(p)), + (ALTER_KW, USER_KW) if p.nth_at(2, MAPPING_KW) => Some(alter_user_mapping_stmt(p)), + (ALTER_KW, USER_KW) => Some(alter_user_stmt(p)), + (ALTER_KW, VIEW_KW) => Some(alter_view_stmt(p)), + (ANALYZE_KW | ANALYSE_KW, _) => Some(analyze_stmt(p)), + (BEGIN_KW, _) if r.begin_end_allowed => Some(begin_stmt(p)), + (CALL_KW, _) => Some(call_stmt(p)), + (CHECKPOINT_KW, _) => Some(checkpoint_stmt(p)), + (CLOSE_KW, _) => Some(close_stmt(p)), + (CLUSTER_KW, _) => Some(cluster_stmt(p)), + (COMMENT_KW, _) => Some(comment_stmt(p)), + (COMMIT_KW, _) => Some(commit_stmt(p)), + (COPY_KW, _) => Some(copy_stmt(p)), + (CREATE_KW, ACCESS_KW) => Some(create_access_method_stmt(p)), + (CREATE_KW, AGGREGATE_KW) => Some(create_aggregate_stmt(p)), + (CREATE_KW, CAST_KW) => Some(create_cast_stmt(p)), + (CREATE_KW, COLLATION_KW) => Some(create_collation_stmt(p)), + (CREATE_KW, CONVERSION_KW | DEFAULT_KW) => Some(create_conversion_stmt(p)), + (CREATE_KW, DATABASE_KW) => Some(create_database_stmt(p)), + (CREATE_KW, DOMAIN_KW) => Some(create_domain_stmt(p)), + (CREATE_KW, EVENT_KW) => Some(create_event_trigger_stmt(p)), + (CREATE_KW, EXTENSION_KW) => Some(create_extension_stmt(p)), + (CREATE_KW, FOREIGN_KW) => match p.nth(2) { + DATA_KW => Some(create_foreign_data_wrapper_stmt(p)), + _ => Some(create_foreign_table_stmt(p)), + }, + (CREATE_KW, FUNCTION_KW) => Some(create_function_stmt(p)), + (CREATE_KW, GROUP_KW) => Some(create_group_stmt(p)), + (CREATE_KW, INDEX_KW | UNIQUE_KW) => Some(create_index_stmt(p)), + (CREATE_KW, LANGUAGE_KW) => Some(create_language_stmt(p)), + (CREATE_KW, MATERIALIZED_KW) => Some(create_materialized_view_stmt(p)), + (CREATE_KW, OPERATOR_KW) => match p.nth(2) { + CLASS_KW => Some(create_operator_class_stmt(p)), + FAMILY_KW => Some(create_operator_family_stmt(p)), + _ => Some(create_operator_stmt(p)), + }, + (CREATE_KW, OR_KW) => { + // CREATE OR REPLACE [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW + // CREATE OR REPLACE CONSTRAINT + // CREATE OR REPLACE TRANSFORM + // CREATE OR REPLACE RULE + // CREATE OR REPLACE AGGREGATE + // ^0 ^1 ^2 ^3 + match p.nth(3) { + AGGREGATE_KW => Some(create_aggregate_stmt(p)), + CONSTRAINT_KW | TRIGGER_KW => Some(create_trigger_stmt(p)), + PROCEDURAL_KW | TRUSTED_KW | LANGUAGE_KW => Some(create_language_stmt(p)), + PROCEDURE_KW => Some(create_procedure_stmt(p)), + RECURSIVE_KW | TEMP_KW | TEMPORARY_KW => Some(create_view_stmt(p)), + RULE_KW => Some(create_rule_stmt(p)), + TRANSFORM_KW => Some(create_transform_stmt(p)), + _ => Some(create_function_stmt(p)), + } + } + (CREATE_KW, POLICY_KW) => Some(create_policy_stmt(p)), + (CREATE_KW, PROCEDURE_KW) => Some(create_procedure_stmt(p)), + (CREATE_KW, PUBLICATION_KW) => Some(create_publication_stmt(p)), + (CREATE_KW, RECURSIVE_KW | VIEW_KW) => Some(create_view_stmt(p)), + (CREATE_KW, ROLE_KW) => Some(create_role_stmt(p)), + (CREATE_KW, RULE_KW) => Some(create_rule_stmt(p)), + (CREATE_KW, SCHEMA_KW) => Some(create_schema_stmt(p)), + (CREATE_KW, SEQUENCE_KW) => Some(create_sequence_stmt(p)), + (CREATE_KW, SERVER_KW) => Some(create_server_stmt(p)), + (CREATE_KW, STATISTICS_KW) => Some(create_statistics_stmt(p)), + (CREATE_KW, SUBSCRIPTION_KW) => Some(create_subscription_stmt(p)), + (CREATE_KW, TABLE_KW | GLOBAL_KW | LOCAL_KW | UNLOGGED_KW) if !p.nth_at(2, SEQUENCE_KW) => { + Some(create_table_stmt(p)) + } + (CREATE_KW, TABLESPACE_KW) => Some(create_tablespace_stmt(p)), + (CREATE_KW, TEMP_KW | TEMPORARY_KW) => { + // CREATE TEMP [ RECURSIVE ] VIEW + // CREATE TEMP TABLE + // ^0 ^1 ^2 + match p.nth(2) { + RECURSIVE_KW | VIEW_KW => Some(create_view_stmt(p)), + SEQUENCE_KW => Some(create_sequence_stmt(p)), + _ => Some(create_table_stmt(p)), + } + } + (CREATE_KW, TEXT_KW) if p.nth_at(2, SEARCH_KW) => match p.nth(3) { + CONFIGURATION_KW => Some(create_text_search_config_stmt(p)), + DICTIONARY_KW => Some(create_text_search_dict_stmt(p)), + PARSER_KW => Some(create_text_search_parser_stmt(p)), + TEMPLATE_KW => Some(create_text_search_template_stmt(p)), + _ => { + p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE"); + None + } + }, + (CREATE_KW, TRANSFORM_KW) => Some(create_transform_stmt(p)), + (CREATE_KW, TYPE_KW) => Some(create_type_stmt(p)), + (CREATE_KW, UNLOGGED_KW) if p.nth_at(2, SEQUENCE_KW) => Some(create_sequence_stmt(p)), + (CREATE_KW, USER_KW) if p.nth_at(2, MAPPING_KW) => Some(create_user_mapping_stmt(p)), + (CREATE_KW, USER_KW) => Some(create_user_stmt(p)), + (CREATE_KW, CONSTRAINT_KW | TRIGGER_KW) => Some(create_trigger_stmt(p)), + (DEALLOCATE_KW, _) => Some(deallocate_stmt(p)), + (DECLARE_KW, _) => Some(declare_stmt(p)), + (DELETE_KW, _) => Some(delete_stmt(p, None)), + (DISCARD_KW, _) => Some(discard_stmt(p)), + (DO_KW, _) => Some(do_stmt(p)), + (DROP_KW, ACCESS_KW) => Some(drop_access_method_stmt(p)), + (DROP_KW, AGGREGATE_KW) => Some(drop_aggregate_stmt(p)), + (DROP_KW, CAST_KW) => Some(drop_cast_stmt(p)), + (DROP_KW, COLLATION_KW) => Some(drop_collation_stmt(p)), + (DROP_KW, CONVERSION_KW) => Some(drop_conversion_stmt(p)), + (DROP_KW, DATABASE_KW) => Some(drop_database_stmt(p)), + (DROP_KW, DOMAIN_KW) => Some(drop_domain_stmt(p)), + (DROP_KW, EVENT_KW) => Some(drop_event_trigger_stmt(p)), + (DROP_KW, EXTENSION_KW) => Some(drop_extension_stmt(p)), + (DROP_KW, FOREIGN_KW) => match p.nth(2) { + DATA_KW => Some(drop_foreign_data_stmt(p)), + TABLE_KW => Some(drop_foreign_table_stmt(p)), + _ => { + p.error("expected DATA or TABLE"); + None + } + }, + (DROP_KW, FUNCTION_KW) => Some(drop_function_stmt(p)), + (DROP_KW, GROUP_KW) => Some(drop_group_stmt(p)), + (DROP_KW, INDEX_KW) => Some(drop_index_stmt(p)), + (DROP_KW, LANGUAGE_KW | PROCEDURAL_KW) => Some(drop_language_stmt(p)), + (DROP_KW, MATERIALIZED_KW) => Some(drop_materialized_view_stmt(p)), + (DROP_KW, OPERATOR_KW) => match p.nth(2) { + CLASS_KW => Some(drop_operator_class_stmt(p)), + FAMILY_KW => Some(drop_operator_family_stmt(p)), + _ => Some(drop_operator_stmt(p)), + }, + (DROP_KW, OWNED_KW) => Some(drop_owned_stmt(p)), + (DROP_KW, POLICY_KW) => Some(drop_policy_stmt(p)), + (DROP_KW, PROCEDURE_KW) => Some(drop_procedure_stmt(p)), + (DROP_KW, PUBLICATION_KW) => Some(drop_publication_stmt(p)), + (DROP_KW, ROLE_KW) => Some(drop_role_stmt(p)), + (DROP_KW, ROUTINE_KW) => Some(drop_routine_stmt(p)), + (DROP_KW, RULE_KW) => Some(drop_rule_stmt(p)), + (DROP_KW, SCHEMA_KW) => Some(drop_schema_stmt(p)), + (DROP_KW, SEQUENCE_KW) => Some(drop_sequence_stmt(p)), + (DROP_KW, SERVER_KW) => Some(drop_server_stmt(p)), + (DROP_KW, STATISTICS_KW) => Some(drop_statistics_stmt(p)), + (DROP_KW, SUBSCRIPTION_KW) => Some(drop_subscription_stmt(p)), + (DROP_KW, TABLE_KW) => Some(drop_table_stmt(p)), + (DROP_KW, TABLESPACE_KW) => Some(drop_tablespace_stmt(p)), + (DROP_KW, TEXT_KW) if p.nth_at(2, SEARCH_KW) => match p.nth(3) { + CONFIGURATION_KW => Some(drop_text_search_config_stmt(p)), + DICTIONARY_KW => Some(drop_text_search_dict_stmt(p)), + PARSER_KW => Some(drop_text_search_parser_stmt(p)), + TEMPLATE_KW => Some(drop_text_search_template_stmt(p)), + _ => { + p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE"); + None + } + }, + (DROP_KW, TRANSFORM_KW) => Some(drop_transform_stmt(p)), + (DROP_KW, TRIGGER_KW) => Some(drop_trigger_stmt(p)), + (DROP_KW, TYPE_KW) => Some(drop_type_stmt(p)), + (DROP_KW, USER_KW) => { + if p.nth_at(2, MAPPING_KW) { + Some(drop_user_mapping_stmt(p)) + } else { + Some(drop_user_stmt(p)) + } + } + (DROP_KW, VIEW_KW) => Some(drop_view_stmt(p)), + (END_KW, _) if r.begin_end_allowed => Some(commit_stmt(p)), + (EXECUTE_KW, _) => Some(execute_stmt(p)), + (EXPLAIN_KW, _) => Some(explain_stmt(p)), + (FETCH_KW, _) => Some(fetch_stmt(p)), + (GRANT_KW, _) => Some(grant_stmt(p)), + (IMPORT_KW, FOREIGN_KW) => Some(import_foreign_schema_stmt(p)), + (INSERT_KW, _) => Some(insert_stmt(p, None)), + (L_PAREN, L_PAREN | SELECT_KW) => { + // can have select nested in parens, i.e., ((select 1)); + let cm = paren_select(p)?; + let cm = if p.at_ts(COMPOUND_SELECT_FIRST) { + compound_select(p, cm) + } else { + cm + }; + // TODO: this needs to be rethinked + if p.at(ORDER_KW) { + opt_order_by_clause(p); + } + Some(cm) + } + (LISTEN_KW, _) => Some(listen_stmt(p)), + (LOAD_KW, _) => Some(load_stmt(p)), + (LOCK_KW, _) => Some(lock_stmt(p)), + (MERGE_KW, _) => Some(merge_stmt(p, None)), + (MOVE_KW, _) => Some(move_stmt(p)), + (NOTIFY_KW, _) => Some(notify_stmt(p)), + (PREPARE_KW, TRANSACTION_KW) => Some(prepare_transaction_stmt(p)), + (PREPARE_KW, _) => Some(prepare_stmt(p)), + (REASSIGN_KW, _) => Some(reassign_stmt(p)), + (REFRESH_KW, _) => Some(refresh_stmt(p)), + (REINDEX_KW, _) => Some(reindex_stmt(p)), + (RELEASE_KW, _) => Some(release_stmt(p)), + (RESET_KW, ROLE_KW) => Some(set_role_stmt(p)), + (RESET_KW, SESSION_KW) => Some(set_session_auth_stmt(p)), + (RESET_KW, _) => Some(reset_stmt(p)), + (REVOKE_KW, _) => Some(revoke_stmt(p)), + (ROLLBACK_KW, _) => Some(rollback_stmt(p)), + (SAVEPOINT_KW, _) => Some(savepoint_stmt(p)), + (SECURITY_KW, LABEL_KW) => Some(security_label_stmt(p)), + (SELECT_KW | TABLE_KW | VALUES_KW, _) => select_stmt(p, None), + (SET_KW, CONSTRAINTS_KW) => Some(set_constraints_stmt(p)), + (SET_KW, LOCAL_KW) => match p.nth(2) { + ROLE_KW => Some(set_role_stmt(p)), + SESSION_KW => Some(set_session_auth_stmt(p)), + _ => Some(set_stmt(p)), + }, + (SET_KW, ROLE_KW) => Some(set_role_stmt(p)), + (SET_KW, SESSION_KW) => match p.nth(2) { + AUTHORIZATION_KW | SESSION_KW => Some(set_session_auth_stmt(p)), + CHARACTERISTICS_KW => Some(set_transaction_stmt(p)), + ROLE_KW => Some(set_role_stmt(p)), + _ => Some(set_stmt(p)), + }, + (SET_KW, TRANSACTION_KW) => Some(set_transaction_stmt(p)), + (SET_KW, TIME_KW | _) => Some(set_stmt(p)), + (SHOW_KW, _) => Some(show_stmt(p)), + (START_KW, TRANSACTION_KW) => Some(begin_stmt(p)), + (TRUNCATE_KW, _) => Some(truncate_stmt(p)), + (UNLISTEN_KW, _) => Some(unlisten_stmt(p)), + (UPDATE_KW, _) => Some(update_stmt(p, None)), + (VACUUM_KW, _) => Some(vacuum_stmt(p)), + (WITH_KW, _) => with_stmt(p, None), + (command, _) => { + // commands are outlined in: + // https://www.postgresql.org/docs/17/sql-commands.html + // TODO: see error recovery in rust-analyzer's expr_bp + p.err_and_bump(&format!("expected command, found {:?}", command)); + // m.abandon(p); + None + } + } +} + +// ALTER STATISTICS name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER STATISTICS name RENAME TO new_name +// ALTER STATISTICS name SET SCHEMA new_schema +// ALTER STATISTICS name SET STATISTICS { new_target | DEFAULT } +fn alter_statistics_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, STATISTICS_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(STATISTICS_KW); + path_name_ref(p); + match p.current() { + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name_ref(p); + } + SET_KW => { + p.bump(SET_KW); + if p.eat(SCHEMA_KW) { + name_ref(p); + } else if p.eat(STATISTICS_KW) { + if !p.eat(DEFAULT_KW) { + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + } + } else { + p.error("expected SCHEMA or STATISTICS"); + } + } + _ => { + p.error("expected OWNER, RENAME, or SET"); + } + } + m.complete(p, ALTER_STATISTICS_STMT) +} + +// ALTER SERVER name [ VERSION 'new_version' ] +// [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) ] +// ALTER SERVER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER SERVER name RENAME TO new_name +fn alter_server_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, SERVER_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(SERVER_KW); + name_ref(p); + match p.current() { + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + let mut found_option = false; + if p.eat(VERSION_KW) { + string_literal(p); + found_option = true; + } + if p.eat(OPTIONS_KW) { + found_option = true; + p.expect(L_PAREN); + alter_option(p); + while !p.at(EOF) && p.eat(COMMA) { + alter_option(p); + } + p.expect(R_PAREN); + } + if !found_option { + p.error("expected ALTER SERVER option"); + } + } + } + m.complete(p, ALTER_SERVER_STMT) +} + +// ALTER SEQUENCE [ IF EXISTS ] name +// [ AS data_type ] +// [ INCREMENT [ BY ] increment ] +// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] +// [ START [ WITH ] start ] +// [ RESTART [ [ WITH ] restart ] ] +// [ CACHE cache ] [ [ NO ] CYCLE ] +// [ OWNED BY { table_name.column_name | NONE } ] +// ALTER SEQUENCE [ IF EXISTS ] name SET { LOGGED | UNLOGGED } +// ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name +// ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema +fn alter_sequence_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, SEQUENCE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(SEQUENCE_KW); + opt_if_exists(p); + path_name_ref(p); + match p.current() { + SET_KW => { + p.bump(SET_KW); + if p.eat(SCHEMA_KW) { + name_ref(p); + } else { + if !p.eat(LOGGED_KW) && !p.eat(UNLOGGED_KW) { + p.error("LOGGED or UNLOGGED"); + } + } + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + let mut found_option = false; + while !p.at(EOF) { + if !opt_sequence_option(p) { + break; + } + found_option = true; + } + if !found_option { + p.error("expected ALTER SEQUENCE option"); + } + } + } + m.complete(p, ALTER_SEQUENCE_STMT) +} + +// ALTER SCHEMA name RENAME TO new_name +// ALTER SCHEMA name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +fn alter_schema_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, SCHEMA_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(SCHEMA_KW); + name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + _ => { + p.error("expected RENAME or OWNER"); + } + } + m.complete(p, ALTER_SCHEMA_STMT) +} + +// ALTER RULE name ON table_name RENAME TO new_name +fn alter_rule_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, RULE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(RULE_KW); + name_ref(p); + p.expect(ON_KW); + path_name_ref(p); + p.expect(RENAME_KW); + p.expect(TO_KW); + name(p); + m.complete(p, ALTER_RULE_STMT) +} + +// ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// action [ ... ] [ RESTRICT ] +// ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// RENAME TO new_name +// ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// SET SCHEMA new_schema +// ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// [ NO ] DEPENDS ON EXTENSION extension_name +// where action is one of: +// IMMUTABLE | STABLE | VOLATILE +// [ NOT ] LEAKPROOF +// [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER +// PARALLEL { UNSAFE | RESTRICTED | SAFE } +// COST execution_cost +// ROWS result_rows +// SET configuration_parameter { TO | = } { value | DEFAULT } +// SET configuration_parameter FROM CURRENT +// RESET configuration_parameter +// RESET ALL +fn alter_routine_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, ROUTINE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(ROUTINE_KW); + name_ref(p); + opt_param_list(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW if p.nth_at(1, SCHEMA_KW) => { + p.bump(SET_KW); + p.bump(SCHEMA_KW); + name_ref(p); + } + NO_KW | DEPENDS_KW => { + p.eat(NO_KW); + p.expect(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + path_name_ref(p); + } + _ => { + func_option_list(p); + } + } + p.eat(RESTRICT_KW); + m.complete(p, ALTER_ROUTINE_STMT) +} + +// ALTER ROLE role_specification [ WITH ] option [ ... ] +// where option can be: +// SUPERUSER | NOSUPERUSER +// | CREATEDB | NOCREATEDB +// | CREATEROLE | NOCREATEROLE +// | INHERIT | NOINHERIT +// | LOGIN | NOLOGIN +// | REPLICATION | NOREPLICATION +// | BYPASSRLS | NOBYPASSRLS +// | CONNECTION LIMIT connlimit +// | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL +// | VALID UNTIL 'timestamp' +// ALTER ROLE name RENAME TO new_name +// ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } +// ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT +// ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter +// ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL +// where role_specification can be: +// role_name +// | CURRENT_ROLE +// | CURRENT_USER +// | SESSION_USER +fn alter_role_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, ROLE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(ROLE_KW); + if !p.eat(ALL_KW) { + role(p); + } + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + IN_KW | SET_KW | RESET_KW => { + if p.eat(IN_KW) { + p.expect(DATABASE_KW); + name_ref(p); + } + if p.at(SET_KW) { + set_configuration_param(p); + } else if p.eat(RESET_KW) { + if !p.eat(ALL_KW) { + path_name_ref(p); + } + } + } + _ => { + p.eat(WITH_KW); + if !opt_role_option(p) { + p.error("expected option"); + } + while !p.at(EOF) && p.at_ts(ROLE_OPTION_FIRST) { + opt_role_option(p); + } + } + } + m.complete(p, ALTER_ROLE_STMT) +} + +// ALTER PUBLICATION name ADD publication_object [, ...] +// ALTER PUBLICATION name SET publication_object [, ...] +// ALTER PUBLICATION name DROP publication_object [, ...] +// ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] ) +// ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER PUBLICATION name RENAME TO new_name +// where publication_object is one of: +// TABLE [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +fn alter_publication_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, PUBLICATION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(PUBLICATION_KW); + name_ref(p); + match p.current() { + ADD_KW | DROP_KW => { + p.bump_any(); + publication_object(p); + while !p.at(EOF) && p.eat(COMMA) { + publication_object(p); + } + } + SET_KW => { + p.bump(SET_KW); + if p.eat(L_PAREN) { + while !p.at(EOF) && !p.at(R_PAREN) { + if !storage_parameter(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } else { + publication_object(p); + while !p.at(EOF) && p.eat(COMMA) { + publication_object(p); + } + } + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + p.error("expected ADD, SET, DROP, OWNER, or RENAME"); + } + } + m.complete(p, ALTER_PUBLICATION_STMT) +} + +// ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// action [ ... ] [ RESTRICT ] +// ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// RENAME TO new_name +// ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// SET SCHEMA new_schema +// ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// [ NO ] DEPENDS ON EXTENSION extension_name +// +// where action is one of: +// [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER +// SET configuration_parameter { TO | = } { value | DEFAULT } +// SET configuration_parameter FROM CURRENT +// RESET configuration_parameter +// RESET ALL +fn alter_procedure_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, PROCEDURE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(PROCEDURE_KW); + path_name_ref(p); + opt_param_list(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW if p.nth_at(1, SCHEMA_KW) => { + p.bump(SET_KW); + p.bump(SCHEMA_KW); + name_ref(p); + } + DEPENDS_KW | NO_KW => { + p.eat(NO_KW); + p.expect(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + path_name_ref(p); + } + _ => { + func_option_list(p); + p.eat(RESTRICT_KW); + } + } + m.complete(p, ALTER_PROCEDURE_STMT) +} + +// ALTER POLICY name ON table_name RENAME TO new_name +// ALTER POLICY name ON table_name +// [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ] +// [ USING ( using_expression ) ] +// [ WITH CHECK ( check_expression ) ] +fn alter_policy_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, POLICY_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(POLICY_KW); + name_ref(p); + p.expect(ON_KW); + name_ref(p); + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name(p); + } else { + if p.eat(TO_KW) { + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + if p.eat(USING_KW) { + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + if p.eat(WITH_KW) { + p.expect(CHECK_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + } + m.complete(p, ALTER_POLICY_STMT) +} + +// ALTER OPERATOR FAMILY name USING index_method ADD +// { OPERATOR strategy_number operator_name ( op_type, op_type ) +// [ FOR SEARCH | FOR ORDER BY sort_family_name ] +// | FUNCTION support_number [ ( op_type [ , op_type ] ) ] +// function_name [ ( argument_type [, ...] ) ] +// } [, ... ] +// +// ALTER OPERATOR FAMILY name USING index_method DROP +// { OPERATOR strategy_number ( op_type [ , op_type ] ) +// | FUNCTION support_number ( op_type [ , op_type ] ) +// } [, ... ] +// +// ALTER OPERATOR FAMILY name USING index_method +// RENAME TO new_name +// +// ALTER OPERATOR FAMILY name USING index_method +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// +// ALTER OPERATOR FAMILY name USING index_method +// SET SCHEMA new_schema +fn alter_operator_family_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, OPERATOR_KW) && p.nth_at(2, FAMILY_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(OPERATOR_KW); + p.bump(FAMILY_KW); + path_name_ref(p); + p.expect(USING_KW); + name_ref(p); + match p.current() { + ADD_KW => { + p.bump_any(); + // TODO: need to add some validators to make this stricter + operator_class_option(p); + while !p.at(EOF) && p.eat(COMMA) { + operator_class_option(p); + } + } + DROP_KW => { + p.bump_any(); + operator_drop_class_option(p); + while !p.at(EOF) && p.eat(COMMA) { + operator_drop_class_option(p); + } + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + name_ref(p); + } + _ => { + p.error("expected ADD, DROP, RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_OPERATOR_FAMILY_STMT) +} + +// ALTER OPERATOR CLASS name USING index_method +// RENAME TO new_name +// ALTER OPERATOR CLASS name USING index_method +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER OPERATOR CLASS name USING index_method +// SET SCHEMA new_schema +fn alter_operator_class_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, OPERATOR_KW) && p.nth_at(2, CLASS_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(OPERATOR_KW); + p.bump(CLASS_KW); + path_name_ref(p); + p.expect(USING_KW); + name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name_ref(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + name_ref(p); + } + _ => { + p.error("expected RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_OPERATOR_CLASS_STMT) +} + +// ALTER OPERATOR name ( { left_type | NONE } , right_type ) +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER OPERATOR name ( { left_type | NONE } , right_type ) +// SET SCHEMA new_schema +// ALTER OPERATOR name ( { left_type | NONE } , right_type ) +// SET ( { RESTRICT = { res_proc | NONE } +// | JOIN = { join_proc | NONE } +// | COMMUTATOR = com_op +// | NEGATOR = neg_op +// | HASHES +// | MERGES +// } [, ... ] ) +fn alter_operator_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, OPERATOR_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(OPERATOR_KW); + operator_sig(p); + match p.current() { + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + if p.eat(SCHEMA_KW) { + name_ref(p); + } else { + p.expect(L_PAREN); + if !attribute_option(p, AttributeValue::Either) { + p.error("expected option"); + } + while !p.at(EOF) && p.eat(COMMA) { + if !attribute_option(p, AttributeValue::Either) { + p.error("expected option"); + } + } + p.expect(R_PAREN); + } + } + _ => { + p.error("expected OWNER or SET"); + } + } + m.complete(p, ALTER_OPERATOR_STMT) +} + +// ALTER MATERIALIZED VIEW [ IF EXISTS ] name +// action [, ... ] +// ALTER MATERIALIZED VIEW name +// [ NO ] DEPENDS ON EXTENSION extension_name +// ALTER MATERIALIZED VIEW [ IF EXISTS ] name +// RENAME [ COLUMN ] column_name TO new_column_name +// ALTER MATERIALIZED VIEW [ IF EXISTS ] name +// RENAME TO new_name +// ALTER MATERIALIZED VIEW [ IF EXISTS ] name +// SET SCHEMA new_schema +// ALTER MATERIALIZED VIEW ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] +// SET TABLESPACE new_tablespace [ NOWAIT ] +// +// where action is one of: +// ALTER [ COLUMN ] column_name SET STATISTICS integer +// ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) +// ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) +// ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } +// ALTER [ COLUMN ] column_name SET COMPRESSION compression_method +// CLUSTER ON index_name +// SET WITHOUT CLUSTER +// SET ACCESS METHOD new_access_method +// SET TABLESPACE new_tablespace +// SET ( storage_parameter [= value] [, ... ] ) +// RESET ( storage_parameter [, ... ] ) +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +fn alter_materialized_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, MATERIALIZED_KW) && p.nth_at(2, VIEW_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(MATERIALIZED_KW); + p.bump(VIEW_KW); + if p.eat(ALL_KW) { + p.expect(IN_KW); + p.expect(TABLESPACE_KW); + name_ref(p); + if p.eat(OWNED_KW) { + p.expect(BY_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + p.expect(SET_KW); + p.expect(TABLESPACE_KW); + name(p); + p.eat(NOWAIT_KW); + } else { + opt_if_exists(p); + path_name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + if p.eat(TO_KW) { + name(p); + } else { + p.eat(COLUMN_KW); + name_ref(p); + p.expect(TO_KW); + name(p); + } + } + SET_KW if p.nth_at(1, SCHEMA_KW) => { + p.bump(SET_KW); + p.bump(SCHEMA_KW); + name_ref(p); + } + DEPENDS_KW | NO_KW => { + p.eat(NO_KW); + p.expect(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + name_ref(p); + } + ALTER_KW | CLUSTER_KW | SET_KW | RESET_KW | OWNER_KW => { + // TODO: we should be robust to missing commas + while !p.at(EOF) { + let action = p.start(); + match alter_table_action(p) { + Some(action_kind) => { + action.complete(p, action_kind); + } + None => { + action.abandon(p); + } + }; + if !p.eat(COMMA) { + break; + } + } + } + _ => { + p.error("Expected RENAME, SET SCHEMA, [NO] DEPENDS, or action (ALTER, CLUSTER, SET, RESET, OWNER)"); + } + } + } + m.complete(p, ALTER_MATERIALIZED_VIEW_STMT) +} + +// ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +fn alter_large_object_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, LARGE_KW) && p.nth_at(2, OBJECT_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(LARGE_KW); + p.bump(OBJECT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + p.expect(OWNER_KW); + p.expect(TO_KW); + role(p); + m.complete(p, ALTER_LARGE_OBJECT_STMT) +} + +// ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO new_name +// ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +fn alter_language_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && (p.nth_at(1, PROCEDURAL_KW) || p.nth_at(1, LANGUAGE_KW))); + let m = p.start(); + p.bump(ALTER_KW); + p.eat(PROCEDURAL_KW); + p.expect(LANGUAGE_KW); + name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + _ => { + p.error("expected RENAME or OWNER"); + } + } + m.complete(p, ALTER_LANGUAGE_STMT) +} + +// ALTER INDEX ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] +// SET TABLESPACE new_tablespace [ NOWAIT ] +// ALTER INDEX name ATTACH PARTITION index_name +// ALTER INDEX name [ NO ] DEPENDS ON EXTENSION extension_name +// ALTER INDEX [ IF EXISTS ] name RENAME TO new_name +// ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name +// ALTER INDEX [ IF EXISTS ] name SET ( storage_parameter [= value] [, ... ] ) +// ALTER INDEX [ IF EXISTS ] name RESET ( storage_parameter [, ... ] ) +// ALTER INDEX [ IF EXISTS ] name ALTER [ COLUMN ] column_number +// SET STATISTICS integer +fn alter_index_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, INDEX_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(INDEX_KW); + if p.eat(ALL_KW) { + p.expect(IN_KW); + p.expect(TABLESPACE_KW); + path_name_ref(p); + if p.eat(OWNED_KW) { + p.expect(BY_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + p.expect(SET_KW); + p.expect(TABLESPACE_KW); + name_ref(p); + p.eat(NOWAIT_KW); + } else { + opt_if_exists(p); + path_name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + path_name_ref(p); + } + SET_KW => { + p.bump(SET_KW); + if p.at(TABLESPACE_KW) { + p.bump(TABLESPACE_KW); + path_name_ref(p); + } else { + p.expect(L_PAREN); + storage_parameter(p); + while !p.at(EOF) && p.eat(COMMA) { + storage_parameter(p); + } + p.expect(R_PAREN); + } + } + ATTACH_KW => { + p.bump(ATTACH_KW); + p.expect(PARTITION_KW); + path_name_ref(p); + } + DEPENDS_KW | NO_KW => { + p.eat(NO_KW); + p.bump(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + path_name_ref(p); + } + RESET_KW => { + p.bump(RESET_KW); + p.expect(L_PAREN); + storage_parameter(p); + while !p.at(EOF) && p.eat(COMMA) { + storage_parameter(p); + } + p.expect(R_PAREN); + } + ALTER_KW => { + p.bump(ALTER_KW); + p.eat(COLUMN_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + p.expect(SET_KW); + p.expect(STATISTICS_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + } + _ => { + p.error("expected RENAME, SET, ATTACH, DEPENDS, RESET, or ALTER"); + } + } + } + m.complete(p, ALTER_INDEX_STMT) +} + +// ALTER GROUP role_specification ADD USER user_name [, ... ] +// ALTER GROUP role_specification DROP USER user_name [, ... ] +// where role_specification can be: +// role_name +// | CURRENT_ROLE +// | CURRENT_USER +// | SESSION_USER +// ALTER GROUP group_name RENAME TO new_name +fn alter_group_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, GROUP_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(GROUP_KW); + role(p); + match p.current() { + ADD_KW | DROP_KW => { + p.bump_any(); + p.expect(USER_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + p.error("expected ADD, DROP, or RENAME"); + } + } + m.complete(p, ALTER_GROUP_STMT) +} + +// ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// action [ ... ] [ RESTRICT ] +// ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// RENAME TO new_name +// ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// SET SCHEMA new_schema +// ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] +// [ NO ] DEPENDS ON EXTENSION extension_name +// where action is one of: +// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT +// IMMUTABLE | STABLE | VOLATILE +// [ NOT ] LEAKPROOF +// [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER +// PARALLEL { UNSAFE | RESTRICTED | SAFE } +// COST execution_cost +// ROWS result_rows +// SUPPORT support_function +// SET configuration_parameter { TO | = } { value | DEFAULT } +// SET configuration_parameter FROM CURRENT +// RESET configuration_parameter +// RESET ALL +fn alter_function_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, FUNCTION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(FUNCTION_KW); + path_name_ref(p); + opt_param_list(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW if p.nth_at(1, SCHEMA_KW) => { + p.bump(SET_KW); + p.bump(SCHEMA_KW); + name_ref(p); + } + DEPENDS_KW | NO_KW => { + p.eat(NO_KW); + p.expect(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + name_ref(p); + } + _ => { + func_option_list(p); + } + } + p.eat(RESTRICT_KW); + m.complete(p, ALTER_FUNCTION_STMT) +} + +// ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// action [, ... ] +// ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// RENAME [ COLUMN ] column_name TO new_column_name +// ALTER FOREIGN TABLE [ IF EXISTS ] name +// RENAME TO new_name +// ALTER FOREIGN TABLE [ IF EXISTS ] name +// SET SCHEMA new_schema +// +// where action is one of: +// ADD [ COLUMN ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] +// DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ] +// ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] +// ALTER [ COLUMN ] column_name SET DEFAULT expression +// ALTER [ COLUMN ] column_name DROP DEFAULT +// ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL +// ALTER [ COLUMN ] column_name SET STATISTICS integer +// ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) +// ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) +// ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } +// ALTER [ COLUMN ] column_name OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) +// ADD table_constraint [ NOT VALID ] +// VALIDATE CONSTRAINT constraint_name +// DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] +// DISABLE TRIGGER [ trigger_name | ALL | USER ] +// ENABLE TRIGGER [ trigger_name | ALL | USER ] +// ENABLE REPLICA TRIGGER trigger_name +// ENABLE ALWAYS TRIGGER trigger_name +// SET WITHOUT OIDS +// INHERIT parent_table +// NO INHERIT parent_table +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) +fn alter_foreign_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, TABLE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(FOREIGN_KW); + p.bump(TABLE_KW); + opt_if_exists(p); + relation_name(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + if p.eat(TO_KW) { + name(p); + } else { + p.eat(COLUMN_KW); + name_ref(p); + p.expect(TO_KW); + name(p); + } + } + SET_KW if p.nth_at(1, SCHEMA_KW) => { + p.bump(SET_KW); + p.bump(SCHEMA_KW); + name_ref(p); + } + _ => { + // TODO: we should be robust to missing commas + while !p.at(EOF) { + let action = p.start(); + match alter_table_action(p) { + Some(action_kind) => { + action.complete(p, action_kind); + } + None => { + action.abandon(p); + } + }; + if !p.eat(COMMA) { + break; + } + } + } + } + m.complete(p, ALTER_FOREIGN_TABLE_STMT) +} + +// ALTER FOREIGN DATA WRAPPER name +// [ HANDLER handler_function | NO HANDLER ] +// [ VALIDATOR validator_function | NO VALIDATOR ] +// [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) ] +// ALTER FOREIGN DATA WRAPPER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER FOREIGN DATA WRAPPER name RENAME TO new_name +fn alter_foreign_data_wrapper_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(ALTER_KW) + && p.nth_at(1, FOREIGN_KW) + && p.nth_at(2, DATA_KW) + && p.nth_at(3, WRAPPER_KW) + ); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(FOREIGN_KW); + p.bump(DATA_KW); + p.bump(WRAPPER_KW); + name_ref(p); + let mut found_option = false; + match p.current() { + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + found_option = true; + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + found_option = true; + } + _ => { + while !p.at(EOF) { + if !opt_fdw_option(p) { + break; + } + found_option = true; + } + } + } + if !found_option { + p.error("Missing alter foreign data wrapper option or action.") + } + m.complete(p, ALTER_FOREIGN_DATA_WRAPPER_STMT) +} + +// ALTER EVENT TRIGGER name DISABLE +// ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ] +// ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER EVENT TRIGGER name RENAME TO new_name +fn alter_event_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, EVENT_KW) && p.nth_at(2, TRIGGER_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(EVENT_KW); + p.bump(TRIGGER_KW); + name_ref(p); + match p.current() { + DISABLE_KW => { + p.bump(DISABLE_KW); + } + ENABLE_KW => { + p.bump(ENABLE_KW); + let _ = p.eat(REPLICA_KW) || p.eat(ALWAYS_KW); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + p.error("expected DISABLE, ENABLE, OWNER, or RENAME"); + } + } + m.complete(p, ALTER_EVENT_TRIGGER_STMT) +} + +// ALTER EXTENSION name UPDATE [ TO new_version ] +// ALTER EXTENSION name SET SCHEMA new_schema +// ALTER EXTENSION name ADD member_object +// ALTER EXTENSION name DROP member_object +// +// where member_object is: +// ACCESS METHOD object_name | +// AGGREGATE aggregate_name ( aggregate_signature ) | +// CAST (source_type AS target_type) | +// COLLATION object_name | +// CONVERSION object_name | +// DOMAIN object_name | +// EVENT TRIGGER object_name | +// FOREIGN DATA WRAPPER object_name | +// FOREIGN TABLE object_name | +// FUNCTION function_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// MATERIALIZED VIEW object_name | +// OPERATOR operator_name (left_type, right_type) | +// OPERATOR CLASS object_name USING index_method | +// OPERATOR FAMILY object_name USING index_method | +// [ PROCEDURAL ] LANGUAGE object_name | +// PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// ROUTINE routine_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// SCHEMA object_name | +// SEQUENCE object_name | +// SERVER object_name | +// TABLE object_name | +// TEXT SEARCH CONFIGURATION object_name | +// TEXT SEARCH DICTIONARY object_name | +// TEXT SEARCH PARSER object_name | +// TEXT SEARCH TEMPLATE object_name | +// TRANSFORM FOR type_name LANGUAGE lang_name | +// TYPE object_name | +// VIEW object_name +// +// and aggregate_signature is: +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +fn alter_extension_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, EXTENSION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(EXTENSION_KW); + name_ref(p); + match p.current() { + UPDATE_KW => { + p.bump(UPDATE_KW); + if p.eat(TO_KW) { + if p.at_ts(NON_RESERVED_WORD) { + p.bump_any(); + } else { + string_literal(p); + } + } + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + name_ref(p); + } + ADD_KW | DROP_KW => { + p.bump_any(); + match p.current() { + SCHEMA_KW | DOMAIN_KW | TABLE_KW | TYPE_KW | EXTENSION_KW | PUBLICATION_KW + | SERVER_KW | DATABASE_KW | ROLE_KW | SUBSCRIPTION_KW | TABLESPACE_KW => { + p.bump_any(); + name_ref(p); + } + COLLATION_KW | CONVERSION_KW | SEQUENCE_KW | VIEW_KW | INDEX_KW | STATISTICS_KW => { + p.bump_any(); + path_name_ref(p); + } + ACCESS_KW => { + p.bump(ACCESS_KW); + p.expect(METHOD_KW); + name_ref(p); + } + AGGREGATE_KW => { + p.bump(AGGREGATE_KW); + path_name_ref(p); + aggregate_arg_list(p); + } + CAST_KW => { + p.bump(CAST_KW); + source_type_as_target_type(p); + } + EVENT_KW => { + p.bump(EVENT_KW); + p.expect(TRIGGER_KW); + name_ref(p); + } + FOREIGN_KW => { + p.bump(FOREIGN_KW); + if p.eat(DATA_KW) { + p.expect(WRAPPER_KW); + name_ref(p); + } else { + p.expect(TABLE_KW); + path_name_ref(p); + } + } + FUNCTION_KW | PROCEDURE_KW | ROUTINE_KW => { + p.bump_any(); + path_name_ref(p); + opt_param_list(p); + } + MATERIALIZED_KW => { + p.bump(MATERIALIZED_KW); + p.expect(VIEW_KW); + path_name_ref(p); + } + OPERATOR_KW => { + p.bump(OPERATOR_KW); + match p.current() { + CLASS_KW => { + p.bump(CLASS_KW); + name_ref(p); + p.expect(USING_KW); + name_ref(p); + } + FAMILY_KW => { + p.bump(FAMILY_KW); + name_ref(p); + p.expect(USING_KW); + name_ref(p); + } + _ => { + operator(p); + p.expect(L_PAREN); + type_name(p); + p.expect(COMMA); + type_name(p); + p.expect(R_PAREN); + } + } + } + LANGUAGE_KW | PROCEDURAL_KW => { + p.eat(PROCEDURAL_KW); + p.bump(LANGUAGE_KW); + name_ref(p); + } + TEXT_KW => { + p.bump(TEXT_KW); + p.expect(SEARCH_KW); + match p.current() { + CONFIGURATION_KW => { + p.bump(CONFIGURATION_KW); + path_name_ref(p); + } + DICTIONARY_KW => { + p.bump(DICTIONARY_KW); + path_name_ref(p); + } + PARSER_KW => { + p.bump(PARSER_KW); + path_name_ref(p); + } + TEMPLATE_KW => { + p.bump(TEMPLATE_KW); + path_name_ref(p); + } + _ => { + p.error("expected CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE after TEXT SEARCH"); + } + } + } + TRANSFORM_KW => { + p.bump(TRANSFORM_KW); + p.expect(FOR_KW); + name_ref(p); + p.expect(LANGUAGE_KW); + name_ref(p); + } + _ => { + p.error("expected valid extension member object type"); + } + } + } + _ => { + p.error("expected UPDATE, SET, ADD, or DROP"); + } + } + m.complete(p, ALTER_EXTENSION_STMT) +} + +// ALTER DOMAIN name +// { SET DEFAULT expression | DROP DEFAULT } +// ALTER DOMAIN name +// { SET | DROP } NOT NULL +// ALTER DOMAIN name +// ADD domain_constraint [ NOT VALID ] +// ALTER DOMAIN name +// DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] +// ALTER DOMAIN name +// RENAME CONSTRAINT constraint_name TO new_constraint_name +// ALTER DOMAIN name +// VALIDATE CONSTRAINT constraint_name +// ALTER DOMAIN name +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER DOMAIN name +// RENAME TO new_name +// ALTER DOMAIN name +// SET SCHEMA new_schema +// +// where domain_constraint is: +// [ CONSTRAINT constraint_name ] +// { NOT NULL | CHECK (expression) } +fn alter_domain_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, DOMAIN_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(DOMAIN_KW); + path_name_ref(p); + alter_domain_action(p); + m.complete(p, ALTER_DOMAIN_STMT) +} + +fn alter_domain_action(p: &mut Parser<'_>) -> Option { + let m = p.start(); + let action = match p.current() { + SET_KW => { + p.bump(SET_KW); + match p.current() { + DEFAULT_KW => { + p.bump(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected expression"); + } + SET_DEFAULT + } + NOT_KW => { + p.bump(NOT_KW); + p.expect(NULL_KW); + SET_NOT_NULL + } + SCHEMA_KW => { + p.bump(SCHEMA_KW); + name_ref(p); + SET_SCHEMA + } + _ => { + p.error("expected DEFAULT, NOT, or SCHEMA"); + m.abandon(p); + return None; + } + } + } + DROP_KW => { + p.bump(DROP_KW); + match p.current() { + DEFAULT_KW => { + p.bump(DEFAULT_KW); + DROP_DEFAULT + } + NOT_KW => { + p.bump(NOT_KW); + p.expect(NULL_KW); + DROP_NOT_NULL + } + CONSTRAINT_KW => { + p.bump(CONSTRAINT_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + DROP_CONSTRAINT + } + _ => { + p.error("expected DEFAULT, NOT, or CONSTRAINT"); + m.abandon(p); + return None; + } + } + } + ADD_KW => { + p.bump(ADD_KW); + domain_constraint(p); + if p.eat(NOT_KW) { + p.expect(VALID_KW); + } + ADD_CONSTRAINT + } + RENAME_KW => { + p.bump(RENAME_KW); + if p.eat(CONSTRAINT_KW) { + name_ref(p); + p.expect(TO_KW); + name(p); + RENAME_CONSTRAINT + } else { + p.expect(TO_KW); + name(p); + RENAME_TO + } + } + VALIDATE_KW => { + p.bump(VALIDATE_KW); + p.expect(CONSTRAINT_KW); + name_ref(p); + VALIDATE_CONSTRAINT + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + OWNER_TO + } + _ => { + p.error("expected SET, DROP, ADD, RENAME, VALIDATE, or OWNER"); + m.abandon(p); + return None; + } + }; + Some(m.complete(p, action)) +} + +// [ CONSTRAINT constraint_name ] +// { NOT NULL | CHECK (expression) } +fn domain_constraint(p: &mut Parser<'_>) { + let m = p.start(); + if p.eat(CONSTRAINT_KW) { + name(p); + } + if p.eat(NOT_KW) { + p.expect(NULL_KW); + m.complete(p, NOT_NULL_CONSTRAINT); + } else if p.eat(CHECK_KW) { + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + m.complete(p, CHECK_CONSTRAINT); + } else { + p.error("expected NOT NULL or CHECK constraint"); + m.abandon(p); + } +} + +// ALTER DEFAULT PRIVILEGES +// [ FOR { ROLE | USER } target_role [, ...] ] +// [ IN SCHEMA schema_name [, ...] ] +// abbreviated_grant_or_revoke +// +// where abbreviated_grant_or_revoke is one of: +// GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +// [, ...] | ALL [ PRIVILEGES ] } +// ON TABLES +// TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] +// +// GRANT { { USAGE | SELECT | UPDATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON SEQUENCES +// TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] +// +// GRANT { EXECUTE | ALL [ PRIVILEGES ] } +// ON { FUNCTIONS | ROUTINES } +// TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] +// +// GRANT { USAGE | ALL [ PRIVILEGES ] } +// ON TYPES +// TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] +// +// GRANT { { USAGE | CREATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON SCHEMAS +// TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] +// +// REVOKE [ GRANT OPTION FOR ] +// { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +// [, ...] | ALL [ PRIVILEGES ] } +// ON TABLES +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +// +// REVOKE [ GRANT OPTION FOR ] +// { { USAGE | SELECT | UPDATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON SEQUENCES +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +// +// REVOKE [ GRANT OPTION FOR ] +// { EXECUTE | ALL [ PRIVILEGES ] } +// ON { FUNCTIONS | ROUTINES } +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +// +// REVOKE [ GRANT OPTION FOR ] +// { USAGE | ALL [ PRIVILEGES ] } +// ON TYPES +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +// +// REVOKE [ GRANT OPTION FOR ] +// { { USAGE | CREATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON SCHEMAS +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +fn alter_default_privileges_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, DEFAULT_KW) && p.nth_at(2, PRIVILEGES_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(DEFAULT_KW); + p.bump(PRIVILEGES_KW); + // [ FOR { ROLE | USER } target_role [, ...] ] + if p.eat(FOR_KW) { + if !p.eat(ROLE_KW) && !p.eat(USER_KW) { + p.error("expected ROLE or USER"); + } + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + // [ IN SCHEMA schema_name [, ...] ] + if p.eat(IN_KW) { + p.expect(SCHEMA_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + match p.current() { + GRANT_KW => { + p.bump(GRANT_KW); + privileges(p); + p.expect(ON_KW); + privilege_target(p); + p.expect(TO_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + if p.eat(WITH_KW) { + p.expect(GRANT_KW); + p.expect(OPTION_KW); + } + } + REVOKE_KW => { + p.bump(REVOKE_KW); + if p.eat(GRANT_KW) { + p.eat(OPTION_KW); + p.eat(FOR_KW); + } + privileges(p); + p.expect(ON_KW); + privilege_target(p); + p.expect(FROM_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + opt_cascade_or_restrict(p); + } + _ => { + p.error("expected GRANT or REVOKE"); + } + } + m.complete(p, ALTER_DEFAULT_PRIVILEGES_STMT) +} + +fn privilege_target(p: &mut Parser<'_>) { + match p.current() { + TABLES_KW | FUNCTIONS_KW | ROUTINES_KW | SEQUENCES_KW | TYPES_KW | SCHEMAS_KW => { + p.bump_any(); + } + _ => p.error( + "expected privilege target, TABLES, FUNCTIONS, ROUTINES, SEQEUNCES, TYPES, SCHEMAS", + ), + } +} + +// ALTER DATABASE name [ [ WITH ] option [ ... ] ] +// where option can be: +// ALLOW_CONNECTIONS allowconn +// CONNECTION LIMIT connlimit +// IS_TEMPLATE istemplate +// +// ALTER DATABASE name RENAME TO new_name +// ALTER DATABASE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER DATABASE name SET TABLESPACE new_tablespace +// ALTER DATABASE name REFRESH COLLATION VERSION +// ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT } +// ALTER DATABASE name SET configuration_parameter FROM CURRENT +// ALTER DATABASE name RESET configuration_parameter +// ALTER DATABASE name RESET ALL +fn alter_database_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, DATABASE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(DATABASE_KW); + name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW if p.nth_at(1, TABLESPACE_KW) => { + p.bump(SET_KW); + p.bump(TABLESPACE_KW); + name_ref(p); + } + SET_KW => { + set_configuration_param(p); + } + RESET_KW => { + p.bump(RESET_KW); + if !p.eat(ALL_KW) { + path_name_ref(p); + } + } + REFRESH_KW => { + p.bump(REFRESH_KW); + p.expect(COLLATION_KW); + p.expect(VERSION_KW); + } + _ => { + p.eat(WITH_KW); + while !p.at(EOF) { + if !opt_create_database_option(p) { + break; + } + } + } + } + m.complete(p, ALTER_DATABASE_STMT) +} + +// ALTER CONVERSION name RENAME TO new_name +// ALTER CONVERSION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER CONVERSION name SET SCHEMA new_schema +fn alter_conversion_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, CONVERSION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(CONVERSION_KW); + path_name_ref(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + name_ref(p); + } + _ => { + p.error("expected RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_CONVERSION_STMT) +} + +// ALTER COLLATION name REFRESH VERSION +// ALTER COLLATION name RENAME TO new_name +// ALTER COLLATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER COLLATION name SET SCHEMA new_schema +fn alter_collation_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, COLLATION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(COLLATION_KW); + path_name_ref(p); + match p.current() { + REFRESH_KW => { + p.bump(REFRESH_KW); + p.expect(VERSION_KW); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + name_ref(p); + } + _ => { + p.error("expected REFRESH, RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_COLLATION_STMT) +} + +// ALTER AGGREGATE name ( aggregate_signature ) RENAME TO new_name +// ALTER AGGREGATE name ( aggregate_signature ) +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER AGGREGATE name ( aggregate_signature ) SET SCHEMA new_schema +// +// where aggregate_signature is: +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +fn alter_aggregate_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, AGGREGATE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(AGGREGATE_KW); + path_name_ref(p); + aggregate_arg_list(p); + match p.current() { + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + path_name_ref(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + path_name_ref(p); + } + _ => { + p.error("expected RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_AGGREGATE_STMT) +} + +// ALTER SUBSCRIPTION name CONNECTION 'conninfo' +// ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] +// ALTER SUBSCRIPTION name ADD PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] +// ALTER SUBSCRIPTION name DROP PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] +// ALTER SUBSCRIPTION name REFRESH PUBLICATION [ WITH ( refresh_option [= value] [, ... ] ) ] +// ALTER SUBSCRIPTION name ENABLE +// ALTER SUBSCRIPTION name DISABLE +// ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] ) +// ALTER SUBSCRIPTION name SKIP ( skip_option = value ) +// ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER SUBSCRIPTION name RENAME TO new_name +fn alter_subscription_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, SUBSCRIPTION_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(SUBSCRIPTION_KW); + name_ref(p); + match p.current() { + CONNECTION_KW => { + p.bump(CONNECTION_KW); + string_literal(p); + } + SET_KW if p.nth_at(1, L_PAREN) => { + p.bump(SET_KW); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + SET_KW | ADD_KW => { + p.bump_any(); + p.expect(PUBLICATION_KW); + name(p); + while !p.at(EOF) && p.eat(COMMA) { + name(p); + } + opt_with_options_list(p); + } + DROP_KW => { + p.bump(DROP_KW); + p.expect(PUBLICATION_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_with_options_list(p); + } + REFRESH_KW => { + p.bump(REFRESH_KW); + p.expect(PUBLICATION_KW); + opt_with_options_list(p); + } + ENABLE_KW | DISABLE_KW => { + p.bump_any(); + } + SKIP_KW => { + p.bump(SKIP_KW); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + name(p); + } + _ => { + p.error( + "expected CONNECTION, SET, ADD, DROP, REFRESH, ENABLE, DISABLE, SKIP, OWNER or RENAME", + ); + } + } + m.complete(p, ALTER_SUBSCRIPTION_STMT) +} + +fn opt_with_options_list(p: &mut Parser<'_>) { + if p.eat(WITH_KW) { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } +} + +// ALTER SYSTEM SET configuration_parameter { TO | = } { value [, ...] | DEFAULT } +// ALTER SYSTEM RESET configuration_parameter +// ALTER SYSTEM RESET ALL +fn alter_system_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, SYSTEM_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(SYSTEM_KW); + if p.at(SET_KW) { + set_configuration_param(p); + } else if p.eat(RESET_KW) { + if !p.eat(ALL_KW) { + path_name_ref(p); + } + } else { + p.error("expected SET or RESET after ALTER SYSTEM"); + } + m.complete(p, ALTER_SYSTEM_STMT) +} + +// ALTER TABLESPACE name RENAME TO new_name +// ALTER TABLESPACE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER TABLESPACE name SET ( tablespace_option = value [, ... ] ) +// ALTER TABLESPACE name RESET ( tablespace_option [, ... ] ) +fn alter_tablespace_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, TABLESPACE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TABLESPACE_KW); + path_name_ref(p); + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name(p); + } else if p.eat(OWNER_KW) { + p.expect(TO_KW); + role(p); + } else if p.eat(SET_KW) || p.eat(RESET_KW) { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !storage_parameter(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } else { + p.error("expected RENAME, OWNER, SET, or RESET after tablespace name"); + } + m.complete(p, ALTER_TABLESPACE_STMT) +} + +// ALTER TEXT SEARCH PARSER name RENAME TO new_name +// ALTER TEXT SEARCH PARSER name SET SCHEMA new_schema +fn alter_text_search_parser_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(ALTER_KW) && p.nth_at(1, TEXT_KW) && p.nth_at(2, SEARCH_KW) && p.nth_at(3, PARSER_KW) + ); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(PARSER_KW); + path_name_ref(p); + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name_ref(p); + } else if p.eat(SET_KW) { + p.expect(SCHEMA_KW); + name_ref(p); + } else { + p.error("expected RENAME TO or SET SCHEMA"); + } + m.complete(p, ALTER_TEXT_SEARCH_PARSER_STMT) +} + +// ALTER TEXT SEARCH DICTIONARY name ( +// option [ = value ] [, ... ] +// ) +// ALTER TEXT SEARCH DICTIONARY name RENAME TO new_name +// ALTER TEXT SEARCH DICTIONARY name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER TEXT SEARCH DICTIONARY name SET SCHEMA new_schema +fn alter_text_search_dict_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(ALTER_KW) + && p.nth_at(1, TEXT_KW) + && p.nth_at(2, SEARCH_KW) + && p.nth_at(3, DICTIONARY_KW) + ); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(DICTIONARY_KW); + path_name_ref(p); + if p.eat(L_PAREN) { + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } else if p.eat(RENAME_KW) { + p.expect(TO_KW); + name(p); + } else if p.eat(OWNER_KW) { + p.expect(TO_KW); + role(p); + } else if p.eat(SET_KW) { + p.expect(SCHEMA_KW); + name(p); + } else { + p.error("expected '(', RENAME, OWNER, or SET"); + } + m.complete(p, ALTER_TEXT_SEARCH_DICTIONARY_STMT) +} + +// ALTER TEXT SEARCH CONFIGURATION name +// ADD MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ] +// ALTER TEXT SEARCH CONFIGURATION name +// ALTER MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ] +// ALTER TEXT SEARCH CONFIGURATION name +// ALTER MAPPING REPLACE old_dictionary WITH new_dictionary +// ALTER TEXT SEARCH CONFIGURATION name +// ALTER MAPPING FOR token_type [, ... ] REPLACE old_dictionary WITH new_dictionary +// ALTER TEXT SEARCH CONFIGURATION name +// DROP MAPPING [ IF EXISTS ] FOR token_type [, ... ] +// ALTER TEXT SEARCH CONFIGURATION name +// RENAME TO new_name +// ALTER TEXT SEARCH CONFIGURATION name +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER TEXT SEARCH CONFIGURATION name +// SET SCHEMA new_schema +fn alter_text_search_configuration(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(ALTER_KW) + && p.nth_at(1, TEXT_KW) + && p.nth_at(2, SEARCH_KW) + && p.nth_at(3, CONFIGURATION_KW) + ); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(CONFIGURATION_KW); + path_name_ref(p); + match p.current() { + // ADD MAPPING FOR token_type + ADD_KW => { + p.bump(ADD_KW); + p.expect(MAPPING_KW); + p.expect(FOR_KW); + name_ref_list(p); + p.expect(WITH_KW); + path_name_ref_list(p); + } + // ALTER MAPPING FOR + // ALTER MAPPING REPLACE + // ALTER MAPPING FOR ... REPLACE + ALTER_KW => { + p.bump(ALTER_KW); + p.expect(MAPPING_KW); + if p.eat(FOR_KW) { + name_ref_list(p); + if p.eat(WITH_KW) { + path_name_ref_list(p); + } else if p.eat(REPLACE_KW) { + path_name_ref(p); + p.expect(WITH_KW); + path_name_ref(p); + } else { + p.error("expected WITH or REPLACE"); + } + } else if p.eat(REPLACE_KW) { + path_name_ref(p); + p.expect(WITH_KW); + path_name_ref(p); + } else { + p.error("expected FOR or REPLACE"); + } + } + DROP_KW => { + p.bump(DROP_KW); + p.expect(MAPPING_KW); + opt_if_exists(p); + p.expect(FOR_KW); + name_ref_list(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + p.expect(TO_KW); + path_name_ref(p); + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + p.expect(SCHEMA_KW); + path_name_ref(p); + } + _ => { + p.error("expected ADD, ALTER, DROP, RENAME, OWNER, or SET"); + } + } + m.complete(p, ALTER_TEXT_SEARCH_CONFIGURATION_STMT) +} + +fn name_ref_list(p: &mut Parser<'_>) { + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } +} + +fn path_name_ref_list(p: &mut Parser<'_>) { + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } +} + +// ALTER TEXT SEARCH TEMPLATE name RENAME TO new_name +// ALTER TEXT SEARCH TEMPLATE name SET SCHEMA new_schema +fn alter_text_search_template_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(ALTER_KW) + && p.nth_at(1, TEXT_KW) + && p.nth_at(2, SEARCH_KW) + && p.nth_at(3, TEMPLATE_KW) + ); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(TEMPLATE_KW); + path_name_ref(p); + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name(p); + } else if p.eat(SET_KW) { + p.expect(SCHEMA_KW); + name(p); + } else { + p.error("expected RENAME TO or SET SCHEMA"); + } + m.complete(p, ALTER_TEXT_SEARCH_TEMPLATE_STMT) +} + +// ALTER TRIGGER name ON table_name RENAME TO new_name +// ALTER TRIGGER name ON table_name [ NO ] DEPENDS ON EXTENSION extension_name +fn alter_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, TRIGGER_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TRIGGER_KW); + name_ref(p); + p.expect(ON_KW); + path_name_ref(p); + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name_ref(p); + } else { + p.eat(NO_KW); + p.expect(DEPENDS_KW); + p.expect(ON_KW); + p.expect(EXTENSION_KW); + name_ref(p); + } + m.complete(p, ALTER_TRIGGER_STMT) +} + +fn alter_type_action(p: &mut Parser<'_>) { + if p.eat(ADD_KW) { + p.expect(ATTRIBUTE_KW); + name(p); + type_name(p); + opt_collate(p); + opt_cascade_or_restrict(p); + } else if p.eat(DROP_KW) { + p.expect(ATTRIBUTE_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + } else { + p.expect(ALTER_KW); + p.expect(ATTRIBUTE_KW); + name_ref(p); + if p.eat(SET_KW) { + p.eat(DATA_KW); + } + p.expect(TYPE_KW); + type_name(p); + opt_collate(p); + opt_cascade_or_restrict(p); + } +} + +// ALTER TYPE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER TYPE name RENAME TO new_name +// ALTER TYPE name SET SCHEMA new_schema +// ALTER TYPE name RENAME ATTRIBUTE attribute_name TO new_attribute_name [ CASCADE | RESTRICT ] +// ALTER TYPE name action [, ... ] +// ALTER TYPE name ADD VALUE [ IF NOT EXISTS ] new_enum_value [ { BEFORE | AFTER } neighbor_enum_value ] +// ALTER TYPE name RENAME VALUE existing_enum_value TO new_enum_value +// ALTER TYPE name SET ( property = value [, ... ] ) +// +// where action is one of: +// ADD ATTRIBUTE attribute_name data_type [ COLLATE collation ] [ CASCADE | RESTRICT ] +// DROP ATTRIBUTE [ IF EXISTS ] attribute_name [ CASCADE | RESTRICT ] +// ALTER ATTRIBUTE attribute_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ CASCADE | RESTRICT ] +fn alter_type_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, TYPE_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(TYPE_KW); + path_name_ref(p); + match p.current() { + ADD_KW | DROP_KW | ALTER_KW if p.nth_at(1, ATTRIBUTE_KW) => { + alter_type_action(p); + while !p.at(EOF) && p.eat(COMMA) { + alter_type_action(p); + } + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + SET_KW => { + p.bump(SET_KW); + if p.eat(SCHEMA_KW) { + name_ref(p); + } else { + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + } + RENAME_KW => { + p.bump(RENAME_KW); + if p.eat(TO_KW) { + name(p); + } else if p.eat(ATTRIBUTE_KW) { + name_ref(p); + p.expect(TO_KW); + name(p); + opt_cascade_or_restrict(p); + } else if p.eat(VALUE_KW) { + string_literal(p); + p.expect(TO_KW); + string_literal(p); + } else { + p.error("expected TO, ATTRIBUTE, or VALUE"); + } + } + ADD_KW => { + p.bump(ADD_KW); + if p.eat(VALUE_KW) { + opt_if_not_exists(p); + string_literal(p); + if p.eat(BEFORE_KW) || p.eat(AFTER_KW) { + string_literal(p); + } + } else if p.eat(ATTRIBUTE_KW) { + name(p); + type_name(p); + opt_collate(p); + opt_cascade_or_restrict(p); + } else { + p.error("expected VALUE or ATTRIBUTE"); + } + } + _ => p.error("expected ALTER TYPE option"), + } + m.complete(p, ALTER_TYPE_STMT) +} + +// ALTER USER role_specification [ WITH ] option [ ... ] +// where option can be: +// SUPERUSER | NOSUPERUSER +// | CREATEDB | NOCREATEDB +// | CREATEROLE | NOCREATEROLE +// | INHERIT | NOINHERIT +// | LOGIN | NOLOGIN +// | REPLICATION | NOREPLICATION +// | BYPASSRLS | NOBYPASSRLS +// | CONNECTION LIMIT connlimit +// | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL +// | VALID UNTIL 'timestamp' +// +// ALTER USER name RENAME TO new_name +// ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } +// ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT +// ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter +// ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL +// +// where role_specification can be: +// role_name +// | CURRENT_ROLE +// | CURRENT_USER +// | SESSION_USER +fn alter_user_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, USER_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(USER_KW); + if !p.eat(ALL_KW) { + role(p); + } + // be careful of the case where we're at the IN of IN DATABASE + if p.eat(WITH_KW) || (p.at_ts(ROLE_OPTION_FIRST) && !p.nth_at(1, DATABASE_KW)) { + opt_role_option(p); + while !p.at(EOF) && p.at_ts(ROLE_OPTION_FIRST) { + opt_role_option(p); + } + return m.complete(p, ALTER_USER_STMT); + } + // RENAME TO new_name + if p.eat(RENAME_KW) { + p.expect(TO_KW); + name_ref(p); + return m.complete(p, ALTER_USER_STMT); + } + if p.eat(IN_KW) { + p.expect(DATABASE_KW); + name_ref(p); + } + match p.current() { + SET_KW => { + set_configuration_param(p); + } + RESET_KW => { + p.bump(RESET_KW); + if !p.eat(ALL_KW) { + name_ref(p); + } + } + _ => p.error("expected SET or RESET"), + } + m.complete(p, ALTER_USER_STMT) +} + +// ALTER USER MAPPING FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC } +// SERVER server_name +// OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) +fn alter_user_mapping_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, USER_KW) && p.nth_at(2, MAPPING_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(USER_KW); + p.bump(MAPPING_KW); + p.expect(FOR_KW); + role(p); + p.expect(SERVER_KW); + name_ref(p); + p.expect(OPTIONS_KW); + p.expect(L_PAREN); + alter_option(p); + while !p.at(EOF) && p.eat(COMMA) { + alter_option(p); + } + p.expect(R_PAREN); + m.complete(p, ALTER_USER_MAPPING_STMT) +} + +fn alter_option(p: &mut Parser<'_>) { + let arg_required = match p.current() { + DROP_KW => { + p.bump(DROP_KW); + false + } + ADD_KW | SET_KW => { + p.bump_any(); + true + } + _ => true, + }; + if arg_required { + let _ = p.eat(ADD_KW) || p.eat(SET_KW); + } + col_label(p); + if arg_required { + string_literal(p); + } +} + +// ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name SET DEFAULT expression +// ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name DROP DEFAULT +// ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// ALTER VIEW [ IF EXISTS ] name RENAME [ COLUMN ] column_name TO new_column_name +// ALTER VIEW [ IF EXISTS ] name RENAME TO new_name +// ALTER VIEW [ IF EXISTS ] name SET SCHEMA new_schema +// ALTER VIEW [ IF EXISTS ] name SET ( view_option_name [= view_option_value] [, ... ] ) +// ALTER VIEW [ IF EXISTS ] name RESET ( view_option_name [, ... ] ) +fn alter_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW) && p.nth_at(1, VIEW_KW)); + let m = p.start(); + p.bump(ALTER_KW); + p.bump(VIEW_KW); + opt_if_exists(p); + path_name_ref(p); + match p.current() { + ALTER_KW => { + p.bump(ALTER_KW); + p.eat(COLUMN_KW); + name_ref(p); + if p.eat(SET_KW) { + p.expect(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected expression") + } + } else if p.eat(DROP_KW) { + p.expect(DEFAULT_KW); + } else { + p.error("expected SET or DROP"); + } + } + OWNER_KW => { + p.bump(OWNER_KW); + p.expect(TO_KW); + role(p); + } + RENAME_KW => { + p.bump(RENAME_KW); + if p.eat(TO_KW) { + name(p); + } else { + p.eat(COLUMN_KW); + name_ref(p); + p.expect(TO_KW); + name(p); + } + } + SET_KW => { + p.bump(SET_KW); + if p.eat(SCHEMA_KW) { + name_ref(p); + } else { + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + } + RESET_KW => { + p.bump(RESET_KW); + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + _ => p.error("expected ALTER, OWNER, RENAME, or SET"), + } + m.complete(p, ALTER_VIEW_STMT) +} + +// ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ] +// where option can be one of: +// VERBOSE [ boolean ] +// SKIP_LOCKED [ boolean ] +// BUFFER_USAGE_LIMIT size +// and table_and_columns is: +// table_name [ ( column_name [, ...] ) ] +fn analyze_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ANALYZE_KW) || p.at(ANALYSE_KW)); + let m = p.start(); + p.bump_any(); + if !p.eat(VERBOSE_KW) { + if p.eat(L_PAREN) { + cluster_option(p); + while !p.at(EOF) && p.eat(COMMA) { + cluster_option(p); + } + p.expect(R_PAREN); + } + } + opt_relation_list(p); + m.complete(p, ANALYZE_STMT) +} + +// COMMENT ON +// { +// ACCESS METHOD object_name | +// AGGREGATE aggregate_name ( aggregate_signature ) | +// CAST (source_type AS target_type) | +// COLLATION object_name | +// COLUMN relation_name.column_name | +// CONSTRAINT constraint_name ON table_name | +// CONSTRAINT constraint_name ON DOMAIN domain_name | +// CONVERSION object_name | +// DATABASE object_name | +// DOMAIN object_name | +// EXTENSION object_name | +// EVENT TRIGGER object_name | +// FOREIGN DATA WRAPPER object_name | +// FOREIGN TABLE object_name | +// FUNCTION function_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// INDEX object_name | +// LARGE OBJECT large_object_oid | +// MATERIALIZED VIEW object_name | +// OPERATOR operator_name (left_type, right_type) | +// OPERATOR CLASS object_name USING index_method | +// OPERATOR FAMILY object_name USING index_method | +// POLICY policy_name ON table_name | +// [ PROCEDURAL ] LANGUAGE object_name | +// PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// PUBLICATION object_name | +// ROLE object_name | +// ROUTINE routine_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// RULE rule_name ON table_name | +// SCHEMA object_name | +// SEQUENCE object_name | +// SERVER object_name | +// STATISTICS object_name | +// SUBSCRIPTION object_name | +// TABLE object_name | +// TABLESPACE object_name | +// TEXT SEARCH CONFIGURATION object_name | +// TEXT SEARCH DICTIONARY object_name | +// TEXT SEARCH PARSER object_name | +// TEXT SEARCH TEMPLATE object_name | +// TRANSFORM FOR type_name LANGUAGE lang_name | +// TRIGGER trigger_name ON table_name | +// TYPE object_name | +// VIEW object_name +// } IS { string_literal | NULL } +// +// where aggregate_signature is: +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +fn comment_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(COMMENT_KW)); + let m = p.start(); + p.bump(COMMENT_KW); + p.expect(ON_KW); + match p.current() { + ACCESS_KW => { + p.bump_any(); + p.expect(METHOD_KW); + path_name_ref(p); + } + AGGREGATE_KW => { + p.bump_any(); + path_name_ref(p); + aggregate_arg_list(p); + } + CAST_KW => { + p.bump_any(); + source_type_as_target_type(p); + } + COLLATION_KW | COLUMN_KW | CONVERSION_KW | DATABASE_KW | DOMAIN_KW | EXTENSION_KW + | INDEX_KW | LANGUAGE_KW | PUBLICATION_KW | ROLE_KW | SCHEMA_KW | SEQUENCE_KW + | SERVER_KW | STATISTICS_KW | SUBSCRIPTION_KW | TABLE_KW | TABLESPACE_KW | TYPE_KW + | VIEW_KW => { + p.bump_any(); + path_name_ref(p); + } + CONSTRAINT_KW => { + p.bump_any(); + name_ref(p); + p.expect(ON_KW); + p.eat(DOMAIN_KW); + path_name_ref(p); + } + EVENT_KW => { + p.bump_any(); + p.expect(TRIGGER_KW); + path_name_ref(p); + } + FOREIGN_KW if p.nth_at(1, DATA_KW) => { + p.bump_any(); + p.bump(DATA_KW); + p.expect(WRAPPER_KW); + path_name_ref(p); + } + FOREIGN_KW => { + p.bump_any(); + p.expect(TABLE_KW); + path_name_ref(p); + } + FUNCTION_KW | PROCEDURE_KW | ROUTINE_KW => { + p.bump_any(); + path_name_ref(p); + opt_param_list(p); + } + LARGE_KW => { + p.bump_any(); + p.expect(OBJECT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected object oid"); + } + } + MATERIALIZED_KW => { + p.bump_any(); + p.expect(VIEW_KW); + path_name_ref(p); + } + OPERATOR_KW if matches!(p.nth(1), CLASS_KW | FAMILY_KW) => { + p.bump_any(); + p.bump_any(); + path_name_ref(p); + if p.eat(USING_KW) { + name_ref(p); + } + } + OPERATOR_KW => { + p.bump_any(); + operator(p); + p.eat(L_PAREN); + type_name(p); + p.expect(COMMA); + type_name(p); + p.eat(R_PAREN); + } + POLICY_KW | RULE_KW | TRIGGER_KW => { + p.bump_any(); + name_ref(p); + p.expect(ON_KW); + path_name_ref(p); + } + PROCEDURAL_KW => { + p.bump_any(); + p.expect(LANGUAGE_KW); + path_name_ref(p); + } + TEXT_KW => { + p.bump_any(); + p.expect(SEARCH_KW); + match p.current() { + CONFIGURATION_KW | DICTIONARY_KW | PARSER_KW | TEMPLATE_KW => { + p.bump_any(); + path_name_ref(p); + } + _ => p.error("expected CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE"), + } + } + TRANSFORM_KW => { + p.bump_any(); + p.expect(FOR_KW); + type_name(p); + p.expect(LANGUAGE_KW); + name_ref(p); + } + _ => p.err_and_bump("unexpected token"), + } + p.expect(IS_KW); + if !p.eat(NULL_KW) && opt_string_literal(p).is_none() { + p.error("expected string literal or NULL"); + } + m.complete(p, COMMENT_STMT) +} + +// CLUSTER [ ( option [, ...] ) ] [ table_name [ USING index_name ] ] +// where option can be one of: +// VERBOSE [ boolean ] +fn cluster_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CLUSTER_KW)); + let m = p.start(); + p.bump(CLUSTER_KW); + if p.eat(VERBOSE_KW) { + // pass + } else if p.eat(L_PAREN) { + cluster_option(p); + while !p.at(EOF) && p.eat(COMMA) { + cluster_option(p); + } + p.expect(R_PAREN); + } + let has_name = opt_path_name_ref(p).is_some(); + if has_name && p.eat(ON_KW) { + path_name_ref(p); + } + if p.eat(USING_KW) { + name_ref(p); + } + m.complete(p, CLUSTER_STMT) +} + +fn cluster_option(p: &mut Parser<'_>) { + // option name + if p.at_ts(NON_RESERVED_WORD) || p.at(ANALYSE_KW) || p.at(ANALYZE_KW) || p.at(FORMAT_KW) { + p.bump_any(); + } else { + p.error("expected cluster option"); + } + opt_option_value(p); +} + +// CREATE ACCESS METHOD name +// TYPE access_method_type +// HANDLER handler_function +fn create_access_method_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.expect(ACCESS_KW); + p.expect(METHOD_KW); + path_name(p); + p.expect(TYPE_KW); + if !p.eat(TABLE_KW) && !p.eat(INDEX_KW) { + p.error("expected TABLE or INDEX"); + } + p.expect(HANDLER_KW); + path_name(p); + m.complete(p, CREATE_ACCESS_METHOD_STMT) +} + +// CREATE [ OR REPLACE ] AGGREGATE name ( [ argmode ] [ argname ] arg_data_type [ , ... ] ) ( +// SFUNC = sfunc, +// STYPE = state_data_type +// [ , SSPACE = state_data_size ] +// [ , FINALFUNC = ffunc ] +// [ , FINALFUNC_EXTRA ] +// [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] +// [ , COMBINEFUNC = combinefunc ] +// [ , SERIALFUNC = serialfunc ] +// [ , DESERIALFUNC = deserialfunc ] +// [ , INITCOND = initial_condition ] +// [ , MSFUNC = msfunc ] +// [ , MINVFUNC = minvfunc ] +// [ , MSTYPE = mstate_data_type ] +// [ , MSSPACE = mstate_data_size ] +// [ , MFINALFUNC = mffunc ] +// [ , MFINALFUNC_EXTRA ] +// [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] +// [ , MINITCOND = minitial_condition ] +// [ , SORTOP = sort_operator ] +// [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] +// ) +// +// CREATE [ OR REPLACE ] AGGREGATE name ( [ [ argmode ] [ argname ] arg_data_type [ , ... ] ] +// ORDER BY [ argmode ] [ argname ] arg_data_type [ , ... ] ) ( +// SFUNC = sfunc, +// STYPE = state_data_type +// [ , SSPACE = state_data_size ] +// [ , FINALFUNC = ffunc ] +// [ , FINALFUNC_EXTRA ] +// [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] +// [ , INITCOND = initial_condition ] +// [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] +// [ , HYPOTHETICAL ] +// ) +// +// or the old syntax +// +// CREATE [ OR REPLACE ] AGGREGATE name ( +// BASETYPE = base_type, +// SFUNC = sfunc, +// STYPE = state_data_type +// [ , SSPACE = state_data_size ] +// [ , FINALFUNC = ffunc ] +// [ , FINALFUNC_EXTRA ] +// [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] +// [ , COMBINEFUNC = combinefunc ] +// [ , SERIALFUNC = serialfunc ] +// [ , DESERIALFUNC = deserialfunc ] +// [ , INITCOND = initial_condition ] +// [ , MSFUNC = msfunc ] +// [ , MINVFUNC = minvfunc ] +// [ , MSTYPE = mstate_data_type ] +// [ , MSSPACE = mstate_data_size ] +// [ , MFINALFUNC = mffunc ] +// [ , MFINALFUNC_EXTRA ] +// [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] +// [ , MINITCOND = minitial_condition ] +// [ , SORTOP = sort_operator ] +// ) +fn create_aggregate_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.expect(AGGREGATE_KW); + path_name(p); + let at_old_syntax = p.at(L_PAREN) && p.nth_at(1, IDENT) && p.nth_at(2, EQ); + if !at_old_syntax { + aggregate_arg_list(p); + } + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_AGGREGATE_STMT) +} + +// CREATE CAST (source_type AS target_type) +// WITH FUNCTION function_name [ (argument_type [, ...]) ] +// [ AS ASSIGNMENT | AS IMPLICIT ] +// +// CREATE CAST (source_type AS target_type) +// WITHOUT FUNCTION +// [ AS ASSIGNMENT | AS IMPLICIT ] +// +// CREATE CAST (source_type AS target_type) +// WITH INOUT +// [ AS ASSIGNMENT | AS IMPLICIT ] +fn create_cast_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, CAST_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(CAST_KW); + source_type_as_target_type(p); + if p.eat(WITH_KW) { + if !p.eat(INOUT_KW) { + p.expect(FUNCTION_KW); + path_name_ref(p); + opt_param_list(p); + } + } else { + p.expect(WITHOUT_KW); + p.expect(FUNCTION_KW); + } + // [ AS ASSIGNMENT | AS IMPLICIT ] + if p.eat(AS_KW) { + if !p.eat(ASSIGNMENT_KW) && !p.eat(IMPLICIT_KW) { + p.error("expected ASSIGNMENT or IMPLICIT"); + } + } + m.complete(p, CREATE_CAST_STMT) +} + +// CREATE COLLATION [ IF NOT EXISTS ] name ( +// [ LOCALE = locale, ] +// [ LC_COLLATE = lc_collate, ] +// [ LC_CTYPE = lc_ctype, ] +// [ PROVIDER = provider, ] +// [ DETERMINISTIC = boolean, ] +// [ RULES = rules, ] +// [ VERSION = version ] +// ) +// CREATE COLLATION [ IF NOT EXISTS ] name FROM existing_collation +fn create_collation_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, COLLATION_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(COLLATION_KW); + opt_if_not_exists(p); + path_name(p); + if p.eat(FROM_KW) { + path_name_ref(p); + } else { + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + m.complete(p, CREATE_COLLATION_STMT) +} + +// CREATE [ DEFAULT ] CONVERSION name +// FOR source_encoding TO dest_encoding FROM function_name +fn create_conversion_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.eat(DEFAULT_KW); + p.expect(CONVERSION_KW); + path_name(p); + p.expect(FOR_KW); + string_literal(p); + p.expect(TO_KW); + string_literal(p); + p.expect(FROM_KW); + path_name(p); + m.complete(p, CREATE_CONVERSION_STMT) +} + +fn opt_option_value(p: &mut Parser<'_>) -> bool { + if opt_numeric_literal(p).is_none() + && opt_string_literal(p).is_none() + && !opt_bool_literal(p) + && !p.eat(DEFAULT_KW) + { + if p.at_ts(NON_RESERVED_WORD) { + p.bump_any(); + return true; + } else { + return false; + } + } + true +} + +fn opt_create_database_option(p: &mut Parser<'_>) -> bool { + p.eat(WITH_KW); + // option name + match p.current() { + OWNER_KW | TEMPLATE_KW | ENCODING_KW | IDENT | TABLESPACE_KW => { + p.bump_any(); + } + CONNECTION_KW => { + p.bump(CONNECTION_KW); + p.expect(LIMIT_KW); + } + _ => return false, + } + p.eat(EQ); + if !opt_option_value(p) { + p.error("expected create database option value"); + return false; + } + true +} + +// CREATE DATABASE name +// [ WITH ] [ OWNER [=] user_name ] +// [ TEMPLATE [=] template ] +// [ ENCODING [=] encoding ] +// [ STRATEGY [=] strategy ] +// [ LOCALE [=] locale ] +// [ LC_COLLATE [=] lc_collate ] +// [ LC_CTYPE [=] lc_ctype ] +// [ BUILTIN_LOCALE [=] builtin_locale ] +// [ ICU_LOCALE [=] icu_locale ] +// [ ICU_RULES [=] icu_rules ] +// [ LOCALE_PROVIDER [=] locale_provider ] +// [ COLLATION_VERSION = collation_version ] +// [ TABLESPACE [=] tablespace_name ] +// [ ALLOW_CONNECTIONS [=] allowconn ] +// [ CONNECTION LIMIT [=] connlimit ] +// [ IS_TEMPLATE [=] istemplate ] +// [ OID [=] oid ] +fn create_database_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, DATABASE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(DATABASE_KW); + name(p); + while !p.at(EOF) { + if !opt_create_database_option(p) { + break; + } + } + m.complete(p, CREATE_DATABASE_STMT) +} + +// CREATE DOMAIN name [ AS ] data_type +// [ COLLATE collation ] +// [ DEFAULT expression ] +// [ domain_constraint [ ... ] ] +// where domain_constraint is: +// [ CONSTRAINT constraint_name ] +// { NOT NULL | NULL | CHECK (expression) } +fn create_domain_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, DOMAIN_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(DOMAIN_KW); + name(p); + p.eat(AS_KW); + type_name(p); + opt_collate(p); + while !p.at(EOF) { + // TODO: add validation to limit the types of constraints allowed + if opt_column_constraint(p).is_none() { + break; + } + } + m.complete(p, CREATE_DOMAIN_STMT) +} + +// filter_variable IN (filter_value [, ... ]) +fn event_trigger_when(p: &mut Parser<'_>) { + name_ref(p); + p.expect(IN_KW); + p.expect(L_PAREN); + string_literal(p); + while !p.at(EOF) && p.eat(COMMA) { + string_literal(p); + } + p.expect(R_PAREN); +} + +// CREATE EVENT TRIGGER name +// ON event +// [ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ] +// EXECUTE { FUNCTION | PROCEDURE } function_name() +fn create_event_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, EVENT_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(EVENT_KW); + p.expect(TRIGGER_KW); + name(p); + p.expect(ON_KW); + p.expect(IDENT); + if p.eat(WHEN_KW) { + event_trigger_when(p); + while !p.at(EOF) && p.eat(AND_KW) { + event_trigger_when(p); + } + } + p.expect(EXECUTE_KW); + if !p.eat(FUNCTION_KW) && !p.eat(PROCEDURE_KW) { + p.error("expected FUNCTION or PROCEDURE"); + } + path_name_ref(p); + p.expect(L_PAREN); + p.expect(R_PAREN); + m.complete(p, CREATE_EVENT_TRIGGER_STMT) +} + +// CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ +// { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ] +// | table_constraint } +// [, ... ] +// ] ) +// [ INHERITS ( parent_table [, ... ] ) ] +// SERVER server_name +// [ OPTIONS ( option 'value' [, ... ] ) ] +// +// CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name +// PARTITION OF parent_table [ ( +// { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ] +// | table_constraint } +// [, ... ] +// ) ] +// { FOR VALUES partition_bound_spec | DEFAULT } +// SERVER server_name +// [ OPTIONS ( option 'value' [, ... ] ) ] +// +// where column_constraint is: +// [ CONSTRAINT constraint_name ] +// { NOT NULL | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) STORED } +// +// and table_constraint is: +// [ CONSTRAINT constraint_name ] +// CHECK ( expression ) [ NO INHERIT ] +// +// and partition_bound_spec is: +// IN ( partition_bound_expr [, ...] ) | +// FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) +// TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | +// WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) +fn create_foreign_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, FOREIGN_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(FOREIGN_KW); + p.expect(TABLE_KW); + opt_if_not_exists(p); + path_name(p); + if p.eat(PARTITION_KW) { + p.expect(OF_KW); + path_name_ref(p); + if p.eat(L_PAREN) { + if p.at_ts(TABLE_CONSTRAINT_FIRST) { + table_constraint(p); + } else { + name_ref(p); + if p.eat(WITH_KW) { + p.expect(OPTIONS_KW); + } + while !p.at(EOF) && opt_column_constraint(p).is_some() { + // pass + } + } + while !p.at(EOF) && p.eat(COMMA) { + if p.at_ts(TABLE_CONSTRAINT_FIRST) { + table_constraint(p); + } else { + name_ref(p); + if p.eat(WITH_KW) { + p.expect(OPTIONS_KW); + } + while !p.at(EOF) && opt_column_constraint(p).is_some() { + // pass + } + } + } + p.expect(R_PAREN); + } + partition_option(p); + } else { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if p.at_ts(TABLE_CONSTRAINT_FIRST) { + table_constraint(p); + } else { + name(p); + type_name(p); + opt_options_list(p); + opt_collate(p); + while !p.at(EOF) && opt_column_constraint(p).is_some() {} + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + opt_inherits_tables(p); + } + p.expect(SERVER_KW); + name_ref(p); + opt_options_list(p); + m.complete(p, CREATE_FOREIGN_TABLE_STMT) +} + +// CREATE FOREIGN DATA WRAPPER name +// [ HANDLER handler_function | NO HANDLER ] +// [ VALIDATOR validator_function | NO VALIDATOR ] +// [ OPTIONS ( option 'value' [, ... ] ) ] +fn create_foreign_data_wrapper_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, DATA_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(FOREIGN_KW); + p.bump(DATA_KW); + p.expect(WRAPPER_KW); + name(p); + while !p.at(EOF) { + if !opt_fdw_option(p) { + break; + } + } + opt_options_list(p); + m.complete(p, CREATE_FOREIGN_DATA_WRAPPER_STMT) +} + +fn opt_fdw_option(p: &mut Parser<'_>) -> bool { + match p.current() { + OPTIONS_KW => { + p.bump(OPTIONS_KW); + p.expect(L_PAREN); + alter_option(p); + while !p.at(EOF) && p.eat(COMMA) { + alter_option(p); + } + p.expect(R_PAREN); + true + } + HANDLER_KW | VALIDATOR_KW => { + p.bump_any(); + path_name_ref(p); + true + } + NO_KW => { + p.bump(NO_KW); + if !p.eat(HANDLER_KW) && !p.eat(VALIDATOR_KW) { + p.error("expected HANDLER or VALIDATOR") + } + true + } + _ => false, + } +} + +// CREATE GROUP name [ [ WITH ] option [ ... ] ] +// where option can be: +// SUPERUSER | NOSUPERUSER +// | CREATEDB | NOCREATEDB +// | CREATEROLE | NOCREATEROLE +// | INHERIT | NOINHERIT +// | LOGIN | NOLOGIN +// | REPLICATION | NOREPLICATION +// | BYPASSRLS | NOBYPASSRLS +// | CONNECTION LIMIT connlimit +// | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL +// | VALID UNTIL 'timestamp' +// | IN ROLE role_name [, ...] +// | IN GROUP role_name [, ...] +// | ROLE role_name [, ...] +// | ADMIN role_name [, ...] +// | USER role_name [, ...] +// | SYSID uid +fn create_group_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, GROUP_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(GROUP_KW); + name(p); + opt_role_option_list(p); + m.complete(p, CREATE_GROUP_STMT) +} + +// CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name +// [ HANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ] ] +fn create_language_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.eat(TRUSTED_KW); + p.eat(PROCEDURAL_KW); + p.eat(LANGUAGE_KW); + name(p); + if p.eat(HANDLER_KW) { + path_name_ref(p); + if p.eat(INLINE_KW) { + path_name_ref(p); + } + if p.eat(VALIDATOR_KW) { + path_name_ref(p); + } + } + m.complete(p, CREATE_LANGUAGE_STMT) +} + +// CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name +// [ ( column_name [, ...] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ TABLESPACE tablespace_name ] +// AS query +// [ WITH [ NO ] DATA ] +fn create_materialized_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, MATERIALIZED_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(MATERIALIZED_KW); + p.expect(VIEW_KW); + opt_if_not_exists(p); + path_name(p); + opt_column_list_with(p, ColumnDefKind::Name); + if p.eat(USING_KW) { + name_ref(p); + } + opt_with_params(p); + if p.eat(TABLESPACE_KW) { + name_ref(p); + } + p.expect(AS_KW); + // A SELECT, TABLE, or VALUES command. + let statement = stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ); + match statement.map(|x| x.kind()) { + Some(SELECT) => (), + Some(kind) => { + p.error(format!( + "expected SELECT, TABLE, or VALUES statement, got {:?}", + kind + )); + } + None => { + p.error("expected SELECT, TABLE, or VALUES statement"); + } + } + if p.eat(WITH_KW) { + p.eat(NO_KW); + p.expect(DATA_KW); + } + m.complete(p, CREATE_MATERIALIZED_VIEW_STMT) +} + +// CREATE OPERATOR name ( +// {FUNCTION|PROCEDURE} = function_name +// [, LEFTARG = left_type ] [, RIGHTARG = right_type ] +// [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ] +// [, RESTRICT = res_proc ] [, JOIN = join_proc ] +// [, HASHES ] [, MERGES ] +// ) +fn create_operator_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, OPERATOR_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(OPERATOR_KW); + operator(p); + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_OPERATOR_STMT) +} + +// CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type +// USING index_method [ FAMILY family_name ] AS +// { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ] [ FOR SEARCH | FOR ORDER BY sort_family_name ] +// | FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] ) +// | STORAGE storage_type +// } [, ... ] +fn create_operator_class_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, OPERATOR_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(OPERATOR_KW); + p.expect(CLASS_KW); + path_name(p); + p.eat(DEFAULT_KW); + p.expect(FOR_KW); + p.expect(TYPE_KW); + type_name(p); + p.expect(USING_KW); + name_ref(p); + if p.eat(FAMILY_KW) { + path_name_ref(p); + } + p.expect(AS_KW); + operator_class_option(p); + while !p.at(EOF) && p.eat(COMMA) { + operator_class_option(p); + } + m.complete(p, CREATE_OPERATOR_CLASS_STMT) +} + +// | OPERATOR strategy_number operator_name [ ( op_type, op_type ) ] [ FOR SEARCH | FOR ORDER BY sort_family_name ] +// | FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] ) +// | STORAGE storage_type +fn operator_class_option(p: &mut Parser<'_>) { + match p.current() { + OPERATOR_KW => { + p.bump(OPERATOR_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected number"); + } + operator(p); + if p.eat(L_PAREN) { + type_name(p); + p.expect(COMMA); + type_name(p); + p.expect(R_PAREN); + } + if p.eat(FOR_KW) { + if p.eat(ORDER_KW) { + p.expect(BY_KW); + path_name_ref(p); + } else if p.eat(SEARCH_KW) { + // pass + } else { + p.error("expected SEARCH or ORDER BY"); + } + } + } + FUNCTION_KW => { + p.bump(FUNCTION_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected number"); + } + if p.eat(L_PAREN) { + type_name(p); + if p.eat(COMMA) { + type_name(p); + } + p.expect(R_PAREN); + } + path_name_ref(p); + opt_param_list(p); + } + STORAGE_KW => { + p.bump(STORAGE_KW); + type_name(p); + } + _ => p.error("expected OPERATOR, FUNCTION, or STORAGE"), + } +} + +// | OPERATOR strategy_number ( op_type [ , op_type ] ) +// | FUNCTION support_number ( op_type [ , op_type ] ) +fn operator_drop_class_option(p: &mut Parser<'_>) { + match p.current() { + OPERATOR_KW | FUNCTION_KW => { + p.bump_any(); + if opt_numeric_literal(p).is_none() { + p.error("expected number"); + } + if p.eat(L_PAREN) { + type_name(p); + if p.eat(COMMA) { + type_name(p); + } + p.expect(R_PAREN); + } + } + _ => p.error("expected OPERATOR, or FUNCTION"), + } +} + +// CREATE OPERATOR FAMILY name USING index_method +fn create_operator_family_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, OPERATOR_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(OPERATOR_KW); + p.expect(FAMILY_KW); + path_name(p); + p.expect(USING_KW); + name_ref(p); + m.complete(p, CREATE_OPERATOR_FAMILY_STMT) +} + +// CREATE POLICY name ON table_name +// [ AS { PERMISSIVE | RESTRICTIVE } ] +// [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] +// [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ] +// [ USING ( using_expression ) ] +// [ WITH CHECK ( check_expression ) ] +fn create_policy_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, POLICY_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(POLICY_KW); + name(p); + p.expect(ON_KW); + path_name_ref(p); + if p.eat(AS_KW) { + p.expect(IDENT); + } + if p.eat(FOR_KW) { + let _ = p.eat(ALL_KW) + || p.eat(SELECT_KW) + || p.eat(INSERT_KW) + || p.eat(UPDATE_KW) + || p.eat(DELETE_KW); + } + if p.eat(TO_KW) { + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + if p.eat(USING_KW) { + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + if p.eat(WITH_KW) { + p.expect(CHECK_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + m.complete(p, CREATE_POLICY_STMT) +} + +// CREATE [ OR REPLACE ] PROCEDURE +// name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) +// { LANGUAGE lang_name +// | TRANSFORM { FOR TYPE type_name } [, ... ] +// | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER +// | SET configuration_parameter { TO value | = value | FROM CURRENT } +// | AS 'definition' +// | AS 'obj_file', 'link_symbol' +// | sql_body +// } ... +fn create_procedure_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.expect(PROCEDURE_KW); + path_name(p); + param_list(p); + func_option_list(p); + m.complete(p, CREATE_PROCEDURE_STMT) +} + +// [ TABLE ] [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [ WHERE ( expression ) ] +// CURRENT_SCHEMA +fn publication_object(p: &mut Parser<'_>) { + if p.eat(TABLES_KW) { + p.expect(IN_KW); + p.expect(SCHEMA_KW); + if !p.eat(CURRENT_SCHEMA_KW) { + name_ref(p); + } + while !p.at(EOF) && p.eat(COMMA) { + if !p.eat(CURRENT_SCHEMA_KW) { + name_ref(p); + } + } + } else if p.eat(CURRENT_SCHEMA_KW) { + return; + } else { + p.eat(TABLE_KW); + p.eat(ONLY_KW); + if p.eat(L_PAREN) { + path_name_ref(p); + p.expect(R_PAREN); + } else { + path_name_ref(p); + } + p.eat(STAR); + opt_column_list(p); + if p.eat(WHERE_KW) { + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + } +} + +// CREATE PUBLICATION name +// [ FOR ALL TABLES +// | FOR publication_object [, ... ] ] +// [ WITH ( publication_parameter [= value] [, ... ] ) ] +// +// where publication_object is one of: +// TABLE [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +fn create_publication_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, PUBLICATION_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(PUBLICATION_KW); + name(p); + if p.eat(FOR_KW) { + if p.eat(ALL_KW) { + p.expect(TABLES_KW); + } else { + publication_object(p); + while !p.at(EOF) && p.eat(COMMA) { + publication_object(p); + } + } + } + opt_with_params(p); + m.complete(p, CREATE_PUBLICATION_STMT) +} + +// CREATE ROLE name [ [ WITH ] option [ ... ] ] +// where option can be: +// SUPERUSER | NOSUPERUSER +// | CREATEDB | NOCREATEDB +// | CREATEROLE | NOCREATEROLE +// | INHERIT | NOINHERIT +// | LOGIN | NOLOGIN +// | REPLICATION | NOREPLICATION +// | BYPASSRLS | NOBYPASSRLS +// | CONNECTION LIMIT connlimit +// | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL +// | VALID UNTIL 'timestamp' +// | IN ROLE role_name [, ...] +// | ROLE role_name [, ...] +// | ADMIN role_name [, ...] +// | SYSID uid +fn create_role_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, ROLE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(ROLE_KW); + name(p); + opt_role_option_list(p); + m.complete(p, CREATE_ROLE_STMT) +} + +fn select_insert_delete_update_or_notify(p: &mut Parser<'_>) { + // statement + // Any SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement. + let statement = stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ); + if let Some(statement) = statement { + match statement.kind() { + SELECT | INSERT_STMT | UPDATE_STMT | DELETE_STMT | NOTIFY_STMT => (), + kind => { + p.error(format!( + "expected SELECT, INSERT, UPDATE, DELETE, NOTIFY, or VALUES statement, got {:?}", + kind + )); + } + } + } else { + p.error("expected SELECT, INSERT, UPDATE, DELETE, NOTIFY, or VALUES statement"); + } +} + +// CREATE [ OR REPLACE ] RULE name AS ON event +// TO table_name [ WHERE condition ] +// DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) } +// where event can be one of: +// SELECT | INSERT | UPDATE | DELETE +fn create_rule_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && matches!(p.nth(1), OR_KW | RULE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.expect(RULE_KW); + name(p); + p.expect(AS_KW); + p.expect(ON_KW); + if p.at(SELECT_KW) || p.at(INSERT_KW) || p.at(UPDATE_KW) || p.at(DELETE_KW) { + p.bump_any(); + } else { + p.error("expected SELECT, INSERT, UPDATE, or DELETE"); + } + p.expect(TO_KW); + path_name_ref(p); + opt_where_clause(p); + p.expect(DO_KW); + let _ = p.eat(ALSO_KW) || p.eat(INSTEAD_KW); + if p.eat(L_PAREN) { + // ( command ; command ... ) + while !p.at(EOF) && !p.at(R_PAREN) { + select_insert_delete_update_or_notify(p); + if !p.eat(SEMICOLON) { + break; + } + } + p.expect(R_PAREN); + } else if p.eat(NOTHING_KW) { + // pass + } else { + select_insert_delete_update_or_notify(p); + } + m.complete(p, CREATE_RULE_STMT) +} + +// CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name +// [ AS data_type ] +// [ INCREMENT [ BY ] increment ] +// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] +// [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ] +// [ OWNED BY { table_name.column_name | NONE } ] +fn create_sequence_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(CREATE_KW) && matches!(p.nth(1), TEMPORARY_KW | TEMP_KW | UNLOGGED_KW | SEQUENCE_KW) + ); + let m = p.start(); + p.bump(CREATE_KW); + let _ = opt_temp(p) || p.eat(UNLOGGED_KW); + p.expect(SEQUENCE_KW); + opt_if_not_exists(p); + path_name(p); + while !p.at(EOF) { + if !opt_sequence_option(p) { + break; + } + } + m.complete(p, CREATE_SEQUENCE_STMT) +} + +// CREATE SERVER [ IF NOT EXISTS ] server_name [ TYPE 'server_type' ] [ VERSION 'server_version' ] +// FOREIGN DATA WRAPPER fdw_name +// [ OPTIONS ( option 'value' [, ... ] ) ] +fn create_server_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, SERVER_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(SERVER_KW); + opt_if_not_exists(p); + name(p); + if p.eat(TYPE_KW) { + string_literal(p); + } + if p.eat(VERSION_KW) { + string_literal(p); + } + p.expect(FOREIGN_KW); + p.expect(DATA_KW); + p.expect(WRAPPER_KW); + name_ref(p); + opt_options_list(p); + m.complete(p, CREATE_SERVER_STMT) +} + +// CREATE STATISTICS [ [ IF NOT EXISTS ] statistics_name ] +// ON ( expression ) +// FROM table_name +// +// CREATE STATISTICS [ [ IF NOT EXISTS ] statistics_name ] +// [ ( statistics_kind [, ... ] ) ] +// ON { column_name | ( expression ) }, { column_name | ( expression ) } [, ...] +// FROM table_name +fn create_statistics_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, STATISTICS_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(STATISTICS_KW); + opt_if_not_exists(p); + if !p.at(L_PAREN) && !p.at(ON_KW) { + path_name(p); + } + if p.eat(L_PAREN) { + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + p.expect(R_PAREN); + } + if p.eat(ON_KW) { + if expr(p).is_none() { + p.error("expected expression"); + } + while !p.at(EOF) && p.eat(COMMA) { + if expr(p).is_none() { + p.error("expected expression"); + } + } + } + p.expect(FROM_KW); + path_name_ref(p); + m.complete(p, CREATE_STATISTICS_STMT) +} + +// CREATE SUBSCRIPTION subscription_name +// CONNECTION 'conninfo' +// PUBLICATION publication_name [, ...] +// [ WITH ( subscription_parameter [= value] [, ... ] ) ] +fn create_subscription_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, SUBSCRIPTION_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(SUBSCRIPTION_KW); + name(p); + p.expect(CONNECTION_KW); + string_literal(p); + p.expect(PUBLICATION_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_with_params(p); + m.complete(p, CREATE_SUBSCRIPTION_STMT) +} + +// CREATE TABLESPACE tablespace_name +// [ OWNER { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ] +// LOCATION 'directory' +// [ WITH ( tablespace_option = value [, ... ] ) ] +fn create_tablespace_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, TABLESPACE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TABLESPACE_KW); + name(p); + if p.eat(OWNER_KW) { + role(p); + } + p.expect(LOCATION_KW); + string_literal(p); + // TODO: we could have a validator to check these params + opt_with_params(p); + m.complete(p, CREATE_TABLESPACE_STMT) +} + +// CREATE TEXT SEARCH PARSER name ( +// START = start_function , +// GETTOKEN = gettoken_function , +// END = end_function , +// LEXTYPES = lextypes_function +// [, HEADLINE = headline_function ] +// ) +fn create_text_search_parser_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, TEXT_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(PARSER_KW); + path_name(p); + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_TEXT_SEARCH_PARSER_STMT) +} + +// CREATE TEXT SEARCH DICTIONARY name ( +// TEMPLATE = template +// [, option = value [, ... ]] +// ) +fn create_text_search_dict_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, TEXT_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(DICTIONARY_KW); + path_name(p); + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_TEXT_SEARCH_PARSER_STMT) +} + +// CREATE TEXT SEARCH CONFIGURATION name ( +// PARSER = parser_name | +// COPY = source_config +// ) +fn create_text_search_config_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, TEXT_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(CONFIGURATION_KW); + path_name(p); + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_TEXT_SEARCH_PARSER_STMT) +} + +// CREATE TEXT SEARCH TEMPLATE name ( +// [ INIT = init_function , ] +// LEXIZE = lexize_function +// ) +fn create_text_search_template_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, TEXT_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(TEMPLATE_KW); + path_name(p); + p.expect(L_PAREN); + // definition in postgres grammar + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, CREATE_TEXT_SEARCH_PARSER_STMT) +} + +// CREATE [ OR REPLACE ] TRANSFORM FOR type_name LANGUAGE lang_name ( +// FROM SQL WITH FUNCTION from_sql_function_name [ (argument_type [, ...]) ], +// TO SQL WITH FUNCTION to_sql_function_name [ (argument_type [, ...]) ] +// ); +fn create_transform_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.expect(TRANSFORM_KW); + p.expect(FOR_KW); + type_name(p); + p.expect(LANGUAGE_KW); + name_ref(p); + p.expect(L_PAREN); + p.expect(FROM_KW); + p.expect(SQL_KW); + p.expect(WITH_KW); + p.expect(FUNCTION_KW); + path_name_ref(p); + opt_param_list(p); + p.expect(COMMA); + p.expect(TO_KW); + p.expect(SQL_KW); + p.expect(WITH_KW); + p.expect(FUNCTION_KW); + path_name_ref(p); + opt_param_list(p); + p.expect(R_PAREN); + m.complete(p, CREATE_TRANSFORM_STMT) +} + +// CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } +// SERVER server_name +// [ OPTIONS ( option 'value' [, ... ] ) ] +fn create_user_mapping_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, USER_KW) && p.nth_at(2, MAPPING_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(USER_KW); + p.bump(MAPPING_KW); + opt_if_not_exists(p); + p.expect(FOR_KW); + // role | USER + if !p.eat(USER_KW) { + role(p); + } + p.eat(SERVER_KW); + // server_name + name_ref(p); + opt_options_list(p); + m.complete(p, CREATE_USER_MAPPING_STMT) +} + +const ROLE_OPTION_FIRST: TokenSet = TokenSet::new(&[ + WITH_KW, + INHERIT_KW, + CONNECTION_KW, + ENCRYPTED_KW, + PASSWORD_KW, + VALID_KW, + IN_KW, + ROLE_KW, + ADMIN_KW, + USER_KW, + SYSID_KW, + IDENT, +]); + +fn opt_role_option(p: &mut Parser<'_>) -> bool { + if !p.at_ts(ROLE_OPTION_FIRST) { + return false; + } + match p.current() { + // SUPERUSER + // NOSUPERUSER + // CREATEDB + // NOCREATEDB + // CREATEROLE + // NOCREATEROLE + // NOINHERIT + // LOGIN + // NOLOGIN + // REPLICATION + // NOREPLICATION + // BYPASSRLS + // NOBYPASSRLS + INHERIT_KW | IDENT => { + p.bump_any(); + } + CONNECTION_KW => { + p.bump(CONNECTION_KW); + p.expect(LIMIT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected number literal"); + } + } + ENCRYPTED_KW => { + p.bump(ENCRYPTED_KW); + p.expect(PASSWORD_KW); + string_literal(p); + } + PASSWORD_KW => { + p.bump(PASSWORD_KW); + if !p.eat(NULL_KW) { + string_literal(p); + } + } + VALID_KW => { + p.bump(VALID_KW); + p.expect(UNTIL_KW); + string_literal(p); + } + IN_KW => { + p.bump(IN_KW); + if p.at(GROUP_KW) || p.at(ROLE_KW) { + p.bump_any(); + } else { + p.error("expected GROUP or ROLE"); + } + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + ROLE_KW | ADMIN_KW | USER_KW => { + p.bump_any(); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + } + SYSID_KW => { + p.bump(SYSID_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected string literal"); + } + } + _ => { + p.err_and_bump("expected role option"); + return false; + } + } + true +} + +// CREATE USER name [ [ WITH ] option [ ... ] ] +// where option can be: +// SUPERUSER | NOSUPERUSER +// | CREATEDB | NOCREATEDB +// | CREATEROLE | NOCREATEROLE +// | INHERIT | NOINHERIT +// | LOGIN | NOLOGIN +// | REPLICATION | NOREPLICATION +// | BYPASSRLS | NOBYPASSRLS +// | CONNECTION LIMIT connlimit +// | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL +// | VALID UNTIL 'timestamp' +// | IN ROLE role_name [, ...] +// | IN GROUP role_name [, ...] +// | ROLE role_name [, ...] +// | ADMIN role_name [, ...] +// | USER role_name [, ...] +// | SYSID uid +fn create_user_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, USER_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(USER_KW); + name(p); + opt_role_option_list(p); + m.complete(p, CREATE_USER_STMT) +} + +fn opt_role_option_list(p: &mut Parser<'_>) { + if p.at_ts(ROLE_OPTION_FIRST) { + p.eat(WITH_KW); + opt_role_option(p); + while !p.at(EOF) && p.at_ts(ROLE_OPTION_FIRST) { + opt_role_option(p); + } + } +} + +// DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE| RESTRICT ] +fn drop_language_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && matches!(p.nth(1), LANGUAGE_KW | PROCEDURAL_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.eat(PROCEDURAL_KW); + p.expect(LANGUAGE_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_LANGUAGE_STMT) +} + +// DROP GROUP [ IF EXISTS ] name [, ...] +fn drop_group_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, GROUP_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(GROUP_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + m.complete(p, DROP_GROUP_STMT) +} + +// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +fn drop_function_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, FUNCTION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(FUNCTION_KW); + opt_if_exists(p); + path_name_ref(p); + opt_param_list(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + opt_param_list(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_FUNCTION_STMT) +} + +// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_foreign_data_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(DROP_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, DATA_KW) && p.nth_at(3, WRAPPER_KW) + ); + let m = p.start(); + p.bump(DROP_KW); + p.bump(FOREIGN_KW); + p.bump(DATA_KW); + p.bump(WRAPPER_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_FOREIGN_DATA_WRAPPER_STMT) +} + +// DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_foreign_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, TABLE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(FOREIGN_KW); + p.bump(TABLE_KW); + opt_if_exists(p); + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_FOREIGN_TABLE_STMT) +} + +// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_access_method_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, ACCESS_KW) && p.nth_at(2, METHOD_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(ACCESS_KW); + p.bump(METHOD_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_ACCESS_METHOD_STMT) +} + +fn aggregate(p: &mut Parser<'_>) { + let m = p.start(); + path_name_ref(p); + aggregate_arg_list(p); + m.complete(p, CALL_EXPR); +} + +// DROP AGGREGATE [ IF EXISTS ] name ( aggregate_signature ) [, ...] [ CASCADE | RESTRICT ] +// where aggregate_signature is: +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +fn drop_aggregate_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, AGGREGATE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(AGGREGATE_KW); + opt_if_exists(p); + aggregate(p); + while !p.at(EOF) && p.eat(COMMA) { + aggregate(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_AGGREGATE_STMT) +} + +fn source_type_as_target_type(p: &mut Parser<'_>) { + p.expect(L_PAREN); + type_name(p); + p.expect(AS_KW); + type_name(p); + p.expect(R_PAREN); +} + +// DROP CAST [ IF EXISTS ] (source_type AS target_type) [ CASCADE | RESTRICT ] +fn drop_cast_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, CAST_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(CAST_KW); + opt_if_exists(p); + source_type_as_target_type(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_CAST_STMT) +} + +// DROP COLLATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_collation_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, COLLATION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(COLLATION_KW); + opt_if_exists(p); + path_name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_COLLATION_STMT) +} + +// DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_conversion_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, CONVERSION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(CONVERSION_KW); + opt_if_exists(p); + path_name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_CONVERSION_STMT) +} + +// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_domain_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, DOMAIN_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(DOMAIN_KW); + opt_if_exists(p); + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_DOMAIN_STMT) +} + +// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_event_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, EVENT_KW) && p.nth_at(2, TRIGGER_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(EVENT_KW); + p.bump(TRIGGER_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_EVENT_TRIGGER_STMT) +} + +// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_extension_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, EXTENSION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(EXTENSION_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_EXTENSION_STMT) +} + +// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_materialized_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, MATERIALIZED_KW) && p.nth_at(2, VIEW_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(MATERIALIZED_KW); + p.bump(VIEW_KW); + opt_if_exists(p); + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_MATERIALIZED_VIEW_STMT) +} + +// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +fn drop_operator_family_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, OPERATOR_KW) && p.nth_at(2, FAMILY_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(OPERATOR_KW); + p.bump(FAMILY_KW); + opt_if_exists(p); + path_name_ref(p); + p.expect(USING_KW); + name_ref(p); // index_method + opt_cascade_or_restrict(p); + m.complete(p, DROP_OPERATOR_FAMILY_STMT) +} + +// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] +fn drop_operator_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, OPERATOR_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(OPERATOR_KW); + opt_if_exists(p); + operator_sig(p); + while !p.at(EOF) && p.eat(COMMA) { + operator_sig(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_OPERATOR_STMT) +} + +// name ( { left_type | NONE } , right_type ) +fn operator_sig(p: &mut Parser<'_>) { + operator(p); + p.expect(L_PAREN); + if !p.eat(NONE_KW) { + type_name(p); + } + p.expect(COMMA); + type_name(p); + p.expect(R_PAREN); +} + +// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +fn drop_operator_class_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, OPERATOR_KW) && p.nth_at(2, CLASS_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(OPERATOR_KW); + p.bump(CLASS_KW); + opt_if_exists(p); + path_name_ref(p); + p.expect(USING_KW); + name_ref(p); // index_method + opt_cascade_or_restrict(p); + m.complete(p, DROP_OPERATOR_CLASS_STMT) +} + +// DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] +fn drop_owned_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, OWNED_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(OWNED_KW); + p.expect(BY_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_OWNED_STMT) +} + +// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +fn drop_policy_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, POLICY_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(POLICY_KW); + opt_if_exists(p); + name_ref(p); + p.expect(ON_KW); + path_name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_POLICY_STMT) +} + +// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +fn drop_procedure_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, PROCEDURE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(PROCEDURE_KW); + opt_if_exists(p); + path_name_ref(p); + opt_param_list(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + opt_param_list(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_PROCEDURE_STMT) +} + +// DROP PUBLICATION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_publication_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, PUBLICATION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(PUBLICATION_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_PUBLICATION_STMT) +} + +// DROP ROLE [ IF EXISTS ] name [, ...] +fn drop_role_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, ROLE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(ROLE_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + m.complete(p, DROP_ROLE_STMT) +} + +// DROP ROUTINE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +fn drop_routine_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, ROUTINE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(ROUTINE_KW); + opt_if_exists(p); + path_name_ref(p); + opt_param_list(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + opt_param_list(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_ROUTINE_STMT) +} + +// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +fn drop_rule_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, RULE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(RULE_KW); + opt_if_exists(p); + name_ref(p); + p.expect(ON_KW); + path_name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_RULE_STMT) +} + +// DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_sequence_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, SEQUENCE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(SEQUENCE_KW); + opt_if_exists(p); + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_SEQUENCE_STMT) +} + +// DROP SERVER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_server_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, SERVER_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(SERVER_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_SERVER_STMT) +} + +// DROP STATISTICS [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_statistics_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, STATISTICS_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(STATISTICS_KW); + opt_if_exists(p); + path_name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_STATISTICS_STMT) +} + +// DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_subscription_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, SUBSCRIPTION_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(SUBSCRIPTION_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_SUBSCRIPTION_STMT) +} + +// [ CASCADE | RESTRICT ] +fn opt_cascade_or_restrict(p: &mut Parser<'_>) -> bool { + p.eat(CASCADE_KW) || p.eat(RESTRICT_KW) +} + +// DROP TABLESPACE [ IF EXISTS ] name +fn drop_tablespace_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, TABLESPACE_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TABLESPACE_KW); + opt_if_exists(p); + name_ref(p); + m.complete(p, DROP_TABLESPACE_STMT) +} + +// DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_text_search_parser_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(DROP_KW) && p.nth_at(1, TEXT_KW) && p.nth_at(2, SEARCH_KW) && p.nth_at(3, PARSER_KW) + ); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(PARSER_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TEXT_SEARCH_PARSER_STMT) +} + +// DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_text_search_config_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(DROP_KW) + && p.nth_at(1, TEXT_KW) + && p.nth_at(2, SEARCH_KW) + && p.nth_at(3, CONFIGURATION_KW) + ); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(CONFIGURATION_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TEXT_SEARCH_CONFIG_STMT) +} + +// DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_text_search_dict_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(DROP_KW) + && p.nth_at(1, TEXT_KW) + && p.nth_at(2, SEARCH_KW) + && p.nth_at(3, DICTIONARY_KW) + ); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(DICTIONARY_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TEXT_SEARCH_DICT_STMT) +} + +// DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ] +fn drop_text_search_template_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!( + p.at(DROP_KW) && p.nth_at(1, TEXT_KW) && p.nth_at(2, SEARCH_KW) && p.nth_at(3, TEMPLATE_KW) + ); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TEXT_KW); + p.bump(SEARCH_KW); + p.bump(TEMPLATE_KW); + opt_if_exists(p); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TEXT_SEARCH_TEMPLATE_STMT) +} + +// DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name [ CASCADE | RESTRICT ] +fn drop_transform_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, TRANSFORM_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TRANSFORM_KW); + opt_if_exists(p); + p.expect(FOR_KW); + type_name(p); + p.expect(LANGUAGE_KW); + name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TRANSFORM_STMT) +} + +// DROP USER [ IF EXISTS ] name [, ...] +fn drop_user_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, USER_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(USER_KW); + opt_if_exists(p); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + m.complete(p, DROP_USER_STMT) +} + +// DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name +fn drop_user_mapping_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, USER_KW) && p.nth_at(2, MAPPING_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(USER_KW); + p.bump(MAPPING_KW); + opt_if_exists(p); + p.expect(FOR_KW); + // role | USER + if !p.eat(USER_KW) { + role(p); + } + p.eat(SERVER_KW); + // server_name + name_ref(p); + m.complete(p, DROP_USER_MAPPING_STMT) +} + +// EXPLAIN [ANALYZE] [VERBOSE] query +// EXPLAIN [ ( option [, ...] ) ] statement +fn explain_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(EXPLAIN_KW)); + let m = p.start(); + p.bump(EXPLAIN_KW); + let pre_pg_9_syntax = p.eat(ANALYZE_KW) || p.eat(VERBOSE_KW); + if !pre_pg_9_syntax && p.eat(L_PAREN) { + explain_option(p); + while !p.at(EOF) && p.eat(COMMA) { + explain_option(p); + } + p.expect(R_PAREN); + } + // statement is SELECT, INSERT, UPDATE, DELETE, MERGE, VALUES, EXECUTE, DECLARE, CREATE TABLE AS, or CREATE MATERIALIZED VIEW AS + let statement = stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ); + if let Some(statement) = statement { + match statement.kind() { + SELECT + | INSERT_STMT + | UPDATE_STMT + | DELETE_STMT + | MERGE_STMT + | EXECUTE_STMT + | DECLARE_STMT + | CREATE_TABLE_AS_STMT + | CREATE_MATERIALIZED_VIEW_STMT + // TODO: we need a validation to check inside this + | PAREN_EXPR => (), + kind => { + p.error(format!( + "expected SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement, got {:?}", + kind + )); + } + } + } else { + p.error("expected SELECT, INSERT, UPDATE, DELETE, MERGE, VALUES, EXECUTE, DECLARE, CREATE TABLE AS, or CREATE MATERIALIZED VIEW AS"); + } + m.complete(p, EXPLAIN_STMT) +} + +// where option can be one of: +// ANALYZE [ boolean ] +// VERBOSE [ boolean ] +// COSTS [ boolean ] +// SETTINGS [ boolean ] +// GENERIC_PLAN [ boolean ] +// BUFFERS [ boolean ] +// SERIALIZE [ { NONE | TEXT | BINARY } ] +// WAL [ boolean ] +// TIMING [ boolean ] +// SUMMARY [ boolean ] +// MEMORY [ boolean ] +// FORMAT { TEXT | XML | JSON | YAML } +fn explain_option(p: &mut Parser<'_>) { + // TODO: we need a validation run for this since we're using IDENT + match p.current() { + ANALYZE_KW | VERBOSE_KW | IDENT | FORMAT_KW => { + p.bump_any(); + // WAL [ boolean ] + if opt_bool_literal(p) { + return; + } + // [ { NONE | TEXT | BINARY } ] + if p.eat(NONE_KW) || p.eat(TEXT_KW) || p.eat(BINARY_KW) { + return; + } + // { TEXT | XML | JSON | YAML } + if p.eat(TEXT_KW) || p.eat(XML_KW) || p.eat(JSON_KW) || p.eat(IDENT) { + return; + } + } + _ => p.error("expected option name"), + } +} + +// TODO: I think we want something like deliminated where we give it a FIRST +// token set so we can be robust to missing commas +fn one_or_more(p: &mut Parser<'_>, mut parse: impl FnMut(&mut Parser<'_>)) { + parse(p); + while !p.at(EOF) && p.eat(COMMA) { + parse(p); + } +} + +// [ OPTIONS ( option 'value' [, ... ] ) ] +fn opt_options_list(p: &mut Parser<'_>) { + // [ OPTIONS ( option 'value' [, ... ] ) ] + if p.eat(OPTIONS_KW) { + p.expect(L_PAREN); + one_or_more(p, |p| { + col_label(p); + string_literal(p); + }); + p.expect(R_PAREN); + } +} + +// IMPORT FOREIGN SCHEMA remote_schema +// [ { LIMIT TO | EXCEPT } ( table_name [, ...] ) ] +// FROM SERVER server_name +// INTO local_schema +// [ OPTIONS ( option 'value' [, ... ] ) ] +fn import_foreign_schema_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(IMPORT_KW) && p.nth_at(1, FOREIGN_KW)); + let m = p.start(); + p.bump(IMPORT_KW); + p.bump(FOREIGN_KW); + p.expect(SCHEMA_KW); + // remote_schema + name_ref(p); + // [ { LIMIT TO | EXCEPT } ( table_name [, ...] ) ] + if p.at(LIMIT_KW) || p.at(EXCEPT_KW) { + if p.eat(LIMIT_KW) { + p.expect(TO_KW); + } else { + p.bump(EXCEPT_KW); + } + // ( table_name [, ...] ) + p.expect(L_PAREN); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + p.expect(R_PAREN); + } + // FROM SERVER server_name + p.expect(FROM_KW); + p.expect(SERVER_KW); + name_ref(p); + // INTO local_schema + p.expect(INTO_KW); + name_ref(p); + opt_options_list(p); + m.complete(p, IMPORT_FOREIGN_SCHEMA) +} + +// LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ] +// where lockmode is one of: +// ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE +// | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE +fn lock_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(LOCK_KW)); + let m = p.start(); + p.bump(LOCK_KW); + // [ TABLE ] + p.eat(TABLE_KW); + // [ ONLY ] name [ * ] [, ...] + relation_name(p); + while !p.at(EOF) && p.eat(COMMA) { + relation_name(p); + } + // [ IN lockmode MODE ] + if p.eat(IN_KW) { + match (p.current(), p.nth(1)) { + // ACCESS SHARE | ROW SHARE + (ACCESS_KW | ROW_KW, SHARE_KW) => { + p.bump_any(); + p.bump(SHARE_KW); + } + // ACCESS EXCLUSIVE | ROW EXCLUSIVE + (ACCESS_KW | ROW_KW, EXCLUSIVE_KW) => { + p.bump_any(); + p.bump(EXCLUSIVE_KW); + } + // SHARE ROW EXCLUSIVE + (SHARE_KW, ROW_KW) => { + p.bump(SHARE_KW); + p.bump(ROW_KW); + p.expect(EXCLUSIVE_KW); + } + // SHARE UPDATE EXCLUSIVE + (SHARE_KW, UPDATE_KW) => { + p.bump(SHARE_KW); + p.bump(UPDATE_KW); + p.expect(EXCLUSIVE_KW); + } + // SHARE + (SHARE_KW, _) => { + p.bump(SHARE_KW); + } + // EXCLUSIVE + (EXCLUSIVE_KW, _) => { + p.bump(EXCLUSIVE_KW); + } + _ => p.error("expected lockmode"), + } + p.expect(MODE_KW); + } + // [ NOWAIT ] + p.eat(NOWAIT_KW); + m.complete(p, LOCK_STMT) +} + +// [ WITH with_query [, ...] ] +// MERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ] +// USING data_source ON join_condition +// when_clause [...] +// [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] +// +// where data_source is: +// { [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ] +// +// and when_clause is: +// { WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | +// WHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | +// WHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } } +// +// and merge_insert is: +// INSERT [( column_name [, ...] )] +// [ OVERRIDING { SYSTEM | USER } VALUE ] +// { VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES } +// +// and merge_update is: +// UPDATE SET { column_name = { expression | DEFAULT } | +// ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | +// ( column_name [, ...] ) = ( sub-SELECT ) +// } [, ...] +// +// and merge_delete is: +// DELETE +fn merge_stmt(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + assert!(p.at(MERGE_KW)); + let m = m.unwrap_or_else(|| p.start()); + p.bump(MERGE_KW); + p.expect(INTO_KW); + // [ ONLY ] target_table_name [ * ] + relation_name(p); + // [ [ AS ] target_alias ] + opt_as_alias(p); + // USING data_source ON join_condition + merge_using_clause(p); + merge_when_clause(p); + while !p.at(EOF) && p.at(WHEN_KW) { + merge_when_clause(p); + } + // [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] + opt_returning_clause(p); + m.complete(p, MERGE_STMT) +} + +// where data_source is: +// { [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ] +// +// and when_clause is: +// { WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | +// WHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | +// WHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } } +// +// and merge_insert is: +// INSERT [ ( column_name [, ...] ) ] +// [ OVERRIDING { SYSTEM | USER } VALUE ] +// { VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES } +// +// and merge_update is: +// UPDATE SET { column_name = { expression | DEFAULT } | +// ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | +// ( column_name [, ...] ) = ( sub-SELECT ) +// } [, ...] +// +// and merge_delete is: +// DELETE +fn merge_when_clause(p: &mut Parser<'_>) { + p.expect(WHEN_KW); + match p.current() { + MATCHED_KW => { + p.bump(MATCHED_KW); + } + NOT_KW => { + p.bump(NOT_KW); + p.expect(MATCHED_KW); + // TODO: need a validation to check these + // BY SOURCE | BY TARGET + if p.eat(BY_KW) { + let _ = p.eat(SOURCE_KW) || p.eat(TARGET_KW); + } + } + _ => p.error("expected MATCHED, or NOT MATCHED"), + } + // [ AND condition ] + if p.eat(AND_KW) { + if expr(p).is_none() { + p.error("expected condition"); + } + } + p.expect(THEN_KW); + // merge_update | merge_delete | merge_insert | DO NOTHING + match p.current() { + // merge_delete + DELETE_KW => { + p.bump(DELETE_KW); + } + // merge_update + UPDATE_KW => { + p.bump(UPDATE_KW); + set_clause(p); + } + // merge_insert + INSERT_KW => { + p.bump(INSERT_KW); + // [ ( column_name [, ...] ) ] + opt_column_list(p); + // [ OVERRIDING { SYSTEM | USER } VALUE ] + if p.eat(OVERRIDING_KW) { + if !p.eat(SYSTEM_KW) && !p.eat(USER_KW) { + p.error("expected SYSTEM or USER"); + } + p.expect(VALUE_KW); + } + // { VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES } + if p.at(VALUES_KW) { + values_clause(p, None); + } else if p.eat(DEFAULT_KW) { + p.expect(VALUES_KW); + } else { + p.error("expected VALUES or DEFAULT VALUES"); + } + } + // DO NOTHING + DO_KW => { + p.bump(DO_KW); + p.expect(NOTHING_KW); + } + _ => p.error("expected INSERT, UPDATE, DELETE, or DO NOTHING"), + } +} + +// REASSIGN OWNED BY { old_role | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] +// TO { new_role | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +fn reassign_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(REASSIGN_KW)); + let m = p.start(); + p.bump(REASSIGN_KW); + p.expect(OWNED_KW); + p.expect(BY_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + p.expect(TO_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + m.complete(p, REASSIGN_STMT) +} + +// REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name +// [ WITH [ NO ] DATA ] +fn refresh_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(REFRESH_KW)); + let m = p.start(); + p.bump(REFRESH_KW); + p.expect(MATERIALIZED_KW); + p.expect(VIEW_KW); + p.eat(CONCURRENTLY_KW); + path_name_ref(p); + if p.eat(WITH_KW) { + p.eat(NO_KW); + p.expect(DATA_KW); + } + m.complete(p, REFRESH_STMT) +} + +// GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +// [, ...] | ALL [ PRIVILEGES ] } +// ON { [ TABLE ] table_name [, ...] +// | ALL TABLES IN SCHEMA schema_name [, ...] } +// TO role_specification [, ...] [ WITH GRANT OPTION ] +// [ GRANTED BY role_specification ] +fn grant_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(GRANT_KW)); + let m = p.start(); + p.bump(GRANT_KW); + // TODO: we'll need a syntax validation for this since it uses specific + // idents not purely keywords + // TODO: we can cleanup this function a lot + // TODO: might be able to dedupe with revoke since it's mostly copy paste + + // { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) + // [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) } + // { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } + // [, ...] | ALL [ PRIVILEGES ] } + // ALL [ PRIVILEGES ] + if p.eat(ALL_KW) { + p.eat(PRIVILEGES_KW); + } else if !p.at(TO_KW) { + revoke_command(p); + while !p.at(EOF) && p.eat(COMMA) { + revoke_command(p); + } + } + // [ ( column_name [, ...] ) ] + opt_column_list(p); + // ON { [ TABLE ] table_name [, ...] + // | ALL TABLES IN SCHEMA schema_name [, ...] } + // ON { SEQUENCE sequence_name [, ...] + // | ALL SEQUENCES IN SCHEMA schema_name [, ...] } + // ON DATABASE database_name [, ...] + // ON TABLESPACE tablespace_name [, ...] + // ON { { FUNCTION | PROCEDURE | ROUTINE } function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] + // | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] } + // ON PARAMETER configuration_parameter [, ...] + if p.eat(ON_KW) { + if p.eat(ALL_KW) { + match p.current() { + TABLES_KW | SEQUENCES_KW | FUNCTIONS_KW | PROCEDURES_KW | ROUTINES_KW => { + p.bump_any(); + p.expect(IN_KW); + p.expect(SCHEMA_KW); + // schema_name [, ...] + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + _ => p.error("expected TABLE"), + } + } else { + match p.current() { + PARAMETER_KW => { + p.bump(PARAMETER_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + FUNCTION_KW | PROCEDURE_KW | ROUTINE_KW => { + p.bump_any(); + // function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] + path_name_ref(p); + opt_param_list(p); + while !p.at(EOF) && p.eat(COMMA) { + // function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] + path_name_ref(p); + opt_param_list(p); + } + } + // TYPE type_name [, ...] + TYPE_KW => { + p.bump(TYPE_KW); + type_name(p); + while !p.at(EOF) && p.eat(COMMA) { + type_name(p); + } + } + TABLE_KW | SEQUENCE_KW | DATABASE_KW | TABLESPACE_KW | SCHEMA_KW | LANGUAGE_KW + | DOMAIN_KW => { + p.bump_any(); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + FOREIGN_KW => { + p.bump(FOREIGN_KW); + if p.eat(DATA_KW) { + p.expect(WRAPPER_KW); + } else { + p.expect(SERVER_KW); + } + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + LARGE_KW => { + p.bump(LARGE_KW); + p.expect(OBJECT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected large_object_oid") + } + while !p.at(EOF) && p.eat(COMMA) { + if opt_numeric_literal(p).is_none() { + p.error("expected large_object_oid") + } + } + } + // table_name [, ...] + _ if p.at_ts(COL_LABEL_FIRST) => { + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + _ => (), + } + } + } + // TO role_specification [, ...] + p.expect(TO_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + // TODO: need more validation here + // [ WITH GRANT OPTION ] + // [ WITH { ADMIN | INHERIT | SET } { OPTION | TRUE | FALSE } ] + if p.eat(WITH_KW) { + match p.current() { + ADMIN_KW | INHERIT_KW | SET_KW => { + p.bump_any(); + if !(p.eat(OPTION_KW) || p.eat(TRUE_KW) || p.eat(FALSE_KW)) { + p.error("expected OPTION, TRUE, or FALSE") + } + } + GRANT_KW => { + p.bump(GRANT_KW); + p.expect(OPTION_KW); + } + _ => p.error("expected WITH GRANT OPTION or WITH ADMIN/INHERIT/SET OPTION/TRUE/FALSE"), + } + } + opt_granted_by(p); + m.complete(p, GRANT_STMT) +} + +// [ GRANTED BY role_specification ] +fn opt_granted_by(p: &mut Parser<'_>) { + if p.eat(GRANTED_KW) { + p.expect(BY_KW); + role(p); + } +} + +// REVOKE [ GRANT OPTION FOR ] +// { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +// [, ...] | ALL [ PRIVILEGES ] } +// ON { [ TABLE ] table_name [, ...] +// | ALL TABLES IN SCHEMA schema_name [, ...] } +// FROM role_specification [, ...] +// [ GRANTED BY role_specification ] +// [ CASCADE | RESTRICT ] +fn revoke_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(REVOKE_KW)); + let m = p.start(); + p.bump(REVOKE_KW); + // TODO: we'll need a syntax validation for this since it uses specific + // idents not purely keywords + // TODO: we can cleanup this function a lot + // [ { ADMIN | INHERIT | SET } OPTION FOR ] + // [ GRANT OPTION FOR ] + match p.current() { + ADMIN_KW | INHERIT_KW | GRANT_KW => { + p.bump_any(); + p.expect(OPTION_KW); + p.expect(FOR_KW); + } + SET_KW if p.nth_at(1, OPTION_KW) => { + p.bump(SET_KW); + p.bump(OPTION_KW); + p.expect(FOR_KW); + } + _ => (), + } + privileges(p); + // ON { [ TABLE ] table_name [, ...] + // | ALL TABLES IN SCHEMA schema_name [, ...] } + // ON { SEQUENCE sequence_name [, ...] + // | ALL SEQUENCES IN SCHEMA schema_name [, ...] } + // ON DATABASE database_name [, ...] + // ON TABLESPACE tablespace_name [, ...] + // ON { { FUNCTION | PROCEDURE | ROUTINE } function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] + // | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] } + // ON PARAMETER configuration_parameter [, ...] + if p.eat(ON_KW) { + if p.eat(ALL_KW) { + match p.current() { + TABLES_KW | SEQUENCES_KW | FUNCTIONS_KW | PROCEDURES_KW | ROUTINES_KW => { + p.bump_any(); + p.expect(IN_KW); + p.expect(SCHEMA_KW); + // schema_name [, ...] + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + _ => p.error("expected TABLE"), + } + } else { + match p.current() { + PARAMETER_KW => { + p.bump(PARAMETER_KW); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + FUNCTION_KW | PROCEDURE_KW | ROUTINE_KW => { + p.bump_any(); + path_name_ref(p); + opt_param_list(p); + while !p.at(EOF) && p.eat(COMMA) { + path_name_ref(p); + opt_param_list(p); + } + } + // TYPE type_name [, ...] + TYPE_KW => { + p.bump(TYPE_KW); + type_name(p); + while !p.at(EOF) && p.eat(COMMA) { + type_name(p); + } + } + TABLE_KW | SEQUENCE_KW | DATABASE_KW | TABLESPACE_KW | SCHEMA_KW | LANGUAGE_KW + | DOMAIN_KW => { + p.bump_any(); + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + FOREIGN_KW => { + p.bump(FOREIGN_KW); + if p.eat(DATA_KW) { + p.expect(WRAPPER_KW); + } else { + p.expect(SERVER_KW); + } + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + LARGE_KW => { + p.bump(LARGE_KW); + p.expect(OBJECT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected large_object_oid") + } + while !p.at(EOF) && p.eat(COMMA) { + if opt_numeric_literal(p).is_none() { + p.error("expected large_object_oid") + } + } + } + // table_name [, ...] + _ if p.at_ts(COL_LABEL_FIRST) => { + name_ref(p); + while !p.at(EOF) && p.eat(COMMA) { + name_ref(p); + } + } + _ => (), + } + } + } + // FROM role_specification [, ...] + p.expect(FROM_KW); + role(p); + while !p.at(EOF) && p.eat(COMMA) { + role(p); + } + // [ GRANTED BY role_specification ] + opt_granted_by(p); + opt_cascade_or_restrict(p); + m.complete(p, REVOKE_STMT) +} + +// { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) +// [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) } +// { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +// [, ...] | ALL [ PRIVILEGES ] } +fn privileges(p: &mut Parser<'_>) { + // ALL [ PRIVILEGES ] + if p.eat(ALL_KW) { + p.eat(PRIVILEGES_KW); + } else if !p.at(FROM_KW) { + revoke_command(p); + while !p.at(EOF) && p.eat(COMMA) { + revoke_command(p); + } + } + // [ ( column_name [, ...] ) ] + opt_column_list(p); +} + +const REVOKE_COMMAND_FIRST: TokenSet = TokenSet::new(&[ + SELECT_KW, + INSERT_KW, + UPDATE_KW, + DELETE_KW, + TRUNCATE_KW, + REFERENCES_KW, + TRIGGER_KW, + IDENT, + ALL_KW, + ALTER_KW, + CREATE_KW, + TEMPORARY_KW, + TEMP_KW, + EXECUTE_KW, +]); + +fn revoke_command(p: &mut Parser<'_>) { + if opt_role(p) { + return; + } + if p.eat(ALTER_KW) { + p.expect(SYSTEM_KW); + } else if p.at_ts(REVOKE_COMMAND_FIRST) { + p.bump_any(); + } else { + p.error(format!("expected command name, got {:?}", p.current())) + } +} + +// where role_specification can be: +// | [ GROUP ] role_name +// | PUBLIC +// | CURRENT_ROLE +// | CURRENT_USER +// | SESSION_USER +fn role(p: &mut Parser<'_>) { + if !opt_role(p) { + p.error(format!("expected role, got {:?}", p.current())) + } +} + +fn opt_role(p: &mut Parser<'_>) -> bool { + match p.current() { + GROUP_KW => { + p.bump(GROUP_KW); + if p.at_ts(NON_RESERVED_WORD) + || p.at(CURRENT_ROLE_KW) + || p.at(CURRENT_USER_KW) + || p.at(SESSION_USER_KW) + { + p.bump_any(); + } else { + p.error(format!("expected role_name, got {:?}", p.current())) + } + } + CURRENT_ROLE_KW | CURRENT_USER_KW | SESSION_USER_KW => { + p.bump_any(); + } + ALTER_KW => { + if !p.nth_at(1, SYSTEM_KW) { + p.bump_any(); + } else { + return false; + } + } + _ if p.at_ts(NON_RESERVED_WORD) => { + p.bump_any(); + } + _ => return false, + } + true +} + +// SECURITY LABEL [ FOR provider ] ON +// { +// TABLE object_name | +// COLUMN table_name.column_name | +// AGGREGATE aggregate_name ( aggregate_signature ) | +// DATABASE object_name | +// DOMAIN object_name | +// EVENT TRIGGER object_name | +// FOREIGN TABLE object_name | +// FUNCTION function_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// LARGE OBJECT large_object_oid | +// MATERIALIZED VIEW object_name | +// [ PROCEDURAL ] LANGUAGE object_name | +// PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// PUBLICATION object_name | +// ROLE object_name | +// ROUTINE routine_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | +// SCHEMA object_name | +// SEQUENCE object_name | +// SUBSCRIPTION object_name | +// TABLESPACE object_name | +// TYPE object_name | +// VIEW object_name +// } IS { string_literal | NULL } +// +// where aggregate_signature is: +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +fn security_label_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SECURITY_KW) && p.nth_at(1, LABEL_KW)); + let m = p.start(); + p.bump(SECURITY_KW); + p.bump(LABEL_KW); + if p.eat(FOR_KW) { + if p.at_ts(NON_RESERVED_WORD) { + p.bump_any(); + } else { + string_literal(p); + } + } + p.expect(ON_KW); + match p.current() { + TABLE_KW | COLUMN_KW | DATABASE_KW | DOMAIN_KW | PUBLICATION_KW | ROLE_KW | SCHEMA_KW + | SEQUENCE_KW | SUBSCRIPTION_KW | TABLESPACE_KW | TYPE_KW | VIEW_KW => { + p.bump_any(); + path_name(p); + } + EVENT_KW => { + p.bump(EVENT_KW); + p.expect(TRIGGER_KW); + path_name(p); + } + FOREIGN_KW => { + p.bump(FOREIGN_KW); + p.expect(TABLE_KW); + path_name(p); + } + // [ PROCEDURAL ] LANGUAGE object_name + PROCEDURAL_KW | LANGUAGE_KW => { + p.eat(PROCEDURAL_KW); + p.expect(LANGUAGE_KW); + path_name(p); + } + // LARGE OBJECT large_object_oid + LARGE_KW => { + p.bump(LARGE_KW); + p.expect(OBJECT_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected large_object_oid") + } + } + MATERIALIZED_KW => { + p.bump(MATERIALIZED_KW); + p.expect(VIEW_KW); + path_name(p); + } + FUNCTION_KW | PROCEDURE_KW | ROUTINE_KW => { + p.bump_any(); + path_name_ref(p); + opt_param_list(p); + } + AGGREGATE_KW => { + p.bump(AGGREGATE_KW); + path_name(p); + aggregate_arg_list(p); + } + _ => p.error("expected database object name"), + } + p.expect(IS_KW); + if !p.eat(NULL_KW) { + string_literal(p); + } + m.complete(p, SECURITY_LABEL_STMT) +} + +fn agg_args(p: &mut Parser<'_>) { + match p.current() { + STAR => { + p.bump(STAR); + } + // ORDER BY [ argmode ] [ argname ] argtype [ , ... ] + ORDER_KW => { + p.bump(ORDER_KW); + p.expect(BY_KW); + // TODO: generalize + param(p); + while !p.at(EOF) { + if p.eat(COMMA) { + param(p); + } else { + break; + } + } + } + _ => { + param(p); + while !p.at(EOF) { + if p.eat(COMMA) { + param(p); + } else { + break; + } + } + // ORDER BY [ argmode ] [ argname ] argtype [ , ... ] + if p.eat(ORDER_KW) { + p.expect(BY_KW); + // TODO: generalize + param(p); + while !p.at(EOF) { + if p.eat(COMMA) { + param(p); + } else { + break; + } + } + } + } + } +} + +fn aggregate_arg_list(p: &mut Parser<'_>) { + let m = p.start(); + p.expect(L_PAREN); + agg_args(p); + p.expect(R_PAREN); + m.complete(p, PARAM_LIST); +} + +// SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE } +fn set_constraints_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SET_KW) && p.nth_at(1, CONSTRAINTS_KW)); + let m = p.start(); + p.bump(SET_KW); + p.bump(CONSTRAINTS_KW); + if !p.eat(ALL_KW) { + // TODO: generalize + path_name(p); + while !p.at(EOF) { + if p.eat(COMMA) { + path_name(p); + } else { + break; + } + } + } + if !p.eat(DEFERRED_KW) && !p.eat(IMMEDIATE_KW) { + p.error("expected DEFERRED or IMMEDIATE"); + } + m.complete(p, SET_CONSTRAINTS_STMT) +} + +// SET [ SESSION | LOCAL ] ROLE role_name +// SET [ SESSION | LOCAL ] ROLE NONE +// RESET ROLE +fn set_role_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SET_KW) || p.at(RESET_KW)); + let m = p.start(); + if p.eat(RESET_KW) { + p.expect(ROLE_KW); + } else { + p.bump(SET_KW); + let _ = p.eat(SESSION_KW) || p.eat(LOCAL_KW); + p.expect(ROLE_KW); + if !p.eat(NONE_KW) && !p.eat(IDENT) && opt_string_literal(p).is_none() { + p.error("expected NONE or role_name"); + } + } + m.complete(p, SET_ROLE_STMT) +} + +// SET [ SESSION | LOCAL ] SESSION AUTHORIZATION user_name +// SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT +// RESET SESSION AUTHORIZATION +fn set_session_auth_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SET_KW) || p.at(RESET_KW)); + let m = p.start(); + if p.at(RESET_KW) { + p.bump(RESET_KW); + p.expect(SESSION_KW); + p.expect(AUTHORIZATION_KW); + } else { + p.bump(SET_KW); + p.eat(LOCAL_KW); + p.expect(SESSION_KW); + p.eat(SESSION_KW); + p.expect(AUTHORIZATION_KW); + if p.at_ts(NON_RESERVED_WORD) || p.at(DEFAULT_KW) { + p.bump_any(); + } else if opt_string_literal(p).is_none() { + p.error("expected user_name or DEFAULT"); + } + } + m.complete(p, SET_SESSION_AUTH_STMT) +} + +// SET TRANSACTION transaction_mode [, ...] +// SET TRANSACTION SNAPSHOT snapshot_id +// SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...] +// +// where transaction_mode is one of: +// ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } +// READ WRITE | READ ONLY +// [ NOT ] DEFERRABLE +fn set_transaction_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SET_KW)); + let m = p.start(); + p.bump(SET_KW); + if p.eat(SESSION_KW) { + p.expect(CHARACTERISTICS_KW); + p.expect(AS_KW); + p.expect(TRANSACTION_KW); + // TODO: generalize + // transaction_mode [, ...] + while !p.at(EOF) { + if !opt_transaction_mode(p) { + p.error("expected transaction mode"); + } + if !p.eat(COMMA) { + break; + } + } + } else { + p.expect(TRANSACTION_KW); + // [ SNAPSHOT snapshot_id ] + if p.eat(SNAPSHOT_KW) { + string_literal(p); + } else { + // TODO: generalize + // transaction_mode [, ...] + while !p.at(EOF) { + if !opt_transaction_mode(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + } + } + m.complete(p, SET_TRANSACTION_STMT) +} + +// VALUES ( expression [, ...] ) [, ...] +// [ ORDER BY sort_expression [ ASC | DESC | USING operator ] [, ...] ] +// [ LIMIT { count | ALL } ] +// [ OFFSET start [ ROW | ROWS ] ] +// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] +fn values_clause(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + let m = m.unwrap_or_else(|| p.start()); + p.bump(VALUES_KW); + // TODO: generalize this + while !p.at(EOF) { + if !p.at(L_PAREN) { + p.err_and_bump("expected L_PAREN"); + continue; + } + delimited( + p, + L_PAREN, + R_PAREN, + COMMA, + || "expected expression".to_string(), + EXPR_FIRST, + |p| expr(p).is_some(), + ); + if !p.eat(COMMA) { + if p.at(L_PAREN) { + p.error("expected COMMA"); + } else { + break; + } + } + } + opt_order_by_clause(p); + opt_limit_clause(p); + opt_offset_clause(p); + opt_fetch_clause(p); + m.complete(p, SELECT) +} + +// REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA } [ CONCURRENTLY ] name +// REINDEX [ ( option [, ...] ) ] { DATABASE | SYSTEM } [ CONCURRENTLY ] [ name ] +// +// where option can be one of: +// CONCURRENTLY [ boolean ] +// TABLESPACE new_tablespace +// VERBOSE [ boolean ] +fn reindex_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(REINDEX_KW)); + let m = p.start(); + p.bump(REINDEX_KW); + // TODO: we need to general this stuff + if p.eat(L_PAREN) { + let mut found = false; + while !p.at(EOF) { + match p.current() { + CONCURRENTLY_KW | VERBOSE_KW => { + p.bump_any(); + opt_bool_literal(p); + found = true; + } + TABLESPACE_KW => { + p.bump_any(); + name(p); + found = true; + } + kind => { + p.error(format!( + "expected CONCURRENTLY, TABLESPACE, or VERBOSE option, got {:?}", + kind + )); + break; + } + } + if !p.eat(COMMA) { + break; + } + } + if !found { + p.error("expected CONCURRENTLY, TABLESPACE, or VERBOSE option"); + } + p.expect(R_PAREN); + } + let name_required = match p.current() { + // { INDEX | TABLE | SCHEMA } + INDEX_KW | TABLE_KW | SCHEMA_KW => { + p.bump_any(); + true + } + // { DATABASE | SYSTEM } + DATABASE_KW | SYSTEM_KW => { + p.bump_any(); + false + } + _ => { + p.error("expected INDEX, TABLE, SCHEMA, DATABASE, or SYSTEM"); + true + } + }; + p.eat(CONCURRENTLY_KW); + if opt_name(p).is_none() && name_required { + p.error("expected name"); + } + m.complete(p, REINDEX_STMT) +} + +// DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, VIEW_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(VIEW_KW); + opt_if_exists(p); + // name [, ...] + // TODO: we need to generalize this pattern + path_name_ref(p); + if p.eat(COMMA) { + while !p.at(EOF) { + path_name_ref(p); + if !p.eat(COMMA) { + break; + } + } + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_VIEW_STMT) +} + +// CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW name [ ( column_name [, ...] ) ] +// [ WITH ( view_option_name [= view_option_value] [, ... ] ) ] +// AS query +// [ WITH [ CASCADED | LOCAL ] CHECK OPTION ] +fn create_view_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + opt_temp(p); + p.eat(RECURSIVE_KW); + p.expect(VIEW_KW); + path_name(p); + // [ ( column_name [, ...] ) ] + opt_column_list(p); + // [ WITH ( view_option_name [= view_option_value] [, ... ] ) ] + // TODO: this can be more specific + opt_with_params(p); + p.expect(AS_KW); + match stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ) { + Some(statement) => match statement.kind() { + SELECT | COMPOUND_SELECT => (), + kind => p.error(format!("expected SELECT, got {:?}", kind)), + }, + None => p.error("expected SELECT"), + } + // [ WITH [ CASCADED | LOCAL ] CHECK OPTION ] + if p.eat(WITH_KW) { + let _ = p.eat(CASCADED_KW) | p.eat(LOCAL_KW); + p.expect(CHECK_KW); + p.expect(OPTION_KW); + } + m.complete(p, CREATE_VIEW_STMT) +} + +// EXECUTE name [ ( parameter [, ...] ) ] +fn execute_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(EXECUTE_KW)); + let m = p.start(); + p.bump(EXECUTE_KW); + name_ref(p); + // [ ( parameter [, ...] ) ] + if p.at(L_PAREN) { + arg_list(p); + } + m.complete(p, EXECUTE_STMT) +} + +// PREPARE name [ ( data_type [, ...] ) ] AS statement +fn prepare_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(PREPARE_KW)); + let m = p.start(); + p.bump(PREPARE_KW); + name(p); + if p.eat(L_PAREN) { + while !p.at(EOF) { + type_name(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + p.expect(AS_KW); + // statement + // Any SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement. + let statement = stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ); + if let Some(statement) = statement { + match statement.kind() { + SELECT | INSERT_STMT | UPDATE_STMT | DELETE_STMT | MERGE_STMT => (), + kind => { + p.error(format!( + "expected SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement, got {:?}", + kind + )); + } + } + } else { + p.error("expected SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement"); + } + m.complete(p, PREPARE_STMT) +} + +// UNLISTEN { channel | * } +fn unlisten_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(UNLISTEN_KW)); + let m = p.start(); + p.bump(UNLISTEN_KW); + if !p.eat(STAR) { + name(p); + } + m.complete(p, UNLISTEN_STMT) +} + +// CHECKPOINT +fn checkpoint_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CHECKPOINT_KW)); + let m = p.start(); + p.bump(CHECKPOINT_KW); + m.complete(p, CHECKPOINT_STMT) +} + +// DEALLOCATE [ PREPARE ] { name | ALL } +fn deallocate_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DEALLOCATE_KW)); + let m = p.start(); + p.bump(DEALLOCATE_KW); + p.eat(PREPARE_KW); + if !p.eat(ALL_KW) { + name(p); + } + m.complete(p, DEALLOCATE_STMT) +} + +// LOAD string +fn load_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(LOAD_KW)); + let m = p.start(); + p.bump(LOAD_KW); + string_literal(p); + m.complete(p, LOAD_STMT) +} + +// LISTEN channel +fn listen_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(LISTEN_KW)); + let m = p.start(); + p.bump(LISTEN_KW); + name(p); + m.complete(p, LISTEN_STMT) +} + +// NOTIFY channel [ , payload ] +fn notify_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(NOTIFY_KW)); + let m = p.start(); + p.bump(NOTIFY_KW); + name(p); + // [ , payload ] + if p.eat(COMMA) { + string_literal(p); + } + m.complete(p, NOTIFY_STMT) +} + +fn reset_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(RESET_KW)); + let m = p.start(); + p.bump(RESET_KW); + if !p.eat(ALL_KW) { + name_ref(p); + } + m.complete(p, RESET_STMT) +} + +// DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP } +fn discard_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DISCARD_KW)); + let m = p.start(); + p.bump(DISCARD_KW); + let _ = p.eat(ALL_KW) || p.eat(PLANS_KW) || p.eat(SEQUENCES_KW) || opt_temp(p); + m.complete(p, DISCARD_STMT) +} + +fn opt_temp(p: &mut Parser<'_>) -> bool { + p.eat(TEMP_KW) || p.eat(TEMPORARY_KW) +} + +// DO [ LANGUAGE lang_name ] code +fn do_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DO_KW)); + let m = p.start(); + p.bump(DO_KW); + if p.eat(LANGUAGE_KW) { + if p.at_ts(NON_RESERVED_WORD) { + p.bump_any(); + } else { + string_literal(p); + } + } + string_literal(p); + m.complete(p, DO_STMT) +} + +// DECLARE name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] +// CURSOR [ { WITH | WITHOUT } HOLD ] FOR query +fn declare_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DECLARE_KW)); + let m = p.start(); + p.bump(DECLARE_KW); + name(p); + // [ BINARY ] + p.eat(BINARY_KW); + // [ ASENSITIVE | INSENSITIVE ] + let _ = p.eat(ASENSITIVE_KW) || p.eat(INSENSITIVE_KW); + // [ [ NO ] SCROLL ] + if p.eat(NO_KW) { + p.expect(SCROLL_KW); + } else { + p.eat(SCROLL_KW); + } + p.expect(CURSOR_KW); + // [ { WITH | WITHOUT } HOLD ] + if p.eat(WITH_KW) || p.eat(WITHOUT_KW) { + p.expect(HOLD_KW); + } + p.expect(FOR_KW); + // select_stmt | values_stmt + query(p); + m.complete(p, DECLARE_STMT) +} + +fn opt_direction(p: &mut Parser<'_>) -> bool { + match p.current() { + NEXT_KW | PRIOR_KW | FIRST_KW | LAST_KW | ALL_KW => { + p.bump_any(); + } + RELATIVE_KW | ABSOLUTE_KW => { + p.bump_any(); + if opt_numeric_literal(p).is_none() { + p.error("expected count") + } + } + FORWARD_KW | BACKWARD_KW => { + p.bump_any(); + if !p.eat(ALL_KW) { + let _ = opt_numeric_literal(p); + } + } + // count + _ if p.at_ts(NUMERIC_FIRST) => { + if opt_numeric_literal(p).is_none() { + p.error("expected count") + } + } + _ => return false, + } + true +} + +// MOVE [ direction ] [ FROM | IN ] cursor_name +// where direction can be one of: +// NEXT +// PRIOR +// FIRST +// LAST +// ABSOLUTE count +// RELATIVE count +// count +// ALL +// FORWARD +// FORWARD count +// FORWARD ALL +// BACKWARD +// BACKWARD count +// BACKWARD ALL +fn move_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(MOVE_KW)); + let m = p.start(); + p.bump(MOVE_KW); + opt_direction(p); + let _ = p.eat(FROM_KW) || p.eat(IN_KW); + // cursor_name + name(p); + m.complete(p, MOVE_STMT) +} + +// FETCH [ direction ] [ FROM | IN ] cursor_name +// where direction can be one of: +// NEXT +// PRIOR +// FIRST +// LAST +// ABSOLUTE count +// RELATIVE count +// count +// ALL +// FORWARD +// FORWARD count +// FORWARD ALL +// BACKWARD +// BACKWARD count +// BACKWARD ALL +fn fetch_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(FETCH_KW)); + let m = p.start(); + p.bump(FETCH_KW); + opt_direction(p); + let _ = p.eat(FROM_KW) || p.eat(IN_KW); + // cursor_name + name(p); + m.complete(p, FETCH_STMT) +} + +// CLOSE { name | ALL } +fn close_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CLOSE_KW)); + let m = p.start(); + p.bump(CLOSE_KW); + if !p.eat(ALL_KW) { + name(p); + } + m.complete(p, CLOSE_STMT) +} + +// TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ] +// [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ] +fn truncate_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(TRUNCATE_KW)); + let m = p.start(); + p.bump(TRUNCATE_KW); + p.eat(TABLE_KW); + while !p.at(EOF) { + relation_name(p); + if !p.eat(COMMA) { + break; + } + } + if p.eat(RESTART_KW) { + p.expect(IDENTITY_KW); + } + if p.eat(CONTINUE_KW) { + p.expect(IDENTITY_KW); + } + opt_cascade_or_restrict(p); + m.complete(p, TRUNCATE_STMT) +} + +// VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] +// +// where option can be one of: +// FULL [ boolean ] +// FREEZE [ boolean ] +// VERBOSE [ boolean ] +// ANALYZE [ boolean ] +// DISABLE_PAGE_SKIPPING [ boolean ] +// SKIP_LOCKED [ boolean ] +// INDEX_CLEANUP { AUTO | ON | OFF } +// PROCESS_MAIN [ boolean ] +// PROCESS_TOAST [ boolean ] +// TRUNCATE [ boolean ] +// PARALLEL integer +// SKIP_DATABASE_STATS [ boolean ] +// ONLY_DATABASE_STATS [ boolean ] +// BUFFER_USAGE_LIMIT size +// +// and table_and_columns is: +// table_name [ ( column_name [, ...] ) ] +// +// pre postgres 9 syntax: +// +// VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] +fn vacuum_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(VACUUM_KW)); + let m = p.start(); + p.bump(VACUUM_KW); + // [ FULL ] + p.eat(FULL_KW); + // [ FREEZE ] + p.eat(FREEZE_KW); + // [ VERBOSE ] + p.eat(VERBOSE_KW); + // [ ANALYZE ] + let _ = p.eat(ANALYZE_KW) || p.eat(ANALYSE_KW); + // [ ( option [, ...] ) ] + if p.at(L_PAREN) { + p.expect(L_PAREN); + while !p.at(EOF) { + vacuum_option(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + opt_relation_list(p); + m.complete(p, VACUUM_STMT) +} + +// [ table_and_columns [, ...] ] +// where table_and_coumns is: +// table_name [ ( column_name [, ...] ) ] +fn opt_relation_list(p: &mut Parser<'_>) { + while !p.at(EOF) { + if opt_path_name_ref(p).is_none() { + break; + } + opt_column_list(p); + if !p.eat(COMMA) { + break; + } + } +} + +// where option can be one of: +// FORMAT format_name +// FREEZE [ boolean ] +// DELIMITER 'delimiter_character' +// NULL 'null_string' +// DEFAULT 'default_string' +// HEADER [ boolean | MATCH ] +// QUOTE 'quote_character' +// ESCAPE 'escape_character' +// FORCE_QUOTE { ( column_name [, ...] ) | * } +// FORCE_NOT_NULL { ( column_name [, ...] ) | * } +// FORCE_NULL { ( column_name [, ...] ) | * } +// ON_ERROR error_action +// ENCODING 'encoding_name' +// LOG_VERBOSITY verbosity +fn vacuum_option(p: &mut Parser<'_>) { + // utility_option_name + if p.at_ts(NON_RESERVED_WORD) || p.at(ANALYZE_KW) || p.at(ANALYSE_KW) || p.at(FORMAT_KW) { + p.bump_any(); + } + if p.at_ts(NON_RESERVED_WORD) || p.at(ON_KW) { + p.bump_any(); + return; + } + // utility_option_arg + if opt_numeric_literal(p).is_some() { + return; + } + if opt_string_literal(p).is_some() { + return; + } + if opt_bool_literal(p) { + return; + } +} + +// copy_generic_opt_elem: +// ColLabel copy_generic_opt_arg +// +// copy_generic_opt_arg: +// opt_boolean_or_string +// | NumericOnly +// | '*' +// | DEFAULT +// | '(' copy_generic_opt_arg_list ')' +// | /* EMPTY */ +fn opt_copy_option(p: &mut Parser) -> bool { + col_label(p); + copy_option_arg(p); + true +} + +fn copy_option_arg(p: &mut Parser<'_>) { + match p.current() { + STAR | DEFAULT_KW => { + p.bump_any(); + } + L_PAREN => { + copy_option_list(p); + } + ON_KW => {} + _ => { + if p.at_ts(NON_RESERVED_WORD) { + p.bump_any(); + return; + } + if opt_numeric_literal(p).is_some() { + return; + } + if opt_string_literal(p).is_some() { + return; + } + if opt_bool_literal(p) { + return; + } + } + } +} + +fn copy_option_list(p: &mut Parser<'_>) { + p.expect(L_PAREN); + while !p.at(EOF) { + if !opt_copy_option(p) { + p.error("expected copy option"); + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); +} + +// COPY table_name [ ( column_name [, ...] ) ] +// FROM { 'filename' | PROGRAM 'command' | STDIN } +// [ [ WITH ] ( option [, ...] ) ] +// [ WHERE condition ] +// +// COPY { table_name [ ( column_name [, ...] ) ] | ( query ) } +// TO { 'filename' | PROGRAM 'command' | STDOUT } +// [ [ WITH ] ( option [, ...] ) ] +// +// where option can be one of: +// FORMAT format_name +// FREEZE [ boolean ] +// DELIMITER 'delimiter_character' +// NULL 'null_string' +// DEFAULT 'default_string' +// HEADER [ boolean | MATCH ] +// QUOTE 'quote_character' +// ESCAPE 'escape_character' +// FORCE_QUOTE { ( column_name [, ...] ) | * } +// FORCE_NOT_NULL { ( column_name [, ...] ) | * } +// FORCE_NULL { ( column_name [, ...] ) | * } +// ON_ERROR error_action +// ENCODING 'encoding_name' +// LOG_VERBOSITY verbosity +// +// # Pre postgres 9 syntax: +// +// COPY table_name [ ( column_name [, ...] ) ] +// FROM { 'filename' | STDIN } +// [ [ WITH ] +// [ BINARY ] +// [ DELIMITER [ AS ] 'delimiter_character' ] +// [ NULL [ AS ] 'null_string' ] +// [ CSV [ HEADER ] +// [ QUOTE [ AS ] 'quote_character' ] +// [ ESCAPE [ AS ] 'escape_character' ] +// [ FORCE NOT NULL column_name [, ...] ] ] ] +// +// COPY { table_name [ ( column_name [, ...] ) ] | ( query ) } +// TO { 'filename' | STDOUT } +// [ [ WITH ] +// [ BINARY ] +// [ DELIMITER [ AS ] 'delimiter_character' ] +// [ NULL [ AS ] 'null_string' ] +// [ CSV [ HEADER ] +// [ QUOTE [ AS ] 'quote_character' ] +// [ ESCAPE [ AS ] 'escape_character' ] +// [ FORCE QUOTE { column_name [, ...] | * } ] ] ] +// +// pre postgres 7.3 +// +// COPY [ BINARY ] table_name +// FROM { 'filename' | STDIN } +// [ [USING] DELIMITERS 'delimiter_character' ] +// [ WITH NULL AS 'null_string' ] +// +// COPY [ BINARY ] table_name +// TO { 'filename' | STDOUT } +// [ [USING] DELIMITERS 'delimiter_character' ] +// [ WITH NULL AS 'null_string' ] +fn copy_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(COPY_KW)); + let m = p.start(); + p.bump(COPY_KW); + if p.eat(L_PAREN) { + // query + query(p); + p.expect(R_PAREN); + } else { + // table_name + path_name(p); + // [ ( column_name [, ...] ) ] + opt_column_list(p); + } + if p.eat(FROM_KW) { + // STDIN + if p.eat(STDIN_KW) { + // PROGRAM 'command' + } else if p.eat(PROGRAM_KW) { + string_literal(p); + // 'filename' + } else { + string_literal(p); + } + } else if p.eat(TO_KW) { + if !p.eat(STDOUT_KW) { + p.eat(PROGRAM_KW); + string_literal(p); + } + } + // [ [ WITH ] ( option [, ...] ) ] + if p.eat(WITH_KW) || p.at(L_PAREN) { + copy_option_list(p); + } + opt_where_clause(p); + m.complete(p, COPY_STMT) +} + +// https://www.postgresql.org/docs/17/sql-call.html +// CALL name ( [ argument ] [, ...] ) +fn call_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CALL_KW)); + let m = p.start(); + p.bump(CALL_KW); + path_name(p); + if p.at(L_PAREN) { + arg_list(p); + } else { + p.error("expected L_PAREN"); + } + m.complete(p, CALL_STMT) +} + +// https://www.postgresql.org/docs/17/sql-createtrigger.html +// CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] } +// ON table_name +// [ FROM referenced_table_name ] +// [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] +// [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ] +// [ FOR [ EACH ] { ROW | STATEMENT } ] +// [ WHEN ( condition ) ] +// EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments ) +// +// where event can be one of: +// INSERT +// UPDATE [ OF column_name [, ... ] ] +// DELETE +// TRUNCATE +fn create_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + opt_or_replace(p); + p.eat(CONSTRAINT_KW); + // TRIGGER name + p.expect(TRIGGER_KW); + name(p); + // { BEFORE | AFTER | INSTEAD OF } + if p.eat(INSTEAD_KW) { + p.expect(OF_KW); + } else if !p.eat(BEFORE_KW) && !p.eat(AFTER_KW) { + p.error("expected BEFORE, AFTER, or INSTEAD OF"); + } + // { event [ OR ... ] } + while !p.at(EOF) { + if p.eat(UPDATE_KW) { + // [ OF column_name [, ... ] ] + if p.eat(OF_KW) { + while !p.at(EOF) { + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + } + } else if !(p.eat(INSERT_KW) || p.eat(DELETE_KW) || p.eat(TRUNCATE_KW)) { + p.error("expected INSERT, UPDATE, DELETE, or TRUNCATE"); + } + if !p.eat(OR_KW) { + break; + } + } + // ON table_name + p.expect(ON_KW); + path_name_ref(p); + // [ FROM referenced_table_name ] + if p.eat(FROM_KW) { + path_name_ref(p); + } + // [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] + opt_constraint_options(p); + // [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ] + if p.eat(REFERENCING_KW) { + while !p.at(EOF) { + if !opt_referencing_table(p) { + break; + } + } + } + // [ FOR [ EACH ] { ROW | STATEMENT } ] + if p.eat(FOR_KW) { + p.eat(EACH_KW); + if p.at(ROW_KW) || p.at(STATEMENT_KW) { + p.bump_any(); + } else { + p.error("expected ROW or STATEMENT"); + } + } + // [ WHEN ( condition ) ] + if p.eat(WHEN_KW) { + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expression"); + } + p.expect(R_PAREN); + } + // EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments ) + p.expect(EXECUTE_KW); + if !p.eat(FUNCTION_KW) && !p.eat(PROCEDURE_KW) { + p.error("expected FUNCTION or PROCEDURE"); + } + // function_name ( arguments ) + call_expr(p); + m.complete(p, CREATE_TRIGGER_STMT) +} + +fn call_expr(p: &mut Parser<'_>) { + match expr(p).map(|x| x.kind()) { + Some(CALL_EXPR) => (), + _ => p.error("expected call expression"), + } +} + +// { { OLD | NEW } TABLE [ AS ] transition_relation_name } +fn opt_referencing_table(p: &mut Parser<'_>) -> bool { + if !(p.at(OLD_KW) || p.at(NEW_KW)) { + return false; + } + p.bump_any(); + p.expect(TABLE_KW); + p.eat(AS_KW); + // transition_relation_name + name_ref(p); + true +} + +// https://www.postgresql.org/docs/17/sql-dropschema.html +// DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +fn drop_schema_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW) && p.nth_at(1, SCHEMA_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(SCHEMA_KW); + opt_if_exists(p); + let mut found_name = false; + while !p.at(EOF) { + name(p); + found_name = true; + if !p.eat(COMMA) { + break; + } + } + if !found_name { + p.error("expected name"); + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_SCHEMA_STMT) +} + +fn opt_schema_auth(p: &mut Parser<'_>) -> bool { + if p.eat(AUTHORIZATION_KW) { + if !(p.eat(CURRENT_ROLE_KW) || p.eat(CURRENT_USER_KW) || p.eat(SESSION_USER_KW)) { + if p.at_ts(UNRESERVED_KEYWORDS) || p.at(IDENT) { + p.bump_any(); + return true; + } else { + p.error("expected user_name"); + } + } else { + return true; + } + } + false +} + +// An SQL statement defining an object to be created within the schema. +// +// Currently, only CREATE TABLE, CREATE VIEW, CREATE INDEX, CREATE SEQUENCE, +// CREATE TRIGGER and GRANT are accepted as clauses within CREATE SCHEMA. Other +// kinds of objects may be created in separate commands after the schema is +// created. +fn opt_schema_elements(p: &mut Parser<'_>) { + while !p.at(EOF) { + match (p.current(), p.nth(1)) { + (CREATE_KW, TABLE_KW) => { + create_table_stmt(p); + } + (CREATE_KW, VIEW_KW) => { + create_view_stmt(p); + return; + } + (CREATE_KW, SEQUENCE_KW) => { + create_sequence_stmt(p); + return; + } + (CREATE_KW, TRIGGER_KW) => { + create_trigger_stmt(p); + return; + } + _ => return, + }; + } +} + +// CREATE SCHEMA schema_name [ AUTHORIZATION role_specification ] [ schema_element [ ... ] ] +// CREATE SCHEMA AUTHORIZATION role_specification [ schema_element [ ... ] ] +// CREATE SCHEMA IF NOT EXISTS schema_name [ AUTHORIZATION role_specification ] +// CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification +// where role_specification can be: +// | user_name +// | CURRENT_ROLE +// | CURRENT_USER +// | SESSION_USER +// https://www.postgresql.org/docs/17/sql-createschema.html +fn create_schema_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW) && p.nth_at(1, SCHEMA_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(SCHEMA_KW); + let if_not_exists = opt_if_not_exists(p).is_some(); + match (if_not_exists, opt_schema_auth(p)) { + // CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification + // ^ + (true, true) => m.complete(p, CREATE_SCHEMA_STMT), + // CREATE SCHEMA IF NOT EXISTS schema_name [ AUTHORIZATION role_specification ] + // ^ + (true, false) => { + name(p); + opt_schema_auth(p); + m.complete(p, CREATE_SCHEMA_STMT) + } + // CREATE SCHEMA AUTHORIZATION role_specification [ schema_element [ ... ] ] + // ^ + (false, true) => { + opt_schema_elements(p); + m.complete(p, CREATE_SCHEMA_STMT) + } + // CREATE SCHEMA schema_name [ AUTHORIZATION role_specification ] [ schema_element [ ... ] ] + // ^ + (false, false) => { + name(p); + opt_schema_auth(p); + opt_schema_elements(p); + m.complete(p, CREATE_SCHEMA_STMT) + } + } +} + +fn query(p: &mut Parser<'_>) { + // TODO: this needs to be more general + if !p.at_ts(SELECT_FIRST) || select_stmt(p, None).is_none() { + p.error("expected select stmt") + } +} + +// https://www.postgresql.org/docs/17/sql-insert.html +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ] +// [ OVERRIDING { SYSTEM | USER } VALUE ] +// { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query } +// [ ON CONFLICT [ conflict_target ] conflict_action ] +// [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] +// +// where conflict_target can be one of: +// ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ] +// ON CONSTRAINT constraint_name +// +// and conflict_action is one of: +// DO NOTHING +// DO UPDATE SET { column_name = { expression | DEFAULT } | +// ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | +// ( column_name [, ...] ) = ( sub-SELECT ) +// } [, ...] +// [ WHERE condition ] +fn insert_stmt(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + assert!(p.at(INSERT_KW)); + let m = m.unwrap_or_else(|| p.start()); + p.bump(INSERT_KW); + p.expect(INTO_KW); + path_name_ref(p); + // [ AS alias ] + if p.at(AS_KW) { + let m = p.start(); + p.bump(AS_KW); + name(p); + m.complete(p, ALIAS); + } + // [ ( column_name [, ...] ) ] + opt_column_list(p); + // [ OVERRIDING { SYSTEM | USER } VALUE ] + if p.eat(OVERRIDING_KW) { + let _ = p.eat(SYSTEM_KW) || p.expect(USER_KW); + p.expect(VALUE_KW); + } + // { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query } + if p.eat(DEFAULT_KW) { + p.expect(VALUES_KW); + } else if p.at(VALUES_KW) { + values_clause(p, None); + } else { + query(p); + } + // [ ON CONFLICT [ conflict_target ] conflict_action ] + if p.eat(ON_KW) { + p.expect(CONFLICT_KW); + // ON CONSTRAINT constraint_name + if p.eat(ON_KW) { + p.expect(CONSTRAINT_KW); + name_ref(p); + // ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ] + } else if p.eat(L_PAREN) { + while !p.at(EOF) { + // ( index_expression ) + if p.eat(L_PAREN) { + // TODO: more strict? + if expr(p).is_none() { + p.error("expected index_expression"); + } + // index_column_name + } + name_ref(p); + opt_collate(p); + // [ opclass ] + p.eat(IDENT); + // [, ...] + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + // [ WHERE index_predicate ] + // TODO: be more strict? + opt_where_clause(p); + } + // conflict_action is one of: + // DO NOTHING + // DO UPDATE SET { column_name = { expression | DEFAULT } | + // ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | + // ( column_name [, ...] ) = ( sub-SELECT ) + // } [, ...] + // [ WHERE condition ] + if p.eat(DO_KW) && !p.eat(NOTHING_KW) { + p.expect(UPDATE_KW); + set_clause(p); + opt_where_clause(p); + } + } + // [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] + opt_returning_clause(p); + m.complete(p, INSERT_STMT) +} + +// SET { column_name = { expression | DEFAULT } | +// ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | +// ( column_name [, ...] ) = ( sub-SELECT ) +// } [, ...] +fn set_clause(p: &mut Parser<'_>) { + p.expect(SET_KW); + // TODO: generalize + while !p.at(EOF) { + // ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | + // ( column_name [, ...] ) = ( sub-SELECT ) + if p.eat(L_PAREN) { + while !p.at(EOF) { + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + p.expect(EQ); + // [ ROW ] ( { expression | DEFAULT } [, ...] ) + // ( sub-SELECT ) + let found_row = p.eat(ROW_KW); + if p.eat(L_PAREN) { + // ( sub-SELECT ) + if p.at(SELECT_KW) && !found_row { + if select_stmt(p, None).is_none() { + p.error("expected sub-SELECT"); + } + } else { + // ( { expression | DEFAULT } [, ...] ) + while !p.at(EOF) { + if !p.eat(DEFAULT_KW) && expr(p).is_none() { + p.error("expected expression"); + } + if !p.eat(COMMA) { + break; + } + } + } + p.expect(R_PAREN); + } + // column_name = { expression | DEFAULT } + } else { + name_ref(p); + p.expect(EQ); + // { expression | DEFAULT } + if !p.eat(DEFAULT_KW) && expr(p).is_none() { + p.error("expected expression"); + } + } + if !p.eat(COMMA) { + break; + } + } +} + +fn opt_as_alias(p: &mut Parser<'_>) -> Option { + if p.at(AS_KW) { + let m = p.start(); + p.bump(AS_KW); + if p.at_ts(NAME_FIRST) { + name(p); + } else { + p.error("col id") + } + Some(m.complete(p, ALIAS)) + } else if p.at_ts(NAME_FIRST) { + let m = p.start(); + opt_name(p); + Some(m.complete(p, ALIAS)) + } else { + None + } +} + +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ] +// SET { column_name = { expression | DEFAULT } | +// ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | +// ( column_name [, ...] ) = ( sub-SELECT ) +// } [, ...] +// [ FROM from_item [, ...] ] +// [ WHERE condition | WHERE CURRENT OF cursor_name ] +// [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] +// +// https://www.postgresql.org/docs/17/sql-update.html +fn update_stmt(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + assert!(p.at(UPDATE_KW)); + let m = m.unwrap_or_else(|| p.start()); + p.bump(UPDATE_KW); + relation_name(p); + // postgres parser has the same setup, it assumes the alias can never be + // named `SET` + if !p.at(SET_KW) { + // [ [ AS ] alias ] + opt_as_alias(p); + } + set_clause(p); + // [ FROM from_item [, ...] ] + opt_from_clause(p); + // [ WHERE condition | WHERE CURRENT OF cursor_name ] + if p.at(WHERE_KW) { + if p.nth_at(1, CURRENT_KW) { + opt_where_current_of(p); + } else { + opt_where_clause(p); + } + } + // [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] + opt_returning_clause(p); + m.complete(p, UPDATE_STMT) +} + +fn with_stmt(p: &mut Parser<'_>, m: Option) -> Option { + let m = m.unwrap_or_else(|| p.start()); + // with aka cte + // [ WITH [ RECURSIVE ] with_query [, ...] ] + with_query_clause(p); + match p.current() { + DELETE_KW => Some(delete_stmt(p, Some(m))), + SELECT_KW | TABLE_KW => select_stmt(p, Some(m)), + INSERT_KW => Some(insert_stmt(p, Some(m))), + UPDATE_KW => Some(update_stmt(p, Some(m))), + MERGE_KW => Some(merge_stmt(p, Some(m))), + _ => { + m.abandon(p); + p.error(format!( + "expected DELETE, SELECT, TABLE, UPDATE, or MERGE, got: {:?}", + p.current() + )); + None + } + } +} + +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] +// [ USING from_item [, ...] ] +// [ WHERE condition | WHERE CURRENT OF cursor_name ] +// [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ] +fn delete_stmt(p: &mut Parser<'_>, m: Option) -> CompletedMarker { + assert!(p.at(DELETE_KW)); + let m = m.unwrap_or_else(|| p.start()); + p.bump(DELETE_KW); + p.expect(FROM_KW); + relation_name(p); + if p.eat(AS_KW) { + p.expect(IDENT); + } else { + p.eat(IDENT); + } + { + let m = p.start(); + if p.eat(USING_KW) { + while p.at_ts(FROM_ITEM_FIRST) { + if !opt_from_item(p) || !p.eat(COMMA) { + break; + } + } + m.complete(p, USING_CLAUSE); + } else { + m.abandon(p); + } + } + // [ WHERE condition | WHERE CURRENT OF cursor_name ] + if p.at(WHERE_KW) { + if p.nth_at(1, CURRENT_KW) { + opt_where_current_of(p); + } else { + opt_where_clause(p); + } + } + opt_returning_clause(p); + m.complete(p, DELETE_STMT) +} + +// WHERE CURRENT OF cursor_name +fn opt_where_current_of(p: &mut Parser<'_>) { + if p.eat(WHERE_KW) { + if p.eat(CURRENT_KW) { + p.expect(OF_KW); + p.expect(IDENT); + } + } +} + +fn opt_returning_clause(p: &mut Parser<'_>) { + if p.eat(RETURNING_KW) { + while !p.at(EOF) { + if !p.eat(STAR) { + if expr(p).is_none() { + p.error("expected output expression"); + } else if p.eat(AS_KW) { + p.expect(IDENT); + } else { + p.eat(IDENT); + } + } + if !p.eat(COMMA) { + break; + } + } + } +} + +// DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// https://www.postgresql.org/docs/17/sql-droptype.html +fn drop_type_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.bump(TYPE_KW); + opt_if_exists(p); + // name [, ...] + while !p.at(EOF) { + path_name_ref(p); + if !p.eat(COMMA) { + break; + } + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_TYPE_STMT) +} + +// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// https://www.postgresql.org/docs/17/sql-droptrigger.html +fn drop_trigger_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.expect(TRIGGER_KW); + opt_if_exists(p); + // name + path_name_ref(p); + p.expect(ON_KW); + // table_name + path_name_ref(p); + opt_cascade_or_restrict(p); + m.complete(p, DROP_TRIGGER_STMT) +} + +// DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// https://www.postgresql.org/docs/17/sql-dropindex.html +fn drop_index_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW)); + let m = p.start(); + // DROP INDEX + p.bump(DROP_KW); + p.expect(INDEX_KW); + p.eat(CONCURRENTLY_KW); + opt_if_exists(p); + // name [, ...] + while !p.at(EOF) { + path_name_ref(p); + if !p.eat(COMMA) { + break; + } + } + opt_cascade_or_restrict(p); + m.complete(p, DROP_INDEX_STMT) +} + +// DROP DATABASE [ IF EXISTS ] name [ [ WITH ] ( option [, ...] ) ] +// +// where option can be: +// +// FORCE +// https://www.postgresql.org/docs/17/sql-dropdatabase.html +fn drop_database_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(DROP_KW)); + let m = p.start(); + p.bump(DROP_KW); + p.expect(DATABASE_KW); + opt_if_exists(p); + name_ref(p); + // [ [ WITH ] ( option [, ...] ) ] + if p.at(L_PAREN) || p.eat(WITH_KW) { + p.expect(L_PAREN); + while !p.at(EOF) { + p.expect(FORCE_KW); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + m.complete(p, DROP_DATABASE_STMT) +} + +// CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ] +// ( +// { column_name | ( expression ) } +// [ COLLATE collation ] +// [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] +// [ ASC | DESC ] +// [ NULLS { FIRST | LAST } ] +// [, ...] +// ) +// [ INCLUDE ( column_name [, ...] ) ] +// [ NULLS [ NOT ] DISTINCT ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ TABLESPACE tablespace_name ] +// [ WHERE predicate ] +fn create_index_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.eat(UNIQUE_KW); + p.bump(INDEX_KW); + p.eat(CONCURRENTLY_KW); + // [ [ IF NOT EXISTS ] name ] + if opt_if_not_exists(p).is_some() { + name(p); + } else if p.at_ts(NAME_FIRST) { + opt_name(p); + } + // ON + p.expect(ON_KW); + relation_name(p); + // [ USING method ] + if p.eat(USING_KW) { + name_ref(p); + } + // ( + // { column_name | ( expression ) } + // [ COLLATE collation ] + // [ opclass ] + // [, ... ] + // ) + // ( + // { column_name | ( expression ) } + // [ COLLATE collation ] + // [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] + // [ ASC | DESC ] + // [ NULLS { FIRST | LAST } ] + // [, ...] + // ) + let param_list = p.start(); + partition_items(p, true); + param_list.complete(p, INDEX_PARAMS); + // [ INCLUDE ( column_name [, ...] ) ] + opt_include_columns(p); + // [ NULLS [ NOT ] DISTINCT ] + if p.eat(NULLS_KW) { + p.eat(NOT_KW); + p.expect(DISTINCT_KW); + } + // [ WITH ( storage_parameter [= value] [, ... ] ) ] + opt_with_params(p); + // [ TABLESPACE tablespace_name ] + if p.eat(TABLESPACE_KW) { + name_ref(p); + } + // [ WHERE predicate ] + opt_where_clause(p); + m.complete(p, CREATE_INDEX_STMT) +} + +// ( +// { column_name | ( expression ) } +// [ COLLATE collation ] +// [ opclass ] +// [, ... ] +// ) +// +// if we pass allow_extra_params: +// ( +// { column_name | ( expression ) } +// [ COLLATE collation ] +// [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] +// [ ASC | DESC ] +// [ NULLS { FIRST | LAST } ] +// [, ...] +// ) +fn partition_items(p: &mut Parser<'_>, allow_extra_params: bool) { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !part_elem(p, allow_extra_params) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); +} + +// [ argmode ] +fn opt_param_mode(p: &mut Parser<'_>) -> Option { + let m = p.start(); + let mode = match p.current() { + VARIADIC_KW => { + p.bump(VARIADIC_KW); + PARAM_VARIADIC + } + IN_KW => { + p.bump(IN_KW); + if p.eat(OUT_KW) { + PARAM_INOUT + } else { + PARAM_IN + } + } + OUT_KW => { + p.bump(OUT_KW); + PARAM_OUT + } + INOUT_KW => { + p.bump(INOUT_KW); + PARAM_INOUT + } + _ => { + m.abandon(p); + return None; + } + }; + Some(m.complete(p, mode)) +} + +fn opt_param_default(p: &mut Parser<'_>) -> Option { + if p.at(DEFAULT_KW) || p.at(EQ) { + let m = p.start(); + p.bump_any(); + if expr(p).is_none() { + p.error("expected default expr for func arg"); + } + Some(m.complete(p, PARAM_DEFAULT)) + } else { + None + } +} + +/// see: +const TYPE_FUNC_NAME_KEYWORDS: TokenSet = TokenSet::new(&[ + AUTHORIZATION_KW, + BINARY_KW, + COLLATION_KW, + CONCURRENTLY_KW, + CROSS_KW, + CURRENT_SCHEMA_KW, + FREEZE_KW, + FULL_KW, + ILIKE_KW, + INNER_KW, + IS_KW, + ISNULL_KW, + JOIN_KW, + LEFT_KW, + LIKE_KW, + NATURAL_KW, + NOTNULL_KW, + OUTER_KW, + OVERLAPS_KW, + RIGHT_KW, + SIMILAR_KW, + TABLESAMPLE_KW, + VERBOSE_KW, +]); + +fn opt_param_name(p: &mut Parser<'_>) -> bool { + if p.at(IDENT) || p.at_ts(UNRESERVED_KEYWORDS) || p.at_ts(TYPE_FUNC_NAME_KEYWORDS) { + p.bump_any(); + true + } else { + false + } +} + +// [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] +// +// func_arg: +// | mode name type +// | mode type +// | name mode type +// | name type +// | type +fn param(p: &mut Parser<'_>) { + let m = p.start(); + // [ argmode ] + let param_mode_seen = opt_param_mode(p).is_some(); + let name_or_type = p.start(); + // [ argname ] + let maybe_name = opt_param_name(p); + if maybe_name { + // Could have either parsed a name or a type, we know if it it's a type if: + let at_type = match p.current() { + // foo.bar%type + // ^ + DOT => true, + // foo(8) + // ^ + L_PAREN => true, + // float8 order by + // ^ + ORDER_KW => true, + // we're at the end of the param, must be a type + R_PAREN | EQ | DEFAULT_KW | COMMA => true, + _ => false, + }; + if at_type { + name_or_type.complete(p, PATH_TYPE); + } else { + name_or_type.complete(p, NAME); + if !param_mode_seen { + opt_param_mode(p); + } + // argtype + type_name(p); + } + } else { + name_or_type.abandon(p); + // argtype + type_name(p); + } + opt_param_default(p); + m.complete(p, PARAM); +} + +// { LANGUAGE lang_name +// | TRANSFORM { FOR TYPE type_name } [, ... ] +// | WINDOW +// | { IMMUTABLE | STABLE | VOLATILE } +// | [ NOT ] LEAKPROOF +// | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } +// | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER } +// | PARALLEL { UNSAFE | RESTRICTED | SAFE } +// | COST execution_cost +// | ROWS result_rows +// | SUPPORT support_function +// | SET configuration_parameter { TO value | = value | FROM CURRENT } +// | AS 'definition' +// | AS 'obj_file', 'link_symbol' +// | sql_body +// } ... +// +// sql_body: +// | RETURN expression +// | BEGIN ATOMIC +// statement; +// statement; +// ... +// statement; +// END +fn opt_function_option(p: &mut Parser<'_>) -> bool { + let m = p.start(); + let kind = match p.current() { + // LANGUAGE lang_name + LANGUAGE_KW => { + p.bump(LANGUAGE_KW); + // string for language is deprecated but let's support it + if opt_string_literal(p).is_none() { + if p.at_ts(UNRESERVED_KEYWORDS) || p.at(IDENT) { + p.bump_any(); + } else { + p.error(format!("expected a language name, got {:?}", p.current())); + } + } + LANGUAGE_FUNC_OPTION + } + // TRANSFORM { FOR TYPE type_name } [, ... ] + TRANSFORM_KW => { + p.bump(TRANSFORM_KW); + while !p.at(EOF) { + p.expect(FOR_KW); + p.expect(TYPE_KW); + type_name(p); + if !p.eat(COMMA) { + break; + } + } + TRANSFORM_FUNC_OPTION + } + // WINDOW + WINDOW_KW => { + p.bump(WINDOW_KW); + WINDOW_FUNC_OPTION + } + // { IMMUTABLE | STABLE | VOLATILE } + IMMUTABLE_KW | STABLE_KW | VOLATILE_KW => { + p.bump_any(); + VOLATILITY_FUNC_OPTION + } + // [ NOT ] LEAKPROOF + NOT_KW | LEAKPROOF_KW => { + p.eat(NOT_KW); + p.expect(LEAKPROOF_KW); + LEAKPROOF_FUNC_OPTION + } + // RESET configuration_parameter + // RESET ALL + RESET_KW => { + p.bump(RESET_KW); + if !p.eat(ALL_KW) { + path_name_ref(p); + } + RESET_FUNC_OPTION + } + // { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } + CALLED_KW | RETURNS_KW | STRICT_KW => { + if p.eat(CALLED_KW) { + p.expect(ON_KW); + p.expect(NULL_KW); + p.expect(INPUT_KW); + } else if p.eat(RETURNS_KW) { + p.expect(NULL_KW); + p.expect(ON_KW); + p.expect(NULL_KW); + p.expect(INPUT_KW); + } else { + p.expect(STRICT_KW); + } + STRICT_FUNC_OPTION + } + // { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER } + EXTERNAL_KW | SECURITY_KW => { + p.eat(EXTERNAL_KW); + p.expect(SECURITY_KW); + let _ = p.eat(INVOKER_KW) || p.expect(DEFINER_KW); + SECURITY_FUNC_OPTION + } + // PARALLEL { UNSAFE | RESTRICTED | SAFE } + PARALLEL_KW => { + p.bump(PARALLEL_KW); + p.expect(IDENT); + PARALLEL_FUNC_OPTION + } + // COST execution_cost + COST_KW => { + p.bump(COST_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric value for execution_cost"); + } + COST_FUNC_OPTION + } + // ROWS result_rows + ROWS_KW => { + p.bump(ROWS_KW); + if opt_numeric_literal(p).is_none() { + p.error("expected numeric value for result_rows"); + } + ROWS_FUNC_OPTION + } + // SUPPORT support_function + SUPPORT_KW => { + p.bump(SUPPORT_KW); + path_name_ref(p); + SUPPORT_FUNC_OPTION + } + // SET configuration_parameter { TO value | = value | FROM CURRENT } + SET_KW => { + set_configuration_param(p); + SET_FUNC_OPTION + } + // AS 'definition' + // AS 'obj_file', 'link_symbol' + AS_KW => { + p.bump(AS_KW); + string_literal(p); + if p.eat(COMMA) { + string_literal(p); + } + AS_FUNC_OPTION + } + // RETURN expression + RETURN_KW => { + p.bump(RETURN_KW); + if expr(p).is_none() { + p.error("expected expression for return"); + } + RETURN_FUNC_OPTION + } + // BEGIN ATOMIC + // statement; + // statement; + // ... + // statement; + // END + BEGIN_KW => { + p.bump(BEGIN_KW); + p.expect(ATOMIC_KW); + while !p.at(EOF) && !p.at(END_KW) { + if p.eat(SEMICOLON) { + continue; + } + stmt( + p, + &StmtRestrictions { + begin_end_allowed: false, + }, + ); + if p.at(END_KW) { + p.expect(SEMICOLON); + } + } + p.expect(END_KW); + BEGIN_FUNC_OPTION + } + _ => { + m.abandon(p); + return false; + } + }; + m.complete(p, kind); + true +} + +// SET configuration_parameter { TO | = } { value | DEFAULT } +// SET configuration_parameter FROM CURRENT +fn set_configuration_param(p: &mut Parser<'_>) { + assert!(p.at(SET_KW)); + p.bump(SET_KW); + // configuration_parameter + path_name_ref(p); + // { TO value | = value | FROM CURRENT } + if p.eat(FROM_KW) { + p.expect(CURRENT_KW); + } else if (p.eat(TO_KW) || p.expect(EQ)) && !config_value(p) { + p.error(format!("expected config value, got {:?}", p.current())); + } +} + +fn opt_ret_type(p: &mut Parser<'_>) { + // [ RETURNS rettype + // | RETURNS TABLE ( column_name column_type [, ...] ) ] + let m = p.start(); + if p.eat(RETURNS_KW) { + if p.eat(TABLE_KW) { + p.expect(L_PAREN); + while !p.at(EOF) { + // column_name + name_ref(p); + // column_type + type_name(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } else { + p.eat(SETOF_KW); + type_name(p); + } + m.complete(p, RET_TYPE); + } else { + m.abandon(p); + } +} + +fn func_option_list(p: &mut Parser<'_>) { + let m = p.start(); + let mut seen_func_option = false; + while !p.at(EOF) { + if !opt_function_option(p) { + if !seen_func_option { + p.error("expected function option"); + } + break; + } else { + seen_func_option = true + } + } + if !seen_func_option { + m.abandon(p); + return; + } + m.complete(p, FUNC_OPTION_LIST); +} + +// [ ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) ] +fn opt_param_list(p: &mut Parser<'_>) -> bool { + if !p.at(L_PAREN) { + return false; + } + param_list(p); + true +} + +fn param_list(p: &mut Parser<'_>) { + let m = p.start(); + // ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) + if !p.expect(L_PAREN) { + m.abandon(p); + return; + } + while !p.at(EOF) && !p.at(R_PAREN) { + param(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + m.complete(p, PARAM_LIST); +} + +// CREATE [ OR REPLACE ] FUNCTION +// name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) +// [ RETURNS rettype +// | RETURNS TABLE ( column_name column_type [, ...] ) ] +// { LANGUAGE lang_name +// | TRANSFORM { FOR TYPE type_name } [, ... ] +// | WINDOW +// | { IMMUTABLE | STABLE | VOLATILE } +// | [ NOT ] LEAKPROOF +// | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } +// | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER } +// | PARALLEL { UNSAFE | RESTRICTED | SAFE } +// | COST execution_cost +// | ROWS result_rows +// | SUPPORT support_function +// | SET configuration_parameter { TO value | = value | FROM CURRENT } +// | AS 'definition' +// | AS 'obj_file', 'link_symbol' +// | sql_body +// } ... +// https://www.postgresql.org/docs/17/sql-createfunction.html +fn create_function_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + // CREATE + p.bump(CREATE_KW); + opt_or_replace(p); + p.expect(FUNCTION_KW); + // name + path_name(p); + param_list(p); + opt_ret_type(p); + func_option_list(p); + m.complete(p, CREATE_FUNCTION_STMT) +} + +fn opt_or_replace(p: &mut Parser<'_>) -> Option { + // [ OR REPLACE ] + if p.at(OR_KW) { + let m = p.start(); + p.expect(OR_KW); + p.expect(REPLACE_KW); + Some(m.complete(p, OR_REPLACE)) + } else { + None + } +} + +// CREATE TYPE name AS +// ( [ attribute_name data_type [ COLLATE collation ] [, ... ] ] ) +// +// CREATE TYPE name AS ENUM +// ( [ 'label' [, ... ] ] ) +// +// CREATE TYPE name AS RANGE ( +// SUBTYPE = subtype +// [ , SUBTYPE_OPCLASS = subtype_operator_class ] +// [ , COLLATION = collation ] +// [ , CANONICAL = canonical_function ] +// [ , SUBTYPE_DIFF = subtype_diff_function ] +// [ , MULTIRANGE_TYPE_NAME = multirange_type_name ] +// ) +// +// CREATE TYPE name ( +// INPUT = input_function, +// OUTPUT = output_function +// [ , RECEIVE = receive_function ] +// [ , SEND = send_function ] +// [ , TYPMOD_IN = type_modifier_input_function ] +// [ , TYPMOD_OUT = type_modifier_output_function ] +// [ , ANALYZE = analyze_function ] +// [ , SUBSCRIPT = subscript_function ] +// [ , INTERNALLENGTH = { internallength | VARIABLE } ] +// [ , PASSEDBYVALUE ] +// [ , ALIGNMENT = alignment ] +// [ , STORAGE = storage ] +// [ , LIKE = like_type ] +// [ , CATEGORY = category ] +// [ , PREFERRED = preferred ] +// [ , DEFAULT = default ] +// [ , ELEMENT = element ] +// [ , DELIMITER = delimiter ] +// [ , COLLATABLE = collatable ] +// ) +// +// CREATE TYPE name +// https://www.postgresql.org/docs/17/sql-createtype.html +fn create_type_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(TYPE_KW); + path_name(p); + if p.eat(AS_KW) { + // AS ENUM + if p.eat(ENUM_KW) { + p.expect(L_PAREN); + while !p.at(EOF) { + if opt_string_literal(p).is_none() { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + // AS RANGE + } else if p.eat(RANGE_KW) { + p.expect(L_PAREN); + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Required) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + // AS + } else { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + // attribute_name + name_ref(p); + // data_type + type_name(p); + opt_collate(p); + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + } else if p.eat(L_PAREN) { + while !p.at(EOF) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + } + m.complete(p, CREATE_TYPE_STMT) +} + +// CREATE EXTENSION [ IF NOT EXISTS ] extension_name +// [ WITH ] [ SCHEMA schema_name ] +// [ VERSION version ] +// [ CASCADE ] +// https://www.postgresql.org/docs/17/sql-createextension.html +fn create_extension_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(CREATE_KW)); + let m = p.start(); + p.bump(CREATE_KW); + p.bump(EXTENSION_KW); + opt_if_not_exists(p); + // extension_name + name(p); + p.eat(WITH_KW); + if p.eat(SCHEMA_KW) { + p.expect(IDENT); + } + if p.eat(VERSION_KW) { + if opt_string_literal(p).is_none() && !p.eat(IDENT) { + p.error("expected string literal or IDENT"); + } + } + p.eat(CASCADE_KW); + m.complete(p, CREATE_EXTENSION_STMT) +} + +// { value | 'value' | DEFAULT } +// where value can be specified as string constants, identifiers, numbers, or +// comma-separated lists of these +fn config_value(p: &mut Parser<'_>) -> bool { + if p.eat(DEFAULT_KW) { + return true; + } + let mut found_value = false; + // ident, number or comma separated list of strings, idents, numbers + while !p.at(EOF) { + if opt_string_literal(p).is_none() + && opt_numeric_literal(p).is_none() + && !p.eat(IDENT) + && !opt_bool_literal(p) + { + if p.at_ts(BARE_LABEL_KEYWORDS) { + p.bump_any(); + } else { + break; + } + } + found_value = true; + if !p.eat(COMMA) { + break; + } + } + found_value +} + +// SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT } +// SET [ SESSION | LOCAL ] TIME ZONE { value | 'value' | LOCAL | DEFAULT } +// +// https://www.postgresql.org/docs/17/sql-set.html +fn set_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SET_KW)); + let m = p.start(); + p.bump(SET_KW); + let _ = p.eat(SESSION_KW) || p.eat(LOCAL_KW); + // TIME ZONE { value | 'value' | LOCAL | DEFAULT } + if p.eat(TIME_KW) { + p.expect(ZONE_KW); + if !p.eat(LOCAL_KW) && !config_value(p) { + p.error(format!("expected config value, got {:?}", p.current())); + } + // configuration_parameter { TO | = } { value | 'value' | DEFAULT } + } else { + // configuration_parameter + name_ref(p); + // { TO | = } + let _ = p.eat(TO_KW) || p.expect(EQ); + // { value | 'value' | DEFAULT } + if !config_value(p) { + p.error(format!("expected config value, got {:?}", p.current())); + } + } + m.complete(p, SET_STMT) +} + +// SHOW name +// SHOW ALL +// +// https://www.postgresql.org/docs/17/sql-show.html +fn show_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(SHOW_KW)); + let m = p.start(); + p.bump(SHOW_KW); + if !p.eat(ALL_KW) { + name_ref(p); + } + m.complete(p, SHOW_STMT) +} + +const COLUMN_FIRST: TokenSet = TokenSet::new(&[IDENT]) + .union(UNRESERVED_KEYWORDS) + .union(COLUMN_OR_TABLE_KEYWORDS); + +const NON_RESERVED_WORD: TokenSet = TokenSet::new(&[IDENT]) + .union(UNRESERVED_KEYWORDS) + .union(COLUMN_NAME_KEYWORDS) + .union(TYPE_FUNC_NAME_KEYWORDS); + +fn relation_name(p: &mut Parser<'_>) { + // [ ONLY ] + if p.eat(ONLY_KW) { + let trailing_paren = p.eat(L_PAREN); + // name + path_name_ref(p); + if trailing_paren { + p.expect(R_PAREN); + } + } else { + path_name_ref(p); + p.eat(STAR); + } +} + +// ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// RENAME [ COLUMN ] column_name TO new_column_name +// ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// RENAME CONSTRAINT constraint_name TO new_constraint_name +// ALTER TABLE [ IF EXISTS ] name +// RENAME TO new_name +// +// ALTER TABLE [ IF EXISTS ] name +// SET SCHEMA new_schema +// ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] +// SET TABLESPACE new_tablespace [ NOWAIT ] +// +// ALTER TABLE [ IF EXISTS ] name +// ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT } +// ALTER TABLE [ IF EXISTS ] name +// DETACH PARTITION partition_name [ CONCURRENTLY | FINALIZE ] +// +// ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// action [, ... ] +// +// where action is one of: +// +// ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] +// DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ] +// ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ] +// ALTER [ COLUMN ] column_name SET DEFAULT expression +// ALTER [ COLUMN ] column_name DROP DEFAULT +// ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL +// ALTER [ COLUMN ] column_name SET EXPRESSION AS ( expression ) +// ALTER [ COLUMN ] column_name DROP EXPRESSION [ IF EXISTS ] +// ALTER [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] +// ALTER [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...] +// ALTER [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ] +// ALTER [ COLUMN ] column_name SET STATISTICS { integer | DEFAULT } +// ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) +// ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) +// ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } +// ALTER [ COLUMN ] column_name SET COMPRESSION compression_method +// ADD table_constraint [ NOT VALID ] +// ADD table_constraint_using_index +// ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] +// VALIDATE CONSTRAINT constraint_name +// DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] +// DISABLE TRIGGER [ trigger_name | ALL | USER ] +// ENABLE TRIGGER [ trigger_name | ALL | USER ] +// ENABLE REPLICA TRIGGER trigger_name +// ENABLE ALWAYS TRIGGER trigger_name +// DISABLE RULE rewrite_rule_name +// ENABLE RULE rewrite_rule_name +// ENABLE REPLICA RULE rewrite_rule_name +// ENABLE ALWAYS RULE rewrite_rule_name +// DISABLE ROW LEVEL SECURITY +// ENABLE ROW LEVEL SECURITY +// FORCE ROW LEVEL SECURITY +// NO FORCE ROW LEVEL SECURITY +// CLUSTER ON index_name +// SET WITHOUT CLUSTER +// SET WITHOUT OIDS +// SET ACCESS METHOD { new_access_method | DEFAULT } +// SET TABLESPACE new_tablespace +// SET { LOGGED | UNLOGGED } +// SET ( storage_parameter [= value] [, ... ] ) +// RESET ( storage_parameter [, ... ] ) +// INHERIT parent_table +// NO INHERIT parent_table +// OF type_name +// NOT OF +// OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING } +fn alter_table_stmt(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(ALTER_KW)); + let m = p.start(); + // ALTER TABLE + p.bump(ALTER_KW); + p.expect(TABLE_KW); + let mut all_in_tablespace = false; + // [ ALL IN TABLESPACE] + if p.eat(ALL_KW) { + p.expect(IN_KW); + p.expect(TABLESPACE_KW); + all_in_tablespace = true; + } else { + opt_if_exists(p); + } + relation_name(p); + // ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] + // SET TABLESPACE new_tablespace [ NOWAIT ] + if all_in_tablespace && p.eat(OWNED_KW) { + p.expect(BY_KW); + while !p.at(EOF) { + // name + name_ref(p); + if !p.eat(COMMA) { + break; + } + } + } + // TODO: we should be robust to missing commas + while !p.at(EOF) { + let action = p.start(); + match alter_table_action(p) { + Some(action_kind) => { + action.complete(p, action_kind); + } + None => { + action.abandon(p); + } + }; + if !p.eat(COMMA) { + break; + } + } + m.complete(p, ALTER_TABLE) +} + +fn alter_table_action(p: &mut Parser<'_>) -> Option { + let kind = match p.current() { + // VALIDATE CONSTRAINT constraint_name + VALIDATE_KW => { + p.bump(VALIDATE_KW); + p.expect(CONSTRAINT_KW); + name_ref(p); + VALIDATE_CONSTRAINT + } + // REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING } + REPLICA_KW => { + p.bump(REPLICA_KW); + p.expect(IDENTITY_KW); + if !p.eat(DEFAULT_KW) && !p.eat(FULL_KW) && !p.eat(NOTHING_KW) { + p.expect(USING_KW); + p.expect(INDEX_KW); + name_ref(p); + } + REPLICA_IDENTITY + } + // OF type_name + OF_KW => { + p.bump(OF_KW); + simple_type_name(p); + OF_TYPE + } + // NOT OF + NOT_KW if p.nth_at(1, OF_KW) => { + p.bump(NOT_KW); + p.bump(OF_KW); + NOT_OF + } + // FORCE ROW LEVEL SECURITY + FORCE_KW => { + p.bump(FORCE_KW); + p.expect(ROW_KW); + p.expect(LEVEL_KW); + p.expect(SECURITY_KW); + FORCE_RLS + } + // NO FORCE ROW LEVEL SECURITY + NO_KW if p.nth_at(1, FORCE_KW) => { + p.bump(NO_KW); + p.bump(FORCE_KW); + p.expect(ROW_KW); + p.expect(LEVEL_KW); + p.expect(SECURITY_KW); + NO_FORCE_RLS + } + // INHERIT parent_table + INHERIT_KW => { + p.bump(INHERIT_KW); + path_name_ref(p); + INHERIT + } + // NO INHERIT parent_table + NO_KW if p.nth_at(1, INHERIT_KW) => { + p.bump(NO_KW); + p.bump(INHERIT_KW); + path_name_ref(p); + NO_INHERIT + } + // ENABLE TRIGGER [ trigger_name | ALL | USER ] + // ENABLE REPLICA TRIGGER trigger_name + // ENABLE REPLICA RULE rewrite_rule_name + // ENABLE ALWAYS TRIGGER trigger_name + // ENABLE ALWAYS RULE rewrite_rule_name + // ENABLE RULE rewrite_rule_name + // ENABLE ROW LEVEL SECURITY + ENABLE_KW => { + p.bump(ENABLE_KW); + match p.current() { + TRIGGER_KW => { + p.bump(TRIGGER_KW); + if !p.eat(ALL_KW) && !p.eat(USER_KW) { + name_ref(p); + } + ENABLE_TRIGGER + } + REPLICA_KW => { + p.bump(REPLICA_KW); + if p.eat(TRIGGER_KW) { + name_ref(p); + ENABLE_REPLICA_TRIGGER + } else { + p.expect(RULE_KW); + name_ref(p); + ENABLE_REPLICA_RULE + } + } + ALWAYS_KW => { + p.bump(ALWAYS_KW); + if p.eat(TRIGGER_KW) { + name_ref(p); + ENABLE_ALWAYS_TRIGGER + } else { + p.expect(RULE_KW); + name_ref(p); + ENABLE_ALWAYS_RULE + } + } + RULE_KW => { + p.bump(RULE_KW); + name_ref(p); + ENABLE_RULE + } + ROW_KW => { + p.bump(ROW_KW); + p.expect(LEVEL_KW); + p.expect(SECURITY_KW); + ENABLE_RLS + } + _ => { + p.error("expected TRIGGER, REPLICA, ALWAYS, RULE, or ROW"); + // TODO: just picking something for now + ENABLE_RLS + } + } + } + // DISABLE TRIGGER [ trigger_name | ALL | USER ] + // DISABLE RULE rewrite_rule_name + // DISABLE ROW LEVEL SECURITY + DISABLE_KW => { + p.bump(DISABLE_KW); + match p.current() { + TRIGGER_KW => { + p.bump(TRIGGER_KW); + if !p.eat(ALL_KW) && !p.eat(USER_KW) { + name_ref(p); + } + DISABLE_TRIGGER + } + ROW_KW => { + p.bump(ROW_KW); + p.expect(LEVEL_KW); + p.expect(SECURITY_KW); + DISABLE_RLS + } + RULE_KW => { + p.bump(RULE_KW); + name_ref(p); + DISABLE_RULE + } + _ => { + p.error("expected TRIGGER, ROW, or RULE"); + // TODO: just picking something for now + DISABLE_RULE + } + } + } + // CLUSTER ON index_name + CLUSTER_KW => { + p.bump(CLUSTER_KW); + p.bump(ON_KW); + name_ref(p); + DISABLE_CLUSTER + } + // OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } + OWNER_KW => { + p.bump(OWNER_KW); + p.bump(TO_KW); + if !(p.eat(CURRENT_ROLE_KW) || p.eat(CURRENT_USER_KW) || p.eat(SESSION_USER_KW)) { + name_ref(p); + } + OWNER_TO + } + DETACH_KW => { + p.bump(DETACH_KW); + p.expect(PARTITION_KW); + // partition_name + name_ref(p); + // [ CONCURRENTLY | FINALIZE ] + if !p.eat(CONCURRENTLY_KW) { + p.eat(FINALIZE_KW); + } + DETACH_PARTITION + } + // DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ] + // DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] + DROP_KW => { + p.bump(DROP_KW); + // CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] + let kind = if p.eat(CONSTRAINT_KW) { + opt_if_exists(p); + name_ref(p); + DROP_CONSTRAINT + // [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ] + } else { + p.eat(COLUMN_KW); + opt_if_exists(p); + name_ref(p); + DROP_COLUMN + }; + opt_cascade_or_restrict(p); + kind + } + // ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] + // ADD table_constraint [ NOT VALID ] + // ADD table_constraint_using_index + // + // and table_constraint is: + // + // [ CONSTRAINT constraint_name ] + // { CHECK ( expression ) [ NO INHERIT ] | + // UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | + // PRIMARY KEY ( column_name [, ... ] ) index_parameters | + // EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | + // FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] + // [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } + // [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + // + // + // and table_constraint_using_index is: + // + // [ CONSTRAINT constraint_name ] + // { UNIQUE | PRIMARY KEY } USING INDEX index_name + // [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + ADD_KW => { + p.bump(ADD_KW); + if p.at_ts(TABLE_CONSTRAINT_FIRST) { + // at table_constraint or table_constraint_using_index + table_constraint(p); + opt_not_valid(p); + ADD_CONSTRAINT + } else { + // [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] + // otherwise we're expecting an add column + p.eat(COLUMN_KW); + opt_if_not_exists(p); + // column_name + name_ref(p); + type_name(p); + opt_collate(p); + // [ column_constraint [ ... ] ] + while !p.at(EOF) { + if opt_column_constraint(p).is_none() { + break; + } + } + ADD_COLUMN + } + } + // ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT } + ATTACH_KW => { + p.bump(ATTACH_KW); + p.expect(PARTITION_KW); + // name + name_ref(p); + // { FOR VALUES partition_bound_spec | DEFAULT } + partition_option(p); + ATTACH_PARTITION + } + // SET SCHEMA new_schema + // SET TABLESPACE new_tablespace [ NOWAIT ] + // SET WITHOUT CLUSTER + // SET WITHOUT OIDS + // SET ACCESS METHOD { new_access_method | DEFAULT } + // SET { LOGGED | UNLOGGED } + // SET ( storage_parameter [= value] [, ... ] ) + SET_KW => { + p.expect(SET_KW); + // SET SCHEMA new_schema + if p.eat(SCHEMA_KW) { + // name + name_ref(p); + SET_SCHEMA + // SET TABLESPACE new_tablespace [ NOWAIT ] + } else if p.eat(TABLESPACE_KW) { + // name + name_ref(p); + p.eat(NOWAIT_KW); + SET_TABLESPACE + // SET WITHOUT CLUSTER + // SET WITHOUT OIDS + } else if p.eat(WITHOUT_KW) { + if p.eat(CLUSTER_KW) { + SET_WITHOUT_CLUSTER + } else { + p.expect(OIDS_KW); + SET_WITHOUT_OIDS + } + // SET ACCESS METHOD { new_access_method | DEFAULT } + } else if p.eat(ACCESS_KW) { + p.eat(METHOD_KW); + if !p.eat(DEFAULT_KW) { + // TODO: I think this can be stricter + // name + name_ref(p); + } + SET_ACCESS_METHOD + // SET { LOGGED | UNLOGGED } + } else if p.eat(LOGGED_KW) { + SET_LOGGED + } else if p.eat(UNLOGGED_KW) { + SET_UNLOGGED + // SET ( storage_parameter [= value] [, ... ] ) + } else { + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !storage_parameter(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + SET_STORAGE_PARAMS + } + } + RESET_KW => { + p.bump(RESET_KW); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !storage_parameter(p) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + RESET_STORAGE_PARAMS + } + // RENAME CONSTRAINT constraint_name TO new_constraint_name + // RENAME [ COLUMN ] column_name TO new_column_name + // RENAME TO new_name + RENAME_KW => { + p.expect(RENAME_KW); + // TO new_name + if p.eat(TO_KW) { + // name + name_ref(p); + RENAME_TABLE + // CONSTRAINT + } else if p.eat(CONSTRAINT_KW) { + // name + name_ref(p); + // TO + p.expect(TO_KW); + // name + name_ref(p); + RENAME_CONSTRAINT + // [ COLUMN ] + } else { + p.eat(COLUMN_KW); + // name + name_ref(p); + // TO + p.expect(TO_KW); + // name + name_ref(p); + RENAME_COLUMN + } + } + // ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ] + // ALTER [ COLUMN ] column_name SET DEFAULT expression + // ALTER [ COLUMN ] column_name DROP DEFAULT + // ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL + // ALTER [ COLUMN ] column_name SET EXPRESSION AS ( expression ) + // ALTER [ COLUMN ] column_name DROP EXPRESSION [ IF EXISTS ] + // ALTER [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] + // ALTER [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...] + // ALTER [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ] + // ALTER [ COLUMN ] column_name SET STATISTICS { integer | DEFAULT } + // ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) + // ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) + // ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } + // ALTER [ COLUMN ] column_name SET COMPRESSION compression_method + // ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + ALTER_KW => { + p.bump(ALTER_KW); + // ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + if p.eat(CONSTRAINT_KW) { + // name + name_ref(p); + opt_constraint_options(p); + ALTER_CONSTRAINT + } else { + p.eat(COLUMN_KW); + if p.at_ts(COLUMN_FIRST) { + p.bump_any(); + } else { + p.error("expected column_name"); + } + let m = p.start(); + if let Some(alter_kind) = alter_column_option(p) { + m.complete(p, alter_kind); + } else { + p.error("expected alter column option"); + m.abandon(p); + } + ALTER_COLUMN + } + } + _ => return None, + }; + Some(kind) +} + +fn opt_not_valid(p: &mut Parser<'_>) -> Option { + if p.at(NOT_KW) { + let m = p.start(); + p.bump(NOT_KW); + p.expect(VALID_KW); + Some(m.complete(p, NOT_VALID)) + } else { + None + } +} + +// /* Column label --- allowed labels in "AS" clauses. +// * This presently includes *all* Postgres keywords. +// */ +// ColLabel: IDENT +// | unreserved_keyword +// | col_name_keyword +// | type_func_name_keyword +// | reserved_keyword +fn opt_col_label(p: &mut Parser<'_>) -> bool { + if p.at_ts(COL_LABEL_FIRST) { + let m = p.start(); + p.bump_any(); + m.complete(p, NAME); + true + } else { + false + } +} + +fn col_label(p: &mut Parser<'_>) { + if !opt_col_label(p) { + p.error("expected label"); + } +} + +enum AttributeValue { + Either, + Required, + Disallowed, +} + +// reloption_list: +// | reloption_elem +// | reloption_list ',' reloption_elem +// reloption_elem: +// | ColLabel '=' def_arg +// | ColLabel +// | ColLabel '.' ColLabel '=' def_arg +// | ColLabel '.' ColLabel +fn attribute_option(p: &mut Parser<'_>, option: AttributeValue) -> bool { + if !opt_col_label(p) { + return false; + } + if p.eat(DOT) && !opt_col_label(p) { + p.error("expected column label") + } + match option { + AttributeValue::Required => { + p.expect(EQ); + def_arg(p); + } + AttributeValue::Disallowed => {} + AttributeValue::Either => { + if p.eat(EQ) { + def_arg(p); + } + } + } + true +} + +// def_arg: +// | func_type +// | reserved_keyword +// | qual_all_Op +// | NumericOnly +// | Sconst +// | NONE +// +// qual_all_Op: +// | all_Op +// | OPERATOR '(' any_operator ')' +fn def_arg(p: &mut Parser<'_>) -> bool { + if opt_bool_literal(p) + || opt_string_literal(p).is_some() + || opt_numeric_literal(p).is_some() + || opt_operator(p) + || p.eat(NONE_KW) + { + true + } else if p.at_ts(RESERVED_KEYWORDS) { + p.bump_any(); + true + } else if p.eat(OPERATOR_KW) { + p.expect(L_PAREN); + operator(p); + p.expect(R_PAREN); + true + } else { + opt_type_name(p) + } +} + +fn generated_options(p: &mut Parser<'_>) { + // { + // | SET GENERATED { ALWAYS | BY DEFAULT } + // | SET sequence_option + // | RESTART [ [ WITH ] restart ] + // } [...] + while !p.at(EOF) { + let m = p.start(); + if p.eat(RESTART_KW) { + if p.eat(WITH_KW) { + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + } else { + let _ = opt_numeric_literal(p); + } + m.complete(p, RESTART); + } else if p.eat(SET_KW) { + if opt_sequence_option(p) { + m.complete(p, SET_SEQUENCE_OPTION); + continue; + } else { + p.expect(GENERATED_KW); + if !p.eat(ALWAYS_KW) { + p.expect(BY_KW); + p.expect(DEFAULT_KW); + } + m.complete(p, SET_GENERATED); + } + } else { + m.abandon(p); + break; + } + } +} + +// [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ] +// [ COLUMN ] column_name SET DEFAULT expression +// [ COLUMN ] column_name DROP DEFAULT +// [ COLUMN ] column_name { SET | DROP } NOT NULL +// [ COLUMN ] column_name SET EXPRESSION AS ( expression ) +// [ COLUMN ] column_name DROP EXPRESSION [ IF EXISTS ] +// [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] +// [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...] +// [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ] +// [ COLUMN ] column_name SET STATISTICS { integer | DEFAULT } +// [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) +// [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) +// [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } +// [ COLUMN ] column_name SET COMPRESSION compression_method +// [ COLUMN ] column_name OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) +fn alter_column_option(p: &mut Parser<'_>) -> Option { + // DROP NOT NULL + // DROP DEFAULT + // DROP EXPRESSION [ IF EXISTS ] + // DROP IDENTITY [ IF EXISTS ] + let kind = match p.current() { + DROP_KW => { + p.bump(DROP_KW); + if p.eat(DEFAULT_KW) { + DROP_DEFAULT + } else if p.eat(EXPRESSION_KW) { + opt_if_exists(p); + DROP_EXPRESSION + } else if p.eat(IDENTITY_KW) { + opt_if_exists(p); + DROP_IDENTITY + } else { + p.expect(NOT_KW); + p.expect(NULL_KW); + DROP_NOT_NULL + } + } + // RESTART [ [ WITH ] restart ] + RESTART => { + p.bump(RESTART_KW); + if p.eat(WITH_KW) { + p.expect(RESTART_KW); + } else { + p.eat(RESTART_KW); + } + RESTART + } + ADD_KW => { + p.bump(ADD_KW); + // ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] + p.expect(GENERATED_KW); + if !p.eat(ALWAYS_KW) { + p.expect(BY_KW); + p.expect(DEFAULT_KW); + } + p.expect(AS_KW); + p.expect(IDENTITY_KW); + opt_sequence_options(p); + ADD_GENERATED + } + // RESET ( attribute_option [, ... ] ) + RESET_KW => { + p.bump(RESET_KW); + p.expect(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !attribute_option(p, AttributeValue::Disallowed) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + RESET_OPTIONS + } + // TYPE data_type [ COLLATE collation ] [ USING expression ] + TYPE_KW => { + set_data_type(p); + SET_TYPE + } + // SET DATA TYPE data_type [ COLLATE collation ] [ USING expression ] + SET_KW if p.nth_at(1, DATA_KW) => { + p.bump(SET_KW); + p.bump(DATA_KW); + set_data_type(p); + SET_TYPE + } + // { SET GENERATED { ALWAYS | BY DEFAULT } + SET_KW if p.nth_at(1, GENERATED_KW) => { + generated_options(p); + SET_GENERATED_OPTIONS + } + // SET sequence_option + SET_KW if p.nth_at_ts(1, SEQUENCE_OPTION_FIRST) => { + generated_options(p); + SET_GENERATED_OPTIONS + } + // RESTART [ [ WITH ] restart ] } [...] + RESTART_KW => { + generated_options(p); + SET_GENERATED_OPTIONS + } + // OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) + OPTIONS_KW => { + p.bump(OPTIONS_KW); + p.expect(L_PAREN); + alter_option(p); + while !p.at(EOF) && p.eat(COMMA) { + alter_option(p); + } + p.expect(R_PAREN); + SET_OPTIONS_LIST + } + // SET DEFAULT expression + SET_KW if p.nth_at(1, DEFAULT_KW) => { + p.bump(SET_KW); + p.bump(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected expr"); + } + SET_DEFAULT + } + // SET EXPRESSION AS ( expression ) + SET_KW if p.nth_at(1, EXPRESSION_KW) => { + p.bump(SET_KW); + p.bump(EXPRESSION_KW); + p.expect(AS_KW); + p.expect(L_PAREN); + if expr(p).is_none() { + p.error("expected expr"); + } + p.expect(R_PAREN); + SET_EXPRESSION + } + // SET STATISTICS { integer | DEFAULT } + SET_KW if p.nth_at(1, STATISTICS_KW) => { + p.bump(SET_KW); + p.bump(STATISTICS_KW); + if !p.eat(DEFAULT_KW) { + if opt_numeric_literal(p).is_none() { + p.error("expected numeric literal"); + } + } + SET_STATISTICS + } + // SET ( attribute_option = value [, ... ] ) + SET_KW if p.nth_at(1, L_PAREN) => { + p.bump(SET_KW); + p.bump(L_PAREN); + while !p.at(EOF) && !p.at(R_PAREN) { + if !attribute_option(p, AttributeValue::Either) { + break; + } + if !p.eat(COMMA) { + break; + } + } + p.expect(R_PAREN); + SET_OPTIONS + } + // SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } + SET_KW if p.nth_at(1, STORAGE_KW) => { + p.bump(SET_KW); + p.bump(STORAGE_KW); + if !p.eat(DEFAULT_KW) { + if p.at_ts(COLUMN_FIRST) { + p.bump_any(); + } else { + p.error("expected name"); + } + } + SET_STORAGE + } + // SET COMPRESSION { ColId | DEFAULT } + SET_KW if p.nth_at(1, COMPRESSION_KW) => { + p.bump(SET_KW); + p.bump(COMPRESSION_KW); + if !p.eat(DEFAULT_KW) { + if p.at_ts(COLUMN_FIRST) { + p.bump_any(); + } else { + p.error("expected name"); + } + } + SET_COMPRESSION + } + // SET NOT NULL + SET_KW if p.nth_at(1, NOT_KW) => { + p.bump(SET_KW); + p.bump(NOT_KW); + p.expect(NULL_KW); + SET_NOT_NULL + } + _ => return None, + }; + Some(kind) +} + +fn opt_collate(p: &mut Parser<'_>) -> Option { + let m = p.start(); + if p.eat(COLLATE_KW) { + path_name_ref(p); + Some(m.complete(p, COLLATE)) + } else { + m.abandon(p); + None + } +} + +// TYPE data_type [ COLLATE collation ] [ USING expression ] +fn set_data_type(p: &mut Parser<'_>) { + p.expect(TYPE_KW); + type_name(p); + opt_collate(p); + if p.eat(USING_KW) && expr(p).is_none() { + p.error("expected expression"); + } +} + +pub(crate) fn entry_point(p: &mut Parser) { + let m = p.start(); + while !p.at(EOF) { + // handle things like: ;;;select 1 + if p.eat(SEMICOLON) { + continue; + } + let parsed_stmt = stmt( + p, + &StmtRestrictions { + begin_end_allowed: true, + }, + ); + if !p.at(EOF) && parsed_stmt.is_some() { + p.expect(SEMICOLON); + } + } + m.complete(p, SOURCE_FILE); +} diff --git a/crates/squawk_parser/src/input.rs b/crates/squawk_parser/src/input.rs new file mode 100644 index 00000000..0f960abe --- /dev/null +++ b/crates/squawk_parser/src/input.rs @@ -0,0 +1,120 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/input.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//! See [`Input`]. + +use crate::SyntaxKind; + +#[allow(non_camel_case_types)] +type bits = u64; + +/// Input for the parser -- a sequence of tokens. +/// +/// As of now, parser doesn't have access to the *text* of the tokens, and makes +/// decisions based solely on their classification. Unlike `LexerToken`, the +/// `Tokens` doesn't include whitespace and comments. Main input to the parser. +/// +/// Struct of arrays internally, but this shouldn't really matter. +#[derive(Default)] +pub struct Input { + kind: Vec, + joint: Vec, + // TODO: I think we can remove this + contextual_kind: Vec, +} + +/// `pub` impl used by callers to create `Tokens`. +impl Input { + #[inline] + pub(crate) fn push(&mut self, kind: SyntaxKind) { + self.push_impl(kind, SyntaxKind::EOF) + } + // #[inline] + // pub(crate) fn push_ident(&mut self, contextual_kind: SyntaxKind) { + // self.push_impl(SyntaxKind::IDENT, contextual_kind) + // } + /// Sets jointness for the last token we've pushed. + /// + /// This is a separate API rather than an argument to the `push` to make it + /// convenient both for textual and mbe tokens. With text, you know whether + /// the *previous* token was joint, with mbe, you know whether the *current* + /// one is joint. This API allows for styles of usage: + /// + /// ``` + /// // In text: + /// tokens.was_joint(prev_joint); + /// tokens.push(curr); + /// + /// // In MBE: + /// token.push(curr); + /// tokens.push(curr_joint) + /// ``` + #[inline] + pub(crate) fn was_joint(&mut self) { + let n = self.len() - 1; + let (idx, b_idx) = self.bit_index(n); + self.joint[idx] |= 1 << b_idx; + } + #[inline] + fn push_impl(&mut self, kind: SyntaxKind, contextual_kind: SyntaxKind) { + let idx = self.len(); + if idx % (bits::BITS as usize) == 0 { + self.joint.push(0); + } + self.kind.push(kind); + self.contextual_kind.push(contextual_kind); + } +} + +/// pub(crate) impl used by the parser to consume `Tokens`. +impl Input { + pub(crate) fn kind(&self, idx: usize) -> SyntaxKind { + self.kind.get(idx).copied().unwrap_or(SyntaxKind::EOF) + } + // TODO: we may want to use this in the parser since we have a lot of + // "keywords" that are actually contextual. + // pub(crate) fn contextual_kind(&self, idx: usize) -> SyntaxKind { + // self.contextual_kind + // .get(idx) + // .copied() + // .unwrap_or(SyntaxKind::EOF) + // } + pub(crate) fn is_joint(&self, n: usize) -> bool { + let (idx, b_idx) = self.bit_index(n); + self.joint[idx] & 1 << b_idx != 0 + } +} + +impl Input { + fn bit_index(&self, n: usize) -> (usize, usize) { + let idx = n / (bits::BITS as usize); + let b_idx = n % (bits::BITS as usize); + (idx, b_idx) + } + fn len(&self) -> usize { + self.kind.len() + } +} diff --git a/crates/squawk_parser/src/lexed_str.rs b/crates/squawk_parser/src/lexed_str.rs new file mode 100644 index 00000000..58b14b2c --- /dev/null +++ b/crates/squawk_parser/src/lexed_str.rs @@ -0,0 +1,301 @@ +// based on https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/lexed_str.rs + +use std::ops; + +use squawk_lexer::tokenize; + +use crate::SyntaxKind; + +pub struct LexedStr<'a> { + text: &'a str, + kind: Vec, + start: Vec, + error: Vec, +} + +struct LexError { + msg: String, + token: u32, +} + +impl<'a> LexedStr<'a> { + // TODO: rust-analyzer has an edition thing to specify things that are only + // available in certain version, we can do that later + pub fn new(text: &'a str) -> LexedStr<'a> { + let mut conv = Converter::new(text); + + for token in tokenize(&text[conv.offset..]) { + let token_text = &text[conv.offset..][..token.len as usize]; + + conv.extend_token(&token.kind, token_text); + } + + conv.finalize_with_eof() + } + + // pub(crate) fn single_token(text: &'a str) -> Option<(SyntaxKind, Option)> { + // if text.is_empty() { + // return None; + // } + + // let token = tokenize(text).next()?; + // if token.len as usize != text.len() { + // return None; + // } + + // let mut conv = Converter::new(text); + // conv.extend_token(&token.kind, text); + // match &*conv.res.kind { + // [kind] => Some((*kind, conv.res.error.pop().map(|it| it.msg))), + // _ => None, + // } + // } + + // pub(crate) fn as_str(&self) -> &str { + // self.text + // } + + pub(crate) fn len(&self) -> usize { + self.kind.len() - 1 + } + + // pub(crate) fn is_empty(&self) -> bool { + // self.len() == 0 + // } + + pub(crate) fn kind(&self, i: usize) -> SyntaxKind { + assert!(i < self.len()); + self.kind[i] + } + + pub(crate) fn text(&self, i: usize) -> &str { + self.range_text(i..i + 1) + } + + pub(crate) fn range_text(&self, r: ops::Range) -> &str { + assert!(r.start < r.end && r.end <= self.len()); + let lo = self.start[r.start] as usize; + let hi = self.start[r.end] as usize; + &self.text[lo..hi] + } + + // Naming is hard. + pub fn text_range(&self, i: usize) -> ops::Range { + assert!(i < self.len()); + let lo = self.start[i] as usize; + let hi = self.start[i + 1] as usize; + lo..hi + } + pub(crate) fn text_start(&self, i: usize) -> usize { + assert!(i <= self.len()); + self.start[i] as usize + } + // pub(crate) fn text_len(&self, i: usize) -> usize { + // assert!(i < self.len()); + // let r = self.text_range(i); + // r.end - r.start + // } + + // pub(crate) fn error(&self, i: usize) -> Option<&str> { + // assert!(i < self.len()); + // let err = self + // .error + // .binary_search_by_key(&(i as u32), |i| i.token) + // .ok()?; + // Some(self.error[err].msg.as_str()) + // } + + pub fn errors(&self) -> impl Iterator + '_ { + self.error + .iter() + .map(|it| (it.token as usize, it.msg.as_str())) + } + + fn push(&mut self, kind: SyntaxKind, offset: usize) { + self.kind.push(kind); + self.start.push(offset as u32); + } +} + +struct Converter<'a> { + res: LexedStr<'a>, + offset: usize, +} + +impl<'a> Converter<'a> { + fn new(text: &'a str) -> Self { + Self { + res: LexedStr { + text, + kind: Vec::new(), + start: Vec::new(), + error: Vec::new(), + }, + offset: 0, + } + } + + fn finalize_with_eof(mut self) -> LexedStr<'a> { + self.res.push(SyntaxKind::EOF, self.offset); + self.res + } + + fn push(&mut self, kind: SyntaxKind, len: usize, err: Option<&str>) { + self.res.push(kind, self.offset); + self.offset += len; + + if let Some(err) = err { + let token = self.res.len() as u32; + let msg = err.to_owned(); + self.res.error.push(LexError { msg, token }); + } + } + + fn extend_token(&mut self, kind: &squawk_lexer::TokenKind, token_text: &str) { + // A note on an intended tradeoff: + // We drop some useful information here (see patterns with double dots `..`) + // Storing that info in `SyntaxKind` is not possible due to its layout requirements of + // being `u16` that come from `rowan::SyntaxKind`. + let mut err = ""; + + let syntax_kind = { + match kind { + squawk_lexer::TokenKind::LineComment => SyntaxKind::COMMENT, + squawk_lexer::TokenKind::BlockComment { terminated } => { + if !terminated { + err = "Missing trailing `*/` symbols to terminate the block comment"; + } + SyntaxKind::COMMENT + } + + squawk_lexer::TokenKind::Whitespace => SyntaxKind::WHITESPACE, + squawk_lexer::TokenKind::Ident => { + // TODO: check for max identifier length + // + // see: https://www.postgresql.org/docs/16/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS + // The system uses no more than NAMEDATALEN-1 bytes of an + // identifier; longer names can be written in commands, but + // they will be truncated. By default, NAMEDATALEN is 64 so + // the maximum identifier length is 63 bytes. If this limit + // is problematic, it can be raised by changing the + // NAMEDATALEN constant in src/include/pg_config_manual.h. + // see: https://github.com/postgres/postgres/blob/e032e4c7ddd0e1f7865b246ec18944365d4f8614/src/include/pg_config_manual.h#L29 + SyntaxKind::from_keyword(token_text).unwrap_or(SyntaxKind::IDENT) + } + squawk_lexer::TokenKind::Literal { kind, .. } => { + self.extend_literal(token_text.len(), kind); + return; + } + squawk_lexer::TokenKind::Semi => SyntaxKind::SEMICOLON, + squawk_lexer::TokenKind::Comma => SyntaxKind::COMMA, + squawk_lexer::TokenKind::Dot => SyntaxKind::DOT, + squawk_lexer::TokenKind::OpenParen => SyntaxKind::L_PAREN, + squawk_lexer::TokenKind::CloseParen => SyntaxKind::R_PAREN, + squawk_lexer::TokenKind::OpenBracket => SyntaxKind::L_BRACK, + squawk_lexer::TokenKind::CloseBracket => SyntaxKind::R_BRACK, + squawk_lexer::TokenKind::At => SyntaxKind::AT, + squawk_lexer::TokenKind::Pound => SyntaxKind::POUND, + squawk_lexer::TokenKind::Tilde => SyntaxKind::TILDE, + squawk_lexer::TokenKind::Question => SyntaxKind::QUESTION, + squawk_lexer::TokenKind::Colon => SyntaxKind::COLON, + squawk_lexer::TokenKind::Eq => SyntaxKind::EQ, + squawk_lexer::TokenKind::Bang => SyntaxKind::BANG, + squawk_lexer::TokenKind::Lt => SyntaxKind::L_ANGLE, + squawk_lexer::TokenKind::Gt => SyntaxKind::R_ANGLE, + squawk_lexer::TokenKind::Minus => SyntaxKind::MINUS, + squawk_lexer::TokenKind::And => SyntaxKind::AMP, + squawk_lexer::TokenKind::Or => SyntaxKind::PIPE, + squawk_lexer::TokenKind::Plus => SyntaxKind::PLUS, + squawk_lexer::TokenKind::Star => SyntaxKind::STAR, + squawk_lexer::TokenKind::Slash => SyntaxKind::SLASH, + squawk_lexer::TokenKind::Caret => SyntaxKind::CARET, + squawk_lexer::TokenKind::Percent => SyntaxKind::PERCENT, + squawk_lexer::TokenKind::Unknown => SyntaxKind::ERROR, + squawk_lexer::TokenKind::UnknownPrefix => { + err = "unknown literal prefix"; + SyntaxKind::IDENT + } + squawk_lexer::TokenKind::Eof => SyntaxKind::EOF, + squawk_lexer::TokenKind::Backtick => SyntaxKind::BACKTICK, + squawk_lexer::TokenKind::Param => SyntaxKind::PARAM, + squawk_lexer::TokenKind::QuotedIdent { terminated } => { + if !terminated { + err = "Missing trailing \" to terminate the quoted identifier" + } + SyntaxKind::IDENT + } + } + }; + + let err = if err.is_empty() { None } else { Some(err) }; + self.push(syntax_kind, token_text.len(), err); + } + + fn extend_literal(&mut self, len: usize, kind: &squawk_lexer::LiteralKind) { + let mut err = ""; + + let syntax_kind = match *kind { + squawk_lexer::LiteralKind::Int { empty_int, base: _ } => { + if empty_int { + err = "Missing digits after the integer base prefix"; + } + SyntaxKind::INT_NUMBER + } + squawk_lexer::LiteralKind::Float { + empty_exponent, + base: _, + } => { + if empty_exponent { + err = "Missing digits after the exponent symbol"; + } + SyntaxKind::FLOAT_NUMBER + } + squawk_lexer::LiteralKind::Str { terminated } => { + if !terminated { + err = "Missing trailing `'` symbol to terminate the string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::STRING + } + squawk_lexer::LiteralKind::ByteStr { terminated } => { + if !terminated { + err = "Missing trailing `'` symbol to terminate the hex bit string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::BYTE_STRING + } + squawk_lexer::LiteralKind::BitStr { terminated } => { + if !terminated { + err = "Missing trailing `\'` symbol to terminate the bit string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::BIT_STRING + } + squawk_lexer::LiteralKind::DollarQuotedString { terminated } => { + if !terminated { + // TODO: we could be fancier and say the ending string we're looking for + err = "Unterminated dollar quoted string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::DOLLAR_QUOTED_STRING + } + squawk_lexer::LiteralKind::UnicodeEscStr { terminated } => { + if !terminated { + err = "Missing trailing `'` symbol to terminate the unicode escape string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::BYTE_STRING + } + squawk_lexer::LiteralKind::EscStr { terminated } => { + if !terminated { + err = "Missing trailing `\'` symbol to terminate the escape string literal"; + } + // TODO: rust analzyer checks for un-escaped strings, we should too + SyntaxKind::ESC_STRING + } + }; + + let err = if err.is_empty() { None } else { Some(err) }; + self.push(syntax_kind, len, err); + } +} diff --git a/crates/squawk_parser/src/lib.rs b/crates/squawk_parser/src/lib.rs new file mode 100644 index 00000000..07b802f6 --- /dev/null +++ b/crates/squawk_parser/src/lib.rs @@ -0,0 +1,655 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/lib.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// https://www.scattered-thoughts.net/writing/babys-second-wasm-compiler/ +// +// https://craftinginterpreters.com/parsing-expressions.html +// +// see: https://github.com/rust-lang/rust-analyzer/blob/master/crates/parser/src/parser.rs +// https://rust-analyzer.github.io/blog/2020/09/16/challeging-LR-parsing.html +// https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/syntax.md +// https://ericlippert.com/2012/06/08/red-green-trees/ +// https://github.com/swiftlang/swift/tree/5e2c815edfd758f9b1309ce07bfc01c4bc20ec23/lib/Syntax +// https://swift-ast-explorer.com +// https://github.com/rust-lang/rust-analyzer/blob/cf156a7a43f822e71309e50470ac34363da26727/docs/dev/syntax.md +// https://github.com/kaleidawave/ezno/blob/8ce921e39c3d4e947063f206347b2932cee456ec/parser/src/lib.rs#L177 +// https://kaleidawave.github.io/posts/sets-types-and-type-checking/ +// https://github.com/m-novikov/tree-sitter-sql/tree/main +// https://github.com/withered-magic/starpls/tree/79f47e12dab8be650804ce7fa931ee5e1e116eae/crates/starpls_parser/src +// https://github.com/apache/datafusion-sqlparser-rs -- removes comments and whitespace :/ + +// rust analyzer has a builtin doc test like thing where you generate snapshot +// style tests from comments on top of grammar functions + +use drop_bomb::DropBomb; +use event::Event; +use grammar::OPERATOR_FIRST; +use std::cell::Cell; +use token_set::TokenSet; +mod grammar; +mod token_set; + +mod lexed_str; +mod shortcuts; +mod syntax_kind; + +mod event; +mod input; +mod output; + +#[cfg(test)] +mod test; + +pub use crate::{ + lexed_str::LexedStr, + // output::{Output, Step}, + shortcuts::StrStep, + syntax_kind::SyntaxKind, +}; + +use crate::input::Input; +pub use crate::output::Output; + +/// See [`Parser::start`]. +pub(crate) struct Marker { + pos: u32, + bomb: DropBomb, +} + +impl Marker { + fn new(pos: u32) -> Marker { + Marker { + pos, + bomb: DropBomb::new("Marker must be either completed or abandoned"), + } + } + + /// Finishes the syntax tree node and assigns `kind` to it, + /// and mark the create a `CompletedMarker` for possible future + /// operation like `.precede()` to deal with `forward_parent`. + pub(crate) fn complete(mut self, p: &mut Parser<'_>, kind: SyntaxKind) -> CompletedMarker { + self.bomb.defuse(); + let idx = self.pos as usize; + match &mut p.events[idx] { + Event::Start { kind: slot, .. } => { + *slot = kind; + } + _ => unreachable!(), + } + p.push_event(Event::Finish); + CompletedMarker::new(self.pos, kind) + } + + /// Abandons the syntax tree node. All its children + /// are attached to its parent instead. + pub(crate) fn abandon(mut self, p: &mut Parser<'_>) { + self.bomb.defuse(); + let idx = self.pos as usize; + if idx == p.events.len() - 1 { + match p.events.pop() { + Some(Event::Start { + kind: SyntaxKind::TOMBSTONE, + forward_parent: None, + }) => (), + _ => unreachable!(), + } + } + } +} + +pub(crate) struct CompletedMarker { + pos: u32, + kind: SyntaxKind, +} + +impl CompletedMarker { + fn new(pos: u32, kind: SyntaxKind) -> Self { + CompletedMarker { pos, kind } + } + + /// This method allows to create a new node which starts + /// *before* the current one. That is, parser could start + /// node `A`, then complete it, and then after parsing the + /// whole `A`, decide that it should have started some node + /// `B` before starting `A`. `precede` allows to do exactly + /// that. See also docs about + /// [`Event::Start::forward_parent`](crate::event::Event::Start::forward_parent). + /// + /// Given completed events `[START, FINISH]` and its corresponding + /// `CompletedMarker(pos: 0, _)`. + /// Append a new `START` events as `[START, FINISH, NEWSTART]`, + /// then mark `NEWSTART` as `START`'s parent with saving its relative + /// distance to `NEWSTART` into `forward_parent`(=2 in this case); + pub(crate) fn precede(self, p: &mut Parser<'_>) -> Marker { + let new_pos = p.start(); + let idx = self.pos as usize; + match &mut p.events[idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(new_pos.pos - self.pos); + } + _ => unreachable!(), + } + new_pos + } + + /// Extends this completed marker *to the left* up to `m`. + pub(crate) fn extend_to(self, p: &mut Parser<'_>, mut m: Marker) -> CompletedMarker { + m.bomb.defuse(); + let idx = m.pos as usize; + match &mut p.events[idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(self.pos - m.pos); + } + _ => unreachable!(), + } + self + } + + pub(crate) fn kind(&self) -> SyntaxKind { + self.kind + } +} + +pub fn parse(input: &Input) -> Output { + let mut p = Parser::new(input); + // 2. lex tokens to event vec via parser aka actually run the parser code, + // it calls the methods on the parser to create a vector of events + grammar::entry_point(&mut p); + let events = p.finish(); + // 3. forward parents + event::process(events) +} + +pub(crate) struct Parser<'t> { + inp: &'t Input, + pos: usize, + events: Vec, + steps: Cell, +} + +const PARSER_STEP_LIMIT: usize = 15_000_000; + +enum TrivaBetween { + NotAllowed, + Allowed, +} + +impl<'t> Parser<'t> { + fn new(inp: &'t Input) -> Parser<'t> { + Parser { + inp, + pos: 0, + events: vec![], + steps: Cell::new(0), + } + } + + /// Consume the next token if `kind` matches. + pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool { + if !self.at(kind) { + return false; + } + let n_raw_tokens = match kind { + SyntaxKind::COLON2 + | SyntaxKind::COLONEQ + | SyntaxKind::NEQ + | SyntaxKind::NEQB + | SyntaxKind::LTEQ + | SyntaxKind::FAT_ARROW + | SyntaxKind::GTEQ => 2, + SyntaxKind::SIMILAR_TO => { + let m = self.start(); + self.bump(SyntaxKind::SIMILAR_KW); + self.bump(SyntaxKind::TO_KW); + m.complete(self, SyntaxKind::SIMILAR_TO); + return true; + } + SyntaxKind::AT_TIME_ZONE => { + let m = self.start(); + self.bump(SyntaxKind::AT_KW); + self.bump(SyntaxKind::TIME_KW); + self.bump(SyntaxKind::ZONE_KW); + m.complete(self, SyntaxKind::AT_TIME_ZONE); + return true; + } + SyntaxKind::IS_NOT_DISTINCT_FROM => { + let m = self.start(); + self.bump(SyntaxKind::IS_KW); + self.bump(SyntaxKind::NOT_KW); + self.bump(SyntaxKind::DISTINCT_KW); + self.bump(SyntaxKind::FROM_KW); + m.complete(self, SyntaxKind::IS_NOT_DISTINCT_FROM); + return true; + } + SyntaxKind::OPERATOR_CALL => { + let m = self.start(); + self.bump(SyntaxKind::OPERATOR_KW); + self.bump(SyntaxKind::L_PAREN); + + // database. + if self.eat(SyntaxKind::IDENT) { + self.expect(SyntaxKind::DOT); + } + // schema. + if self.eat(SyntaxKind::IDENT) { + self.expect(SyntaxKind::DOT); + } + + // +, -, etc. + match grammar::current_operator(self) { + Some(kind) => { + self.bump(kind); + } + None => { + self.error("expected operator"); + } + } + + self.expect(SyntaxKind::R_PAREN); + m.complete(self, SyntaxKind::OPERATOR_CALL); + return true; + } + SyntaxKind::IS_DISTINCT_FROM => { + let m = self.start(); + self.bump(SyntaxKind::IS_KW); + self.bump(SyntaxKind::DISTINCT_KW); + self.bump(SyntaxKind::FROM_KW); + m.complete(self, SyntaxKind::IS_DISTINCT_FROM); + return true; + } + SyntaxKind::NOT_LIKE => { + let m = self.start(); + self.bump(SyntaxKind::NOT_KW); + self.bump(SyntaxKind::LIKE_KW); + m.complete(self, SyntaxKind::NOT_LIKE); + return true; + } + SyntaxKind::NOT_IN => { + let m = self.start(); + self.bump(SyntaxKind::NOT_KW); + self.bump(SyntaxKind::IN_KW); + m.complete(self, SyntaxKind::NOT_IN); + return true; + } + SyntaxKind::IS_NOT => { + let m = self.start(); + self.bump(SyntaxKind::IS_KW); + self.bump(SyntaxKind::NOT_KW); + m.complete(self, SyntaxKind::IS_NOT); + return true; + } + SyntaxKind::CUSTOM_OP => { + let m = self.start(); + while !self.at(SyntaxKind::EOF) { + let is_joint = self.inp.is_joint(self.pos); + if self.at_ts(OPERATOR_FIRST) { + self.bump_any(); + } else { + break; + } + if !is_joint { + break; + } + } + m.complete(self, SyntaxKind::CUSTOM_OP); + return true; + } + _ => 1, + }; + self.do_bump(kind, n_raw_tokens); + true + } + + fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, triva: TrivaBetween) -> bool { + let tokens_match = + self.inp.kind(self.pos + n) == k1 && self.inp.kind(self.pos + n + 1) == k2; + // We need to do this so we can say that: + // 1 > > 2, is not the same as 1 >> 2 + match triva { + TrivaBetween::Allowed => tokens_match, + TrivaBetween::NotAllowed => { + return tokens_match + && self.inp.is_joint(self.pos + n) + && self.next_not_joined_op(n + 1); + } + } + } + + fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool { + self.inp.kind(self.pos + n) == k1 + && self.inp.kind(self.pos + n + 1) == k2 + && self.inp.kind(self.pos + n + 2) == k3 + } + + fn at_composite4( + &self, + n: usize, + k1: SyntaxKind, + k2: SyntaxKind, + k3: SyntaxKind, + k4: SyntaxKind, + ) -> bool { + self.inp.kind(self.pos + n) == k1 + && self.inp.kind(self.pos + n + 1) == k2 + && self.inp.kind(self.pos + n + 2) == k3 + && self.inp.kind(self.pos + n + 3) == k4 + } + + fn next_not_joined_op(&self, n: usize) -> bool { + let next = self.inp.kind(self.pos + n + 1); + // next isn't an operator so we know we're not joined to it + if !OPERATOR_FIRST.contains(next) { + return true; + } + // current kind isn't joined + if !self.inp.is_joint(self.pos + n) { + return true; + } + false + } + + /// Checks if the current token is in `kinds`. + pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool { + kinds.contains(self.current()) + } + + /// Starts a new node in the syntax tree. All nodes and tokens + /// consumed between the `start` and the corresponding `Marker::complete` + /// belong to the same node. + pub(crate) fn start(&mut self) -> Marker { + let pos = self.events.len() as u32; + self.push_event(Event::tombstone()); + Marker::new(pos) + } + + /// Consume the next token. Panics if the parser isn't currently at `kind`. + pub(crate) fn bump(&mut self, kind: SyntaxKind) { + assert!(self.eat(kind)); + } + + /// Advances the parser by one token + pub(crate) fn bump_any(&mut self) { + let kind = self.nth(0); + if kind == SyntaxKind::EOF { + return; + } + self.do_bump(kind, 1); + } + + /// Advances the parser by one token + pub(crate) fn split_float(&mut self, mut marker: Marker) -> (bool, Marker) { + assert!(self.at(SyntaxKind::FLOAT_NUMBER)); + // we have parse `.` + // ``.0.1 + // here we need to insert an extra event + // + // ``. 0. 1; + // here we need to change the follow up parse, the return value will cause us to emulate a dot + // the actual splitting happens later + let ends_in_dot = !self.inp.is_joint(self.pos); + if !ends_in_dot { + let new_marker = self.start(); + let idx = marker.pos as usize; + match &mut self.events[idx] { + Event::Start { + forward_parent, + kind, + } => { + *kind = SyntaxKind::FIELD_EXPR; + *forward_parent = Some(new_marker.pos - marker.pos); + } + _ => unreachable!(), + } + marker.bomb.defuse(); + marker = new_marker; + }; + self.pos += 1; + self.push_event(Event::FloatSplitHack { ends_in_dot }); + (ends_in_dot, marker) + } + + /// Consume the next token if it is `kind` or emit an error + /// otherwise. + pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { + if self.eat(kind) { + return true; + } + self.error(format!("expected {kind:?}")); + false + } + + /// Create an error node and consume the next token. + pub(crate) fn err_and_bump(&mut self, message: &str) { + self.err_recover(message, TokenSet::EMPTY); + } + + /// Create an error node and consume the next token. + pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { + // TODO: maybe we actually want this? + // if matches!(self.current(), SyntaxKind::L_PAREN | SyntaxKind::R_PAREN) { + // self.error(message); + // return; + // } + + if self.at_ts(recovery) { + self.error(message); + return; + } + + let m = self.start(); + self.error(message); + self.bump_any(); + m.complete(self, SyntaxKind::ERROR); + } + + fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { + self.pos += n_raw_tokens as usize; + self.steps.set(0); + self.push_event(Event::Token { kind, n_raw_tokens }); + } + + fn push_event(&mut self, event: Event) { + self.events.push(event); + } + + fn finish(self) -> Vec { + self.events + } + + /// Emit error with the `message` + /// FIXME: this should be much more fancy and support + /// structured errors with spans and notes, like rustc + /// does. + pub(crate) fn error>(&mut self, message: T) { + let msg = message.into(); + self.push_event(Event::Error { msg }); + } + + /// Checks if the current token is `kind`. + #[must_use] + pub(crate) fn at(&self, kind: SyntaxKind) -> bool { + self.nth_at(0, kind) + } + + /// Checks if the nth token is in `kinds`. + #[must_use] + pub(crate) fn nth_at_ts(&self, n: usize, kinds: TokenSet) -> bool { + kinds.contains(self.nth(n)) + } + + #[must_use] + pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool { + match kind { + // => + SyntaxKind::FAT_ARROW => self.at_composite2( + n, + SyntaxKind::EQ, + SyntaxKind::R_ANGLE, + TrivaBetween::NotAllowed, + ), + // := + SyntaxKind::COLONEQ => self.at_composite2( + n, + SyntaxKind::COLON, + SyntaxKind::EQ, + TrivaBetween::NotAllowed, + ), + // :: + SyntaxKind::COLON2 => self.at_composite2( + n, + SyntaxKind::COLON, + SyntaxKind::COLON, + TrivaBetween::NotAllowed, + ), + // != + SyntaxKind::NEQ => self.at_composite2( + n, + SyntaxKind::BANG, + SyntaxKind::EQ, + TrivaBetween::NotAllowed, + ), + // <> + SyntaxKind::NEQB => self.at_composite2( + n, + SyntaxKind::L_ANGLE, + SyntaxKind::R_ANGLE, + TrivaBetween::NotAllowed, + ), + // is not + SyntaxKind::IS_NOT => self.at_composite2( + n, + SyntaxKind::IS_KW, + SyntaxKind::NOT_KW, + TrivaBetween::Allowed, + ), + // is null + SyntaxKind::IS_NULL => self.at_composite2( + n, + SyntaxKind::IS_KW, + SyntaxKind::NULL_KW, + TrivaBetween::Allowed, + ), + // not like + SyntaxKind::NOT_LIKE => self.at_composite2( + n, + SyntaxKind::NOT_KW, + SyntaxKind::LIKE_KW, + TrivaBetween::Allowed, + ), + // not in + SyntaxKind::NOT_IN => self.at_composite2( + n, + SyntaxKind::NOT_KW, + SyntaxKind::IN_KW, + TrivaBetween::Allowed, + ), + // at time zone + SyntaxKind::AT_TIME_ZONE => self.at_composite3( + n, + SyntaxKind::AT_KW, + SyntaxKind::TIME_KW, + SyntaxKind::ZONE_KW, + ), + // is distinct from + SyntaxKind::IS_DISTINCT_FROM => self.at_composite3( + n, + SyntaxKind::IS_KW, + SyntaxKind::DISTINCT_KW, + SyntaxKind::FROM_KW, + ), + // is not distinct from + SyntaxKind::IS_NOT_DISTINCT_FROM => self.at_composite4( + n, + SyntaxKind::IS_KW, + SyntaxKind::NOT_KW, + SyntaxKind::DISTINCT_KW, + SyntaxKind::FROM_KW, + ), + // similar to + SyntaxKind::SIMILAR_TO => self.at_composite2( + n, + SyntaxKind::SIMILAR_KW, + SyntaxKind::TO_KW, + TrivaBetween::Allowed, + ), + // https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS + // TODO: is this right? + SyntaxKind::OPERATOR_CALL => self.at_composite2( + n, + SyntaxKind::OPERATOR_KW, + SyntaxKind::L_PAREN, + TrivaBetween::Allowed, + ), + // <= + SyntaxKind::LTEQ => self.at_composite2( + n, + SyntaxKind::L_ANGLE, + SyntaxKind::EQ, + TrivaBetween::NotAllowed, + ), + // <= + SyntaxKind::GTEQ => self.at_composite2( + n, + SyntaxKind::R_ANGLE, + SyntaxKind::EQ, + TrivaBetween::NotAllowed, + ), + SyntaxKind::CUSTOM_OP => { + // TODO: is this right? + if self.at_ts(OPERATOR_FIRST) { + return true; + } + return false; + } + // TODO: we probably shouldn't be using a _ for this but be explicit for each type? + _ => self.inp.kind(self.pos + n) == kind, + } + } + + /// Returns the kind of the current token. + /// If parser has already reached the end of input, + /// the special `EOF` kind is returned. + #[must_use] + pub(crate) fn current(&self) -> SyntaxKind { + self.nth(0) + } + + /// Lookahead operation: returns the kind of the next nth + /// token. + #[must_use] + fn nth(&self, n: usize) -> SyntaxKind { + assert!(n <= 3); + + let steps = self.steps.get(); + assert!( + (steps as usize) < PARSER_STEP_LIMIT, + "the parser seems stuck" + ); + self.steps.set(steps + 1); + + self.inp.kind(self.pos + n) + } +} diff --git a/crates/squawk_parser/src/output.rs b/crates/squawk_parser/src/output.rs new file mode 100644 index 00000000..f310f7ad --- /dev/null +++ b/crates/squawk_parser/src/output.rs @@ -0,0 +1,150 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/master/crates/parser/src/output.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//! See [`Output`] + +use crate::SyntaxKind; + +/// Output of the parser -- a DFS traversal of a concrete syntax tree. +/// +/// Use the [`Output::iter`] method to iterate over traversal steps and consume +/// a syntax tree. +/// +/// In a sense, this is just a sequence of [`SyntaxKind`]-colored parenthesis +/// interspersed into the original [`crate::Input`]. The output is fundamentally +/// coordinated with the input and `n_input_tokens` refers to the number of +/// times [`crate::Input::push`] was called. +#[derive(Default)] +pub struct Output { + /// 32-bit encoding of events. If LSB is zero, then that's an index into the + /// error vector. Otherwise, it's one of the thee other variants, with data encoded as + /// + /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| + /// + event: Vec, + error: Vec, +} + +#[derive(Debug)] +pub(crate) enum Step<'a> { + Token { + kind: SyntaxKind, + n_input_tokens: u8, + }, + FloatSplit { + ends_in_dot: bool, + }, + Enter { + kind: SyntaxKind, + }, + Exit, + Error { + msg: &'a str, + }, +} + +impl Output { + const EVENT_MASK: u32 = 0b1; + const TAG_MASK: u32 = 0x0000_00F0; + const N_INPUT_TOKEN_MASK: u32 = 0x0000_FF00; + const KIND_MASK: u32 = 0xFFFF_0000; + + const ERROR_SHIFT: u32 = Self::EVENT_MASK.trailing_ones(); + const TAG_SHIFT: u32 = Self::TAG_MASK.trailing_zeros(); + const N_INPUT_TOKEN_SHIFT: u32 = Self::N_INPUT_TOKEN_MASK.trailing_zeros(); + const KIND_SHIFT: u32 = Self::KIND_MASK.trailing_zeros(); + + const TOKEN_EVENT: u8 = 0; + const ENTER_EVENT: u8 = 1; + const EXIT_EVENT: u8 = 2; + const SPLIT_EVENT: u8 = 3; + + pub(crate) fn iter(&self) -> impl Iterator> { + self.event.iter().map(|&event| { + if event & Self::EVENT_MASK == 0 { + return Step::Error { + msg: self.error[(event as usize) >> Self::ERROR_SHIFT].as_str(), + }; + } + let tag = ((event & Self::TAG_MASK) >> Self::TAG_SHIFT) as u8; + match tag { + Self::TOKEN_EVENT => { + let kind: SyntaxKind = + (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into(); + let n_input_tokens = + ((event & Self::N_INPUT_TOKEN_MASK) >> Self::N_INPUT_TOKEN_SHIFT) as u8; + Step::Token { + kind, + n_input_tokens, + } + } + Self::ENTER_EVENT => { + let kind: SyntaxKind = + (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into(); + Step::Enter { kind } + } + Self::EXIT_EVENT => Step::Exit, + Self::SPLIT_EVENT => Step::FloatSplit { + ends_in_dot: event & Self::N_INPUT_TOKEN_MASK != 0, + }, + _ => unreachable!(), + } + }) + } + + pub(crate) fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { + let e = ((kind as u16 as u32) << Self::KIND_SHIFT) + | ((n_tokens as u32) << Self::N_INPUT_TOKEN_SHIFT) + | Self::EVENT_MASK; + self.event.push(e) + } + + pub(crate) fn float_split_hack(&mut self, ends_in_dot: bool) { + let e = (Self::SPLIT_EVENT as u32) << Self::TAG_SHIFT + | ((ends_in_dot as u32) << Self::N_INPUT_TOKEN_SHIFT) + | Self::EVENT_MASK; + self.event.push(e); + } + + pub(crate) fn enter_node(&mut self, kind: SyntaxKind) { + let e = ((kind as u16 as u32) << Self::KIND_SHIFT) + | ((Self::ENTER_EVENT as u32) << Self::TAG_SHIFT) + | Self::EVENT_MASK; + self.event.push(e) + } + + pub(crate) fn leave_node(&mut self) { + let e = (Self::EXIT_EVENT as u32) << Self::TAG_SHIFT | Self::EVENT_MASK; + self.event.push(e) + } + + pub(crate) fn error(&mut self, error: String) { + let idx = self.error.len(); + self.error.push(error); + let e = (idx as u32) << Self::ERROR_SHIFT; + self.event.push(e); + } +} diff --git a/crates/squawk_parser/src/shortcuts.rs b/crates/squawk_parser/src/shortcuts.rs new file mode 100644 index 00000000..affe1547 --- /dev/null +++ b/crates/squawk_parser/src/shortcuts.rs @@ -0,0 +1,337 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/shortcuts.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::mem; + +use crate::{ + lexed_str::LexedStr, + output::{Output, Step}, + syntax_kind::SyntaxKind, +}; + +#[derive(Debug)] +pub enum StrStep<'a> { + Token { kind: SyntaxKind, text: &'a str }, + Enter { kind: SyntaxKind }, + Exit, + Error { msg: &'a str, pos: usize }, +} + +enum State { + PendingEnter, + Normal, + PendingExit, +} + +struct Builder<'a, 'b> { + lexed: &'a LexedStr<'a>, + pos: usize, + state: State, + sink: &'b mut dyn FnMut(StrStep<'_>), +} + +impl Builder<'_, '_> { + fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { + match mem::replace(&mut self.state, State::Normal) { + State::PendingEnter => unreachable!(), + State::PendingExit => (self.sink)(StrStep::Exit), + State::Normal => (), + } + self.eat_trivias(); + self.do_token(kind, n_tokens as usize); + } + + fn float_split(&mut self, has_pseudo_dot: bool) { + match mem::replace(&mut self.state, State::Normal) { + State::PendingEnter => unreachable!(), + State::PendingExit => (self.sink)(StrStep::Exit), + State::Normal => (), + } + self.eat_trivias(); + self.do_float_split(has_pseudo_dot); + } + + fn enter(&mut self, kind: SyntaxKind) { + match mem::replace(&mut self.state, State::Normal) { + State::PendingEnter => { + (self.sink)(StrStep::Enter { kind }); + // No need to attach trivias to previous node: there is no + // previous node. + return; + } + State::PendingExit => (self.sink)(StrStep::Exit), + State::Normal => (), + } + + let n_trivias = (self.pos..self.lexed.len()) + .take_while(|&it| self.lexed.kind(it).is_trivia()) + .count(); + let leading_trivias = self.pos..self.pos + n_trivias; + let n_attached_trivias = n_attached_trivias( + kind, + leading_trivias + .rev() + .map(|it| (self.lexed.kind(it), self.lexed.text(it))), + ); + self.eat_n_trivias(n_trivias - n_attached_trivias); + (self.sink)(StrStep::Enter { kind }); + self.eat_n_trivias(n_attached_trivias); + } + + fn exit(&mut self) { + match mem::replace(&mut self.state, State::PendingExit) { + State::PendingEnter => unreachable!(), + State::PendingExit => (self.sink)(StrStep::Exit), + State::Normal => (), + } + } + + fn eat_trivias(&mut self) { + while self.pos < self.lexed.len() { + let kind = self.lexed.kind(self.pos); + if !kind.is_trivia() { + break; + } + self.do_token(kind, 1); + } + } + + fn eat_n_trivias(&mut self, n: usize) { + for _ in 0..n { + let kind = self.lexed.kind(self.pos); + assert!(kind.is_trivia()); + self.do_token(kind, 1); + } + } + + fn do_token(&mut self, kind: SyntaxKind, n_tokens: usize) { + let text = &self.lexed.range_text(self.pos..self.pos + n_tokens); + self.pos += n_tokens; + (self.sink)(StrStep::Token { kind, text }); + } + + fn do_float_split(&mut self, has_pseudo_dot: bool) { + let text = &self.lexed.range_text(self.pos..self.pos + 1); + + match text.split_once('.') { + Some((left, right)) => { + assert!(!left.is_empty()); + (self.sink)(StrStep::Enter { + kind: SyntaxKind::NAME_REF, + }); + (self.sink)(StrStep::Token { + kind: SyntaxKind::INT_NUMBER, + text: left, + }); + (self.sink)(StrStep::Exit); + + // here we move the exit up, the original exit has been deleted in process + (self.sink)(StrStep::Exit); + + (self.sink)(StrStep::Token { + kind: SyntaxKind::DOT, + text: ".", + }); + + if has_pseudo_dot { + assert!(right.is_empty(), "{left}.{right}"); + self.state = State::Normal; + } else { + assert!(!right.is_empty(), "{left}.{right}"); + (self.sink)(StrStep::Enter { + kind: SyntaxKind::NAME_REF, + }); + (self.sink)(StrStep::Token { + kind: SyntaxKind::INT_NUMBER, + text: right, + }); + (self.sink)(StrStep::Exit); + + // the parser creates an unbalanced start node, we are required to close it here + self.state = State::PendingExit; + } + } + None => { + // illegal float literal which doesn't have dot in form (like 1e0) + // we should emit an error node here + (self.sink)(StrStep::Error { + msg: "illegal float literal", + pos: self.pos, + }); + (self.sink)(StrStep::Enter { + kind: SyntaxKind::ERROR, + }); + (self.sink)(StrStep::Token { + kind: SyntaxKind::FLOAT_NUMBER, + text, + }); + (self.sink)(StrStep::Exit); + + // move up + (self.sink)(StrStep::Exit); + + self.state = if has_pseudo_dot { + State::Normal + } else { + State::PendingExit + }; + } + } + + self.pos += 1; + } +} + +impl LexedStr<'_> { + pub fn to_input(&self) -> crate::Input { + let mut res = crate::Input::default(); + let mut was_joint = false; + for i in 0..self.len() { + let kind = self.kind(i); + if kind.is_trivia() { + was_joint = false; + // skip over any triva since the parser shouldn't have to deal + // with it + } + // else if kind == SyntaxKind::IDENT { + // let token_text = self.text(i); + // let contextual_kw = + // SyntaxKind::from_contextual_keyword(token_text).unwrap_or(SyntaxKind::IDENT); + // res.push_ident(contextual_kw); + // } + else { + if was_joint { + res.was_joint(); + } + res.push(kind); + // Tag the token as joint if it is float with a fractional part + // we use this jointness to inform the parser about what token split + // event to emit when we encounter a float literal in a field access + // if kind == SyntaxKind::FLOAT_NUMBER { + // if !self.text(i).ends_with('.') { + // res.was_joint(); + // } else { + // was_joint = false; + // } + // } else { + was_joint = true; + // } + } + } + res + } + + /// NB: only valid to call with Output from Reparser/TopLevelEntry. + pub fn intersperse_trivia(&self, output: &Output, sink: &mut dyn FnMut(StrStep<'_>)) -> bool { + let mut builder = Builder { + lexed: self, + pos: 0, + state: State::PendingEnter, + sink, + }; + + for event in output.iter() { + match event { + Step::Token { + kind, + n_input_tokens: n_raw_tokens, + } => builder.token(kind, n_raw_tokens), + Step::FloatSplit { + ends_in_dot: has_pseudo_dot, + } => builder.float_split(has_pseudo_dot), + Step::Enter { kind } => builder.enter(kind), + Step::Exit => builder.exit(), + Step::Error { msg } => { + let text_pos = builder.lexed.text_start(builder.pos); + (builder.sink)(StrStep::Error { msg, pos: text_pos }); + } + } + } + + match mem::replace(&mut builder.state, State::Normal) { + State::PendingExit => { + builder.eat_trivias(); + (builder.sink)(StrStep::Exit); + } + State::PendingEnter | State::Normal => unreachable!(), + } + + // is_eof? + builder.pos == builder.lexed.len() + } +} + +fn n_attached_trivias<'a>( + kind: SyntaxKind, + trivias: impl Iterator, +) -> usize { + match kind { + // CONST | ENUM | FN | IMPL | MACRO_CALL | MACRO_DEF | MACRO_RULES | MODULE | RECORD_FIELD + // | STATIC | STRUCT | TRAIT | TUPLE_FIELD | TYPE_ALIAS | UNION | USE | VARIANT + // | EXTERN_CRATE + SyntaxKind::CREATE_TABLE => { + let mut res = 0; + let mut trivias = trivias.enumerate().peekable(); + + while let Some((i, (kind, text))) = trivias.next() { + match kind { + SyntaxKind::WHITESPACE if text.contains("\n\n") => { + // we check whether the next token is a doc-comment + // and skip the whitespace in this case + if let Some((SyntaxKind::COMMENT, peek_text)) = + trivias.peek().map(|(_, pair)| pair) + { + if is_outer(peek_text) { + continue; + } + } + break; + } + SyntaxKind::COMMENT => { + if is_inner(text) { + break; + } + res = i + 1; + } + _ => (), + } + } + res + } + _ => 0, + } +} + +fn is_outer(text: &str) -> bool { + if text.starts_with("////") || text.starts_with("/***") { + return false; + } + text.starts_with("///") || text.starts_with("/**") +} + +fn is_inner(text: &str) -> bool { + text.starts_with("//!") || text.starts_with("/*!") +} diff --git a/crates/squawk_parser/src/snapshots/parser__test__alter_table_err.snap.new b/crates/squawk_parser/src/snapshots/parser__test__alter_table_err.snap.new new file mode 100644 index 00000000..aeedc020 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/parser__test__alter_table_err.snap.new @@ -0,0 +1,112 @@ +--- +source: crates/squawk_parser/src/test.rs +assertion_line: 88 +input_file: crates/squawk_parser/test_data/err/alter_table.sql +--- +SOURCE_FILE + COMMENT "-- missing alter_table" + WHITESPACE "\n" + ERROR + ADD_KW "add" + WHITESPACE " " + ERROR + COLUMN_KW "column" + WHITESPACE " " + ERROR + IDENT "foo" + WHITESPACE " " + ERROR + BOOLEAN_KW "boolean" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- mismatch options" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITALLY_DEFERRED_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + DEFERRED_KW "deferred" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg 18 only, via: https://www.depesz.com/2025/05/01/waiting-for-postgresql-18-allow-not-null-constraints-to-be-added-as-not-valid/" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "copy_2" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "id_not_null" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + NOT_KW "not" + WHITESPACE " " + ERROR + NULL_KW "null" + WHITESPACE " " + ERROR + IDENT "id" + WHITESPACE " " + ERROR + NOT_KW "not" + WHITESPACE " " + ERROR + VALID_KW "valid" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@23: expected command, found ADD_KW +ERROR@27: expected command, found COLUMN_KW +ERROR@34: expected command, found IDENT +ERROR@38: expected command, found BOOLEAN_KW +ERROR@134: constraint declared INITIALLY DEFERRED must be DEFERRABLE +ERROR@322: expected FOREIGN_KW +ERROR@322: expected KEY_KW +ERROR@322: expected column list +ERROR@322: expected REFERENCES_KW +ERROR@326: expected SEMICOLON +ERROR@327: expected command, found NULL_KW +ERROR@332: expected command, found IDENT +ERROR@335: expected command, found NOT_KW +ERROR@339: expected command, found VALID_KW diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_err.snap new file mode 100644 index 00000000..cba8687c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_err.snap @@ -0,0 +1,45 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/alter_aggregate.sql +--- +SOURCE_FILE + COMMENT "-- can't have out params in aggregates" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + IDENT "t" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + IDENT "u" + R_PAREN ")" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_ok.snap new file mode 100644 index 00000000..9a9da3be --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_aggregate_ok.snap @@ -0,0 +1,186 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_aggregate.sql +--- +SOURCE_FILE + COMMENT "-- star" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple_args" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "t" + R_PAREN ")" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- complex_args" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "x" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "y" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + R_PAREN ")" + WHITESPACE " \n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_order_by" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "x" + WHITESPACE " " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "y" + R_PAREN ")" + WHITESPACE " \n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- qualified_names" + WHITESPACE "\n" + ALTER_AGGREGATE_STMT + ALTER_KW "alter" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + IDENT "t" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "u" + R_PAREN ")" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "new_schema" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_collation_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_collation_ok.snap new file mode 100644 index 00000000..1c78e348 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_collation_ok.snap @@ -0,0 +1,103 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_collation.sql +--- +SOURCE_FILE + COMMENT "-- refresh" + WHITESPACE "\n" + ALTER_COLLATION_STMT + ALTER_KW "alter" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + REFRESH_KW "refresh" + WHITESPACE " " + VERSION_KW "version" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_COLLATION_STMT + ALTER_KW "alter" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_COLLATION_STMT + ALTER_KW "alter" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_COLLATION_STMT + ALTER_KW "alter" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_COLLATION_STMT + ALTER_KW "alter" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_conversion_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_conversion_ok.snap new file mode 100644 index 00000000..b11698be --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_conversion_ok.snap @@ -0,0 +1,106 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_conversion.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_CONVERSION_STMT + ALTER_KW "alter" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_CONVERSION_STMT + ALTER_KW "alter" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_CONVERSION_STMT + ALTER_KW "alter" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_CONVERSION_STMT + ALTER_KW "alter" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- qualified_name" + WHITESPACE "\n" + ALTER_CONVERSION_STMT + ALTER_KW "alter" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_database_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_database_ok.snap new file mode 100644 index 00000000..74281ab8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_database_ok.snap @@ -0,0 +1,285 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_database.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- tablespace" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- refresh" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + REFRESH_KW "refresh" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + VERSION_KW "version" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_param" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_option" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + IDENT "allow_connections" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- option_connection_limit" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- option_is_template" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + IDENT "is_template" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_multiple_options" + WHITESPACE "\n" + ALTER_DATABASE_STMT + ALTER_KW "alter" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + IDENT "allow_connections" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE " " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + IDENT "is_template" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_default_privileges_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_default_privileges_ok.snap new file mode 100644 index 00000000..8e2a9918 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_default_privileges_ok.snap @@ -0,0 +1,948 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_default_privileges.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "s2" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "s3" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + SESSION_USER_KW "session_user" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grant_tables" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + INSERT_KW "insert" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "public" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + SESSION_USER_KW "session_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + TRUNCATE_KW "truncate" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + IDENT "maintain" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + INSERT_KW "insert" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + COMMA "," + WHITESPACE " " + DELETE_KW "delete" + COMMA "," + WHITESPACE " " + TRUNCATE_KW "truncate" + COMMA "," + WHITESPACE " " + REFERENCES_KW "references" + COMMA "," + WHITESPACE " " + TRIGGER_KW "trigger" + COMMA "," + WHITESPACE " " + IDENT "maintain" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grant_sequences" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + COMMA "," + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "u" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + SESSION_USER_KW "session_user" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grant_functions" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FUNCTIONS_KW "functions" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ROUTINES_KW "routines" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ROUTINES_KW "routines" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grant_types" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPES_KW "types" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPES_KW "types" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "u" + COMMA "," + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grant_schemas" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + COMMA "," + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMAS_KW "schemas" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMAS_KW "schemas" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "u" + COMMA "," + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- revoke_tables" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + INSERT_KW "insert" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + COMMA "," + WHITESPACE " " + DELETE_KW "delete" + COMMA "," + WHITESPACE " " + TRUNCATE_KW "truncate" + COMMA "," + WHITESPACE " " + REFERENCES_KW "references" + COMMA "," + WHITESPACE " " + TRIGGER_KW "trigger" + COMMA "," + WHITESPACE " " + IDENT "maintain" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- revoke_sequences" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "usage" + COMMA "," + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- revoke_functions" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FUNCTIONS_KW "functions" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ROUTINES_KW "routines" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- revoke_types" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPES_KW "types" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPES_KW "types" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- revoke_schemas" + WHITESPACE "\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "usage" + COMMA "," + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMAS_KW "schemas" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_DEFAULT_PRIVILEGES_STMT + ALTER_KW "alter" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMAS_KW "schemas" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_domain_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_domain_ok.snap new file mode 100644 index 00000000..11d539ac --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_domain_ok.snap @@ -0,0 +1,365 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_domain.sql +--- +SOURCE_FILE + COMMENT "-- set_default" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + SET_DEFAULT + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + INT_NUMBER "42" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_default" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + DROP_DEFAULT + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_not_null" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + SET_NOT_NULL + SET_KW "set" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_not_null" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + DROP_NOT_NULL + DROP_KW "drop" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_constraint" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + VALUE_KW "value" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + VALUE_KW "value" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + R_PAREN ")" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + VALID_KW "valid" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_constraint" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_constraint" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + RENAME_CONSTRAINT + RENAME_KW "rename" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- validate_constraint" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + VALIDATE_CONSTRAINT + VALIDATE_KW "validate" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_to" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + RENAME_TO + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_DOMAIN_STMT + ALTER_KW "alter" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE "\n " + SET_SCHEMA + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_event_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_event_trigger_ok.snap new file mode 100644 index 00000000..eadcd101 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_event_trigger_ok.snap @@ -0,0 +1,127 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_event_trigger.sql +--- +SOURCE_FILE + COMMENT "-- disable" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_KW "disable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- enable" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_KW "enable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- enable_replica" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_KW "enable" + WHITESPACE " " + REPLICA_KW "replica" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- enable_always" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_KW "enable" + WHITESPACE " " + ALWAYS_KW "always" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_current_role" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_EVENT_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_extension_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_extension_ok.snap new file mode 100644 index 00000000..06907ecf --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_extension_ok.snap @@ -0,0 +1,2487 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_extension.sql +--- +SOURCE_FILE + COMMENT "-- update_to" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + UPDATE_KW "update" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + JSON_KW "json" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'foo'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_access_method" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_aggregate" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + WHITESPACE " " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "b" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "c" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_cast" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_collation" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_conversion" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_domain" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_event_trigger" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_foreign_data_wrapper" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_foreign_table" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_function" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_materialized_view" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_operator" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + COMMA "," + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_operator_class" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + NAME_REF + IDENT "o" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + NAME_REF + IDENT "o" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_operator_family" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + NAME_REF + IDENT "o" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + NAME_REF + IDENT "o" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_language" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_procedure" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_routine" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_sequence" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_table" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_text_search_configuration" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_text_search_dictionary" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_text_search_parser" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_text_search_template" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_transform" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "type_name" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "type_name" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_type" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_view" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_extension" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_publication" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_schema" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_server" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_database" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_index" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_statistics" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_role" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_subscription" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_drop_tablespace" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_EXTENSION_STMT + ALTER_KW "alter" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_err.snap new file mode 100644 index 00000000..cf2c84f2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_err.snap @@ -0,0 +1,22 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/alter_foreign_data_wrapper.sql +--- +SOURCE_FILE + COMMENT "-- missing option" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@46: Missing alter foreign data wrapper option or action. diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_ok.snap new file mode 100644 index 00000000..e0df5bff --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_data_wrapper_ok.snap @@ -0,0 +1,246 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_foreign_data_wrapper.sql +--- +SOURCE_FILE + COMMENT "-- handler" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "h" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- no_handler" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + HANDLER_KW "handler" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- validator" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + VALIDATOR_KW "validator" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- no_validator" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + VALIDATOR_KW "validator" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- options" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + ADD_KW "add" + WHITESPACE " " + NAME + IDENT "o" + WHITESPACE " " + LITERAL + STRING "'v'" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME + IDENT "o" + WHITESPACE " " + LITERAL + STRING "'v'" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + NAME + IDENT "o" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "h" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + HANDLER_KW "handler" + WHITESPACE "\n " + VALIDATOR_KW "validator" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + VALIDATOR_KW "validator" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + ADD_KW "add" + WHITESPACE " " + NAME + IDENT "o" + WHITESPACE " " + LITERAL + STRING "'v'" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME + IDENT "o" + WHITESPACE " " + LITERAL + STRING "''" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + NAME + IDENT "d" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_FOREIGN_DATA_WRAPPER_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "w" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_table_ok.snap new file mode 100644 index 00000000..177500d6 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_foreign_table_ok.snap @@ -0,0 +1,1485 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_foreign_table.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- only_and_asterisk" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_column" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_add_column" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_drop_column" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_column_type" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_TYPE + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_TYPE + SET_KW "set" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set_default" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_DEFAULT + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_DEFAULT + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_drop_default" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_DEFAULT + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_DEFAULT + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_not_null" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_NOT_NULL + DROP_KW "drop" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_NOT_NULL + SET_KW "set" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set_statistics" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_reset" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set_storage" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "plain" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + EXTERNAL_KW "external" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "extended" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "main" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_options" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS_LIST + OPTIONS_KW "options" + L_PAREN "(" + NAME + IDENT "b" + WHITESPACE " " + LITERAL + STRING "''" + COMMA "," + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + LITERAL + STRING "'c'" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME + IDENT "x" + WHITESPACE " " + LITERAL + STRING "''" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + NAME + IDENT "x" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS_LIST + OPTIONS_KW "options" + L_PAREN "(" + SET_KW "set" + WHITESPACE " " + NAME + IDENT "x" + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_add_table_constraint" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + NOT_VALID + NOT_KW "not" + WHITESPACE " " + VALID_KW "valid" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_validate_constraint" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + VALIDATE_CONSTRAINT + VALIDATE_KW "validate" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_drop_constraint" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_disable_trigger" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + USER_KW "user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_enable_replica_trigger" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ENABLE_REPLICA_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + REPLICA_KW "replica" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_enable_always_trigger" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ENABLE_ALWAYS_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set_without_oids" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + SET_WITHOUT_OIDS + SET_KW "set" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + OIDS_KW "oids" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_inherit" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + INHERIT + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + INHERIT + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_no_inherit" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + NO_INHERIT + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + NO_INHERIT + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_owner_to" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple_actions" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + CASCADE_KW "cascade" + COMMA "," + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "e" + WHITESPACE " " + SET_NOT_NULL + SET_KW "set" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_owner" + WHITESPACE "\n" + ALTER_FOREIGN_TABLE_STMT + ALTER_KW "alter" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_function_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_function_ok.snap new file mode 100644 index 00000000..b6aa3ac2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_function_ok.snap @@ -0,0 +1,357 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_function.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + STABLE_KW "stable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "g" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "g" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_with_params" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + FUNC_OPTION_LIST + STRICT_FUNC_OPTION + STRICT_KW "strict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple_actions" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " \n " + FUNC_OPTION_LIST + STRICT_FUNC_OPTION + CALLED_KW "called" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + INPUT_KW "input" + WHITESPACE "\n " + STRICT_FUNC_OPTION + RETURNS_KW "returns" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + INPUT_KW "input" + WHITESPACE "\n " + STRICT_FUNC_OPTION + STRICT_KW "strict" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + IMMUTABLE_KW "immutable" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + STABLE_KW "stable" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + VOLATILE_KW "volatile" + WHITESPACE "\n " + LEAKPROOF_FUNC_OPTION + NOT_KW "not" + WHITESPACE " " + LEAKPROOF_KW "leakproof" + WHITESPACE "\n " + LEAKPROOF_FUNC_OPTION + LEAKPROOF_KW "leakproof" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "unsafe" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "restricted" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "safe" + WHITESPACE "\n " + COST_FUNC_OPTION + COST_KW "cost" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + ROWS_FUNC_OPTION + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + SUPPORT_FUNC_OPTION + SUPPORT_KW "support" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_FUNCTION_STMT + ALTER_KW "alter" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_group_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_group_ok.snap new file mode 100644 index 00000000..921e947c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_group_ok.snap @@ -0,0 +1,157 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_group.sql +--- +SOURCE_FILE + COMMENT "-- add" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "g" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_multiple" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "g" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "v" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "w" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "g" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_multiple" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "g" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "v" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "w" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "g" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_role" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_user" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- session_user" + WHITESPACE "\n" + ALTER_GROUP_STMT + ALTER_KW "alter" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + SESSION_USER_KW "session_user" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_index_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_index_ok.snap new file mode 100644 index 00000000..f31a1440 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_index_ok.snap @@ -0,0 +1,457 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_index.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "j" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "j" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_tablespace" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_params" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + EQ "=" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + EQ "=" + LITERAL + STRING "'v'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_params" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- attach" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + ATTACH_KW "attach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + ATTACH_KW "attach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_column" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_tablespace" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_INDEX_STMT + ALTER_KW "alter" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " \n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + IDENT "s" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "n" + WHITESPACE "\n " + NOWAIT_KW "nowait" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_language_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_language_ok.snap new file mode 100644 index 00000000..0d6f05b3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_language_ok.snap @@ -0,0 +1,75 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_language.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_LANGUAGE_STMT + ALTER_KW "alter" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "y" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_LANGUAGE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "y" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_LANGUAGE_STMT + ALTER_KW "alter" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_LANGUAGE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_large_object_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_large_object_ok.snap new file mode 100644 index 00000000..3780f819 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_large_object_ok.snap @@ -0,0 +1,43 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_large_object.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_LARGE_OBJECT_STMT + ALTER_KW "alter" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "12345" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_role" + WHITESPACE "\n" + ALTER_LARGE_OBJECT_STMT + ALTER_KW "alter" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "12345" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_materialized_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_materialized_view_ok.snap new file mode 100644 index 00000000..867336e8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_materialized_view_ok.snap @@ -0,0 +1,724 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_materialized_view.sql +--- +SOURCE_FILE + COMMENT "-- rename_view" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_column" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " \n " + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends_extension" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_tablespace" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + IDENT "u" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME + IDENT "n" + WHITESPACE " " + NOWAIT_KW "nowait" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_alter_col_stats" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " \n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PREFIX_EXPR + MINUS "-" + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_alter_col_set" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "n_distinct" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.0" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_alter_col_reset" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "n_distinct" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "n_distinct" + COMMA "," + WHITESPACE " " + NAME + IDENT "n_distinct_inherited" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_alter_col_storage" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "plain" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + EXTERNAL_KW "external" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "extended" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "main" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " \n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_alter_col_compression" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_COMPRESSION + SET_KW "set" + WHITESPACE " " + COMPRESSION_KW "compression" + WHITESPACE " " + IDENT "pglz" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_COMPRESSION + SET_KW "set" + WHITESPACE " " + COMPRESSION_KW "compression" + WHITESPACE " " + IDENT "pglz" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_cluster" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + DISABLE_CLUSTER + CLUSTER_KW "cluster" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- action_set_without_cluster" + WHITESPACE "\n" + ALTER_MATERIALIZED_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE "\n " + SET_WITHOUT_CLUSTER + SET_KW "set" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + CLUSTER_KW "cluster" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_class_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_class_ok.snap new file mode 100644 index 00000000..445f8f0b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_class_ok.snap @@ -0,0 +1,139 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_operator_class.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_OPERATOR_CLASS_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "m" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_OPERATOR_CLASS_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "m" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_OPERATOR_CLASS_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "m" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_OPERATOR_CLASS_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "m" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_OPERATOR_CLASS_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "m" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_family_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_family_ok.snap new file mode 100644 index 00000000..5bdd8bc5 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_family_ok.snap @@ -0,0 +1,687 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_operator_family.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_op_for_search" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + SEARCH_KW "search" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_op_for_order" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_func" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_func_with_params" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + ADD_KW "add" + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "a" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_op" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_op_single_param" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_func" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_func_single_param" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_multiple" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_OPERATOR_FAMILY_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_ok.snap new file mode 100644 index 00000000..72f6391e --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_operator_ok.snap @@ -0,0 +1,218 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_operator.sql +--- +SOURCE_FILE + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_OPERATOR_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + DOT "." + PATH_SEGMENT + PLUS "+" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + R_PAREN ")" + WHITESPACE " \n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_OPERATOR_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + L_PAREN "(" + NONE_KW "none" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- options" + WHITESPACE "\n" + ALTER_OPERATOR_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + AMP "&" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bool" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bool" + R_PAREN ")" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + RESTRICT_KW "restrict" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + COMMA "," + WHITESPACE "\n " + NAME + JOIN_KW "join" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "j" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "commutator" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "negator" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "hashes" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "enabled" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "merges" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "enabled" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- none_options" + WHITESPACE "\n" + ALTER_OPERATOR_STMT + ALTER_KW "alter" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PERCENT "%" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " \n " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + RESTRICT_KW "restrict" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NONE_KW "none" + COMMA "," + WHITESPACE " " + NAME + JOIN_KW "join" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NONE_KW "none" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_policy_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_policy_ok.snap new file mode 100644 index 00000000..25006cf8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_policy_ok.snap @@ -0,0 +1,185 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_policy.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- to_role" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- to_multiple_roles" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + IDENT "public" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using_expr" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_check" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "d" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ALTER_POLICY_STMT + ALTER_KW "alter" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + IDENT "s" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "d" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_procedure_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_procedure_ok.snap new file mode 100644 index 00000000..56d25f92 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_procedure_ok.snap @@ -0,0 +1,402 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_procedure.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "p" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- security" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE " \n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- actions" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "z" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_param" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_param" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + FUNC_OPTION_LIST + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PROCEDURE_STMT + ALTER_KW "alter" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_publication_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_publication_ok.snap new file mode 100644 index 00000000..4601fec8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_publication_ok.snap @@ -0,0 +1,397 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_publication.sql +--- +SOURCE_FILE + COMMENT "-- add_table" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + WHITESPACE " " + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_tables_in_schema" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + CURRENT_SCHEMA_KW "current_schema" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_table" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + WHITESPACE " " + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_parameters" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "param1" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param2" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + VALUE_KW "value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_table" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + WHITESPACE " " + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_PUBLICATION_STMT + ALTER_KW "alter" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_role_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_role_ok.snap new file mode 100644 index 00000000..f1aba2db --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_role_ok.snap @@ -0,0 +1,278 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_role.sql +--- +SOURCE_FILE + COMMENT "-- with_options" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + IDENT "superuser" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_options" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + IDENT "superuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "createdb" + WHITESPACE "\n " + IDENT "nocreatedb" + WHITESPACE "\n " + IDENT "createrole" + WHITESPACE "\n " + IDENT "nocreaterole" + WHITESPACE "\n " + INHERIT_KW "inherit" + WHITESPACE "\n " + IDENT "noinherit" + WHITESPACE "\n " + IDENT "login" + WHITESPACE "\n " + IDENT "nologin" + WHITESPACE "\n " + IDENT "replication" + WHITESPACE "\n " + IDENT "noreplication" + WHITESPACE "\n " + IDENT "bypassrls" + WHITESPACE "\n " + IDENT "nobypassrls" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + ENCRYPTED_KW "encrypted" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + VALID_KW "valid" + WHITESPACE " " + UNTIL_KW "until" + WHITESPACE " " + LITERAL + STRING "'2042-02-22'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "newname" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_config" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_config_from_current" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_config" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_all" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- in_database" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "param" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using_current_user" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + IDENT "nologin" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- for_all_roles" + WHITESPACE "\n" + ALTER_ROLE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_routine_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_routine_ok.snap new file mode 100644 index 00000000..dc5bd21d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_routine_ok.snap @@ -0,0 +1,320 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_routine.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + STABLE_KW "stable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- no_depends" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_params" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n " + FUNC_OPTION_LIST + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "safe" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_actions" + WHITESPACE "\n" + ALTER_ROUTINE_STMT + ALTER_KW "alter" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE "\n " + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + IMMUTABLE_KW "immutable" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + STABLE_KW "stable" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + VOLATILE_KW "volatile" + WHITESPACE "\n " + LEAKPROOF_FUNC_OPTION + NOT_KW "not" + WHITESPACE " " + LEAKPROOF_KW "leakproof" + WHITESPACE "\n " + LEAKPROOF_FUNC_OPTION + LEAKPROOF_KW "leakproof" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "unsafe" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "restricted" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "safe" + WHITESPACE "\n " + COST_FUNC_OPTION + COST_KW "cost" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + ROWS_FUNC_OPTION + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + RESET_FUNC_OPTION + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_rule_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_rule_ok.snap new file mode 100644 index 00000000..868d803b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_rule_ok.snap @@ -0,0 +1,60 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_rule.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_RULE_STMT + ALTER_KW "alter" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_schema" + WHITESPACE "\n" + ALTER_RULE_STMT + ALTER_KW "alter" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + SCHEMA_KW "schema" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_schema_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_schema_ok.snap new file mode 100644 index 00000000..299d7d7d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_schema_ok.snap @@ -0,0 +1,55 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_schema.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_SCHEMA_STMT + ALTER_KW "alter" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_SCHEMA_STMT + ALTER_KW "alter" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SCHEMA_STMT + ALTER_KW "alter" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_err.snap new file mode 100644 index 00000000..7654db48 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_err.snap @@ -0,0 +1,20 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/alter_sequence.sql +--- +SOURCE_FILE + COMMENT "-- missing option" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@34: expected ALTER SEQUENCE option diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_ok.snap new file mode 100644 index 00000000..8bcc4200 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_sequence_ok.snap @@ -0,0 +1,229 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_sequence.sql +--- +SOURCE_FILE + COMMENT "-- full" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE "\n " + INCREMENT_KW "increment" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE "\n " + MINVALUE_KW "minvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MINVALUE_KW "minvalue" + WHITESPACE "\n " + MAXVALUE_KW "maxvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MAXVALUE_KW "maxvalue" + WHITESPACE "\n " + START_KW "start" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + START_KW "start" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + RESTART_KW "restart" + WHITESPACE "\n " + RESTART_KW "restart" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + RESTART_KW "restart" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + CACHE_KW "cache" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + CYCLE_KW "cycle" + WHITESPACE "\n " + CYCLE_KW "cycle" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NONE_KW "none" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_logged" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + LOGGED_KW "logged" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + UNLOGGED_KW "unlogged" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_SEQUENCE_STMT + ALTER_KW "alter" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE "\n " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "x" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_err.snap new file mode 100644 index 00000000..6fd6200f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_err.snap @@ -0,0 +1,18 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/alter_server.sql +--- +SOURCE_FILE + COMMENT "-- missing option" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@32: expected ALTER SERVER option diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_ok.snap new file mode 100644 index 00000000..2b8a7f5d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_server_ok.snap @@ -0,0 +1,105 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_server.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + VERSION_KW "version" + WHITESPACE " " + LITERAL + STRING "'v1'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + VERSION_KW "version" + WHITESPACE " " + LITERAL + STRING "'v1'" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + ADD_KW "add" + WHITESPACE " " + NAME + IDENT "o" + WHITESPACE " " + LITERAL + STRING "'val'" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + NAME + IDENT "p" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_SERVER_STMT + ALTER_KW "alter" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_statistics_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_statistics_ok.snap new file mode 100644 index 00000000..cfbd6c0d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_statistics_ok.snap @@ -0,0 +1,123 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_statistics.sql +--- +SOURCE_FILE + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- statistics_value" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_STATISTICS_STMT + ALTER_KW "alter" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_subscription_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_subscription_ok.snap new file mode 100644 index 00000000..bfe56cab --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_subscription_ok.snap @@ -0,0 +1,353 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_subscription.sql +--- +SOURCE_FILE + COMMENT "-- connection" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + CONNECTION_KW "connection" + WHITESPACE " " + LITERAL + STRING "'host=localhost port=5432'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_publication" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + COMMA "," + WHITESPACE " " + NAME + IDENT "q" + COMMA "," + WHITESPACE " " + NAME + IDENT "r" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_publication" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_publication" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- refresh" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + REFRESH_KW "refresh" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "copy_data" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- enable" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + ENABLE_KW "enable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- disable" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + DISABLE_KW "disable" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_parameters" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "slot_name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'new_slot'" + COMMA "," + WHITESPACE " " + NAME + IDENT "synchronous_commit" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'off'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- skip" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + SKIP_KW "skip" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "lsn" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'0/12345678'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_SUBSCRIPTION_STMT + ALTER_KW "alter" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_system_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_system_ok.snap new file mode 100644 index 00000000..5ebb0c3c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_system_ok.snap @@ -0,0 +1,162 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_system.sql +--- +SOURCE_FILE + COMMENT "-- set_to" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'v'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_equals" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'v'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'v'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_multiple" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'v1'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'v2'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'v3'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_default" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_param" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_all" + WHITESPACE "\n" + ALTER_SYSTEM_STMT + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_err.snap new file mode 100644 index 00000000..f8a94c59 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_err.snap @@ -0,0 +1,111 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/alter_table.sql +--- +SOURCE_FILE + COMMENT "-- missing alter_table" + WHITESPACE "\n" + ERROR + ADD_KW "add" + WHITESPACE " " + ERROR + COLUMN_KW "column" + WHITESPACE " " + ERROR + IDENT "foo" + WHITESPACE " " + ERROR + BOOLEAN_KW "boolean" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- mismatch options" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITALLY_DEFERRED_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + DEFERRED_KW "deferred" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg 18 only, via: https://www.depesz.com/2025/05/01/waiting-for-postgresql-18-allow-not-null-constraints-to-be-added-as-not-valid/" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "copy_2" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "id_not_null" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + NOT_KW "not" + WHITESPACE " " + ERROR + NULL_KW "null" + WHITESPACE " " + ERROR + IDENT "id" + WHITESPACE " " + ERROR + NOT_KW "not" + WHITESPACE " " + ERROR + VALID_KW "valid" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@23: expected command, found ADD_KW +ERROR@27: expected command, found COLUMN_KW +ERROR@34: expected command, found IDENT +ERROR@38: expected command, found BOOLEAN_KW +ERROR@134: constraint declared INITIALLY DEFERRED must be DEFERRABLE +ERROR@322: expected FOREIGN_KW +ERROR@322: expected KEY_KW +ERROR@322: expected column list +ERROR@322: expected REFERENCES_KW +ERROR@326: expected SEMICOLON +ERROR@327: expected command, found NULL_KW +ERROR@332: expected command, found IDENT +ERROR@335: expected command, found NOT_KW +ERROR@339: expected command, found VALID_KW diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_ok.snap new file mode 100644 index 00000000..50599dfe --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_ok.snap @@ -0,0 +1,3622 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_table.sql +--- +SOURCE_FILE + COMMENT "-- add column" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "description" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- change column data type" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "price" + WHITESPACE " " + SET_TYPE + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- alter_constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + DEFERRABLE_CONSTRAINT_OPTION + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_CONSTRAINT + ALTER_KW "alter" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITIALLY_IMMEDIATE_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + IMMEDIATE_KW "immediate" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- validate_constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + VALIDATE_CONSTRAINT + VALIDATE_KW "validate" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- change column default" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "price" + WHITESPACE " " + SET_DEFAULT + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "7.77" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column default" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "price" + WHITESPACE " " + DROP_DEFAULT + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- alter_column" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_TYPE + SET_KW "set" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"foo\"" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_TYPE + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_DEFAULT + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_DEFAULT + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_NOT_NULL + SET_KW "set" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_NOT_NULL + DROP_KW "drop" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_EXPRESSION + DROP_KW "drop" + WHITESPACE " " + EXPRESSION_KW "expression" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_EXPRESSION + DROP_KW "drop" + WHITESPACE " " + EXPRESSION_KW "expression" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + ADD_GENERATED + ADD_KW "add" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + ADD_GENERATED + ADD_KW "add" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + ADD_GENERATED + ADD_KW "add" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + SEQUENCE_OPTION_LIST + L_PAREN "(" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_KW "name" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + CYCLE_KW "cycle" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_GENERATED_OPTIONS + SET_GENERATED + SET_KW "set" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + SET_SEQUENCE_OPTION + SET_KW "set" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_KW "name" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTART + RESTART_KW "restart" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE " \n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_GENERATED_OPTIONS + SET_GENERATED + SET_KW "set" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + SET_SEQUENCE_OPTION + SET_KW "set" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_KW "name" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTART + RESTART_KW "restart" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE " \n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_IDENTITY + DROP_KW "drop" + WHITESPACE " " + IDENTITY_KW "identity" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + DROP_IDENTITY + DROP_KW "drop" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STATISTICS + SET_KW "set" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME + IDENT "buzz" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME + IDENT "buzz" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + RESET_OPTIONS + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "p" + DOT "." + NAME + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME + IDENT "buzz" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_OPTIONS + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME + IDENT "z" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + NAME + IDENT "w" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + NAME + JSON_KW "json" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "plain" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + EXTERNAL_KW "external" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "extended" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + IDENT "main" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_STORAGE + SET_KW "set" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_COMPRESSION + SET_KW "set" + WHITESPACE " " + COMPRESSION_KW "compression" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_COMPRESSION + SET_KW "set" + WHITESPACE " " + COMPRESSION_KW "compression" + WHITESPACE " " + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_GENERATED_OPTIONS + RESTART + RESTART_KW "restart" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- inherit" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INHERIT + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + NO_INHERIT + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "some_name" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column not null constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "product_no" + WHITESPACE " " + DROP_NOT_NULL + DROP_KW "drop" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove constraint if exists" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "some_name" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_CONSTRAINT + DROP_KW "drop" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- disable_trigger" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_TRIGGER + DISABLE_KW "disable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + USER_KW "user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- enable_trigger" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + USER_KW "user" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_REPLICA_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + REPLICA_KW "replica" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_ALWAYS_TRIGGER + ENABLE_KW "enable" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- replica_identity" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + REPLICA_IDENTITY + REPLICA_KW "replica" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + REPLICA_IDENTITY + REPLICA_KW "replica" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + REPLICA_IDENTITY + REPLICA_KW "replica" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + FULL_KW "full" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + REPLICA_IDENTITY + REPLICA_KW "replica" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rule_enable_disable" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_RULE + DISABLE_KW "disable" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_RULE + ENABLE_KW "enable" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_REPLICA_RULE + ENABLE_KW "enable" + WHITESPACE " " + REPLICA_KW "replica" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_ALWAYS_RULE + ENABLE_KW "enable" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- row_level_security" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_RLS + DISABLE_KW "disable" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SECURITY_KW "security" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ENABLE_RLS + ENABLE_KW "enable" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SECURITY_KW "security" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + FORCE_RLS + FORCE_KW "force" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SECURITY_KW "security" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + NO_FORCE_RLS + NO_KW "no" + WHITESPACE " " + FORCE_KW "force" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SECURITY_KW "security" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- cluster" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DISABLE_CLUSTER + CLUSTER_KW "cluster" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_WITHOUT_CLUSTER + SET_KW "set" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + CLUSTER_KW "cluster" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_WITHOUT_OIDS + SET_KW "set" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + OIDS_KW "oids" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- access_method" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_ACCESS_METHOD + SET_KW "set" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_LOGGED + SET_KW "set" + WHITESPACE " " + LOGGED_KW "logged" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_UNLOGGED + SET_KW "set" + WHITESPACE " " + UNLOGGED_KW "unlogged" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- of_type" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + OF_TYPE + OF_KW "of" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + NOT_OF + NOT_KW "not" + WHITESPACE " " + OF_KW "of" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "description" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "description" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add column not null constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IDENT "product_no" + WHITESPACE " " + SET_NOT_NULL + SET_KW "set" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi constraints" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_COLUMN + ADD_KW "add" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "description" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "description" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_TYPE + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'UTC'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove_column" + WHITESPACE "\n" + COMMENT "-- remove column" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "description" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column cascade" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "description" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column restrict" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column concise" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + NAME_REF + IDENT "description" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- remove column if exists" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DROP_COLUMN + DROP_KW "drop" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "description" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- add table_constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + NAME_KW "name" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + UNIQUE_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "some_name" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "product_no" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_INCLUDE_CLAUSE + INCLUDE_KW "include" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " \n " + CONSTRAINT_INDEX_TABLESPACE + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + EQ "=" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + IDENT "tsrange" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_INDEX_METHOD + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "gist" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + EQ "=" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + IDENT "tsrange" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "d" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'active'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + MATCH_KW "match" + WHITESPACE " " + FULL_KW "full" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + MATCH_KW "match" + WHITESPACE " " + SIMPLE_KW "simple" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + L_PAREN "(" + NAME_REF + IDENT "e" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "f" + R_PAREN ")" + WHITESPACE " " + MATCH_KW "match" + WHITESPACE " " + FULL_KW "full" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + ACTION_KW "action" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + ACTION_KW "action" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "product_group_id" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "product_groups" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_constraint_using_index" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + USING_INDEX + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + USING_INDEX + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + UNIQUE_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + USING_INDEX + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + USING_INDEX + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not valid check" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "foo_not_null" + WHITESPACE "\n " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "\"foo\"" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + NULL_KW "null" + R_PAREN ")" + WHITESPACE " " + NOT_VALID + NOT_KW "not" + WHITESPACE " " + VALID_KW "valid" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- rename column" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + RENAME_COLUMN + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "product_no" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "product_number" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + RENAME_COLUMN + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + WHITESPACE " \n" + RENAME_COLUMN + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename table" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + RENAME_TABLE + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "items" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + RENAME_TABLE + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename constraint" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_CONSTRAINT + RENAME_KW "rename" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_SCHEMA + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set tablespace" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + SET_TABLESPACE + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set tablespace all" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " \n" + SET_TABLESPACE + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + NOWAIT_KW "nowait" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set tablespace owned by" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n" + SET_TABLESPACE + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "buz" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_TABLESPACE + SET_KW "set" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_table_owner" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "table_name" + WHITESPACE " " + OWNER_TO + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "new_owner" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- default" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ATTACH_PARTITION + ATTACH_KW "attach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + NAME_REF + IDENT "f" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partition spec" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ATTACH_PARTITION + ATTACH_KW "attach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + NAME_REF + IDENT "f" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple_actions" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + NOT_OF + NOT_KW "not" + WHITESPACE " " + OF_KW "of" + COMMA "," + WHITESPACE " " + NOT_OF + NOT_KW "not" + WHITESPACE " " + OF_KW "of" + COMMA "," + WHITESPACE " " + SET_LOGGED + SET_KW "set" + WHITESPACE " " + LOGGED_KW "logged" + COMMA "," + WHITESPACE " " + SET_UNLOGGED + SET_KW "set" + WHITESPACE " " + UNLOGGED_KW "unlogged" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from pg docs" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "ALTER" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "transactions" + WHITESPACE "\n " + ADD_COLUMN + ADD_KW "ADD" + WHITESPACE " " + COLUMN_KW "COLUMN" + WHITESPACE " " + NAME_REF + IDENT "status" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "30" + R_PAREN ")" + WHITESPACE " " + DEFAULT_CONSTRAINT + DEFAULT_KW "DEFAULT" + WHITESPACE " " + LITERAL + STRING "'old'" + COMMA "," + WHITESPACE "\n " + ALTER_COLUMN + ALTER_KW "ALTER" + WHITESPACE " " + COLUMN_KW "COLUMN" + WHITESPACE " " + IDENT "status" + WHITESPACE " " + SET_DEFAULT + SET_KW "SET" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + STRING "'current'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DETACH_PARTITION + DETACH_KW "detach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- concurrently" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DETACH_PARTITION + DETACH_KW "detach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + NAME_REF + IDENT "f" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- finalize" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DETACH_PARTITION + DETACH_KW "detach" + WHITESPACE " " + PARTITION_KW "partition" + WHITESPACE " " + NAME_REF + IDENT "f" + WHITESPACE " " + FINALIZE_KW "finalize" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_pg17_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_pg17_ok.snap new file mode 100644 index 00000000..c7fe3fa8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_table_pg17_ok.snap @@ -0,0 +1,104 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_table_pg17.sql +--- +SOURCE_FILE + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_COLUMN + ALTER_KW "alter" + WHITESPACE " " + IDENT "c" + WHITESPACE " " + SET_EXPRESSION + SET_KW "set" + WHITESPACE " " + EXPRESSION_KW "expression" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_ACCESS_METHOD + SET_KW "set" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TABLE + ALTER_KW "alter" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_CONSTRAINT + ADD_KW "add" + WHITESPACE " " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE " " + MATCH_KW "match" + WHITESPACE " " + PARTIAL_KW "partial" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_tablespace_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_tablespace_ok.snap new file mode 100644 index 00000000..79ce0f93 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_tablespace_ok.snap @@ -0,0 +1,185 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_tablespace.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_option" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_multiple_options" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "o1" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "v1" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o2" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "v2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_option" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_multiple_options" + WHITESPACE "\n" + ALTER_TABLESPACE_STMT + ALTER_KW "alter" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "o1" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_configuration_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_configuration_ok.snap new file mode 100644 index 00000000..604a1c5a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_configuration_ok.snap @@ -0,0 +1,567 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_text_search_configuration.sql +--- +SOURCE_FILE + COMMENT "-- add_mapping" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ADD_KW "add" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ADD_KW "add" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_mapping" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_mapping_replace" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_mapping_for_replace" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "o" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + ALTER_KW "alter" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "o" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_mapping" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + DROP_KW "drop" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE "\n " + DROP_KW "drop" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "m" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "m" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_CONFIGURATION_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_dictionary_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_dictionary_ok.snap new file mode 100644 index 00000000..82c37ac8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_dictionary_ok.snap @@ -0,0 +1,135 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_text_search_dictionary.sql +--- +SOURCE_FILE + COMMENT "-- options" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_DICTIONARY_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "b" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_DICTIONARY_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_DICTIONARY_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_DICTIONARY_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_DICTIONARY_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_parser_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_parser_ok.snap new file mode 100644 index 00000000..a71e6520 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_parser_ok.snap @@ -0,0 +1,80 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_text_search_parser.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_PARSER_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_PARSER_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_TEXT_SEARCH_PARSER_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_template_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_template_ok.snap new file mode 100644 index 00000000..9848c15e --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_text_search_template_ok.snap @@ -0,0 +1,58 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_text_search_template.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_TEMPLATE_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_TEXT_SEARCH_TEMPLATE_STMT + ALTER_KW "alter" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_trigger_ok.snap new file mode 100644 index 00000000..217852eb --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_trigger_ok.snap @@ -0,0 +1,91 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_trigger.sql +--- +SOURCE_FILE + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "x" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- depends_on" + WHITESPACE "\n" + ALTER_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "x" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ALTER_TRIGGER_STMT + ALTER_KW "alter" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + DEPENDS_KW "depends" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "e" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_type_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_type_ok.snap new file mode 100644 index 00000000..7c06435a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_type_ok.snap @@ -0,0 +1,669 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_type.sql +--- +SOURCE_FILE + COMMENT "-- owner" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_attribute" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_attribute_cascade" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_value" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + LITERAL + STRING "'v'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_value_full" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + LITERAL + STRING "'v'" + WHITESPACE " " + BEFORE_KW "before" + WHITESPACE " " + LITERAL + STRING "'w'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + LITERAL + STRING "'v'" + WHITESPACE " " + AFTER_KW "after" + WHITESPACE " " + LITERAL + STRING "'w'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_value" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + LITERAL + STRING "'v'" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'w'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_property" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'v'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'v'" + COMMA "," + WHITESPACE " " + NAME + IDENT "q" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'w'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_attribute" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_attribute_collate" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- add_attribute_cascade" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- drop_attribute" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_attribute" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alter_attribute_set_data" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple_actions" + WHITESPACE "\n" + ALTER_TYPE_STMT + ALTER_KW "alter" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ADD_KW "add" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + ATTRIBUTE_KW "attribute" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_mapping_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_mapping_ok.snap new file mode 100644 index 00000000..b82facb9 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_mapping_ok.snap @@ -0,0 +1,51 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_user_mapping.sql +--- +SOURCE_FILE + COMMENT "-- full" + WHITESPACE "\n" + ALTER_USER_MAPPING_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + ADD_KW "add" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'v'" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + LITERAL + STRING "'w'" + COMMA "," + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_ok.snap new file mode 100644 index 00000000..0bad6b57 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_user_ok.snap @@ -0,0 +1,258 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_user.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + IDENT "superuser" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " \n " + IDENT "superuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "createdb" + WHITESPACE "\n " + IDENT "nocreatedb" + WHITESPACE "\n " + IDENT "createrole" + WHITESPACE "\n " + IDENT "nocreaterole" + WHITESPACE "\n " + INHERIT_KW "inherit" + WHITESPACE "\n " + IDENT "noinherit" + WHITESPACE "\n " + IDENT "login" + WHITESPACE "\n " + IDENT "nologin" + WHITESPACE "\n " + IDENT "replication" + WHITESPACE "\n " + IDENT "noreplication" + WHITESPACE "\n " + IDENT "bypassrls" + WHITESPACE "\n " + IDENT "nobypassrls" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + ENCRYPTED_KW "encrypted" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + VALID_KW "valid" + WHITESPACE " " + UNTIL_KW "until" + WHITESPACE " " + LITERAL + STRING "'2025-01-01'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_user" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "v" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'value'" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_USER_STMT + ALTER_KW "alter" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IDENT "u" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_view_ok.snap new file mode 100644 index 00000000..270e42a9 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__alter_view_ok.snap @@ -0,0 +1,331 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/alter_view.sql +--- +SOURCE_FILE + COMMENT "-- column_set_default" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + INT_NUMBER "42" + SEMICOLON ";" + WHITESPACE "\n\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + NAME_REF + CURRENT_TIMESTAMP_KW "current_timestamp" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column_drop_default" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to_current_role" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to_current_user" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- owner_to_session_user" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SESSION_USER_KW "session_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_to" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rename_column" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RENAME_KW "rename" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_schema" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set_options" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'x'" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + COMMA "," + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- reset_options" + WHITESPACE "\n" + ALTER_VIEW_STMT + ALTER_KW "alter" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + RESET_KW "reset" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__analyze_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__analyze_ok.snap new file mode 100644 index 00000000..540b8ef6 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__analyze_ok.snap @@ -0,0 +1,114 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/analyze.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + ANALYZE_STMT + ANALYZE_KW "analyze" + SEMICOLON ";" + WHITESPACE "\n" + ANALYZE_STMT + ANALYSE_KW "analyse" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + ANALYZE_STMT + ANALYZE_KW "analyze" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full_parens" + WHITESPACE "\n" + ANALYZE_STMT + ANALYZE_KW "analyze" + WHITESPACE " " + L_PAREN "(" + VERBOSE_KW "verbose" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE " " + IDENT "skip_locked" + COMMA "," + WHITESPACE " " + IDENT "buffer_usage_limit" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__call_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__call_ok.snap new file mode 100644 index 00000000..4bc5e8ba --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__call_ok.snap @@ -0,0 +1,76 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/call.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CALL_STMT + CALL_KW "CALL" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "do_db_maintenance" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_schema" + WHITESPACE "\n" + CALL_STMT + CALL_KW "CALL" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman" + DOT "." + PATH_SEGMENT + NAME + IDENT "partition_data_proc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'partman_test.time_taptest_table'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_named_args" + WHITESPACE "\n" + CALL_STMT + CALL_KW "CALL" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "do_db_maintenance" + ARG_LIST + L_PAREN "(" + NAMED_ARG + NAME_REF + IDENT "x" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + STRING "'1'" + COMMA "," + WHITESPACE " " + LITERAL + NULL_KW "null" + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "b" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + STRING "'d'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__checkpoint_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__checkpoint_ok.snap new file mode 100644 index 00000000..5ef96cbb --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__checkpoint_ok.snap @@ -0,0 +1,11 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/checkpoint.sql +--- +SOURCE_FILE + COMMENT "-- checkpoint" + WHITESPACE "\n" + CHECKPOINT_STMT + CHECKPOINT_KW "checkpoint" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__close_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__close_ok.snap new file mode 100644 index 00000000..c86edc2e --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__close_ok.snap @@ -0,0 +1,20 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/close.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + CLOSE_STMT + CLOSE_KW "close" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + CLOSE_STMT + CLOSE_KW "close" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__cluster_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__cluster_ok.snap new file mode 100644 index 00000000..5b82a5f2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__cluster_ok.snap @@ -0,0 +1,108 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/cluster.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + WHITESPACE " " + L_PAREN "(" + VERBOSE_KW "verbose" + WHITESPACE " " + LITERAL + FALSE_KW "false" + R_PAREN ")" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "idx" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- options_only" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + WHITESPACE " " + L_PAREN "(" + VERBOSE_KW "verbose" + WHITESPACE " " + LITERAL + FALSE_KW "false" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pre_14" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "idx" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pre_17" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + WHITESPACE " " + VERBOSE_KW "verbose" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pre_8_3" + WHITESPACE "\n" + CLUSTER_STMT + CLUSTER_KW "cluster" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__comment_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__comment_ok.snap new file mode 100644 index 00000000..3a3e0279 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__comment_ok.snap @@ -0,0 +1,1335 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/comment.sql +--- +SOURCE_FILE + COMMENT "-- access_method" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "m" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggregate_star" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "my_agg" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggregate" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggregate_with_params" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggregate_order_by" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE " " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PARAM + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cast" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- collation" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- constraint_on_table" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- constraint_on_domain" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- conversion" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- database" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- domain" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extension" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- event_trigger" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "e" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_data_wrapper" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_table" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function_with_args" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- index" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "idx" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- large_object" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- materialized_view" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- operator" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + L_PAREN "(" + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "200" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- operator_class" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- operator_family" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- policy" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- language" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "l" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- procedural_language" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "l" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- procedure" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- procedure_with_args" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- publication" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- role" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- routine" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- routine_with_args" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rule" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- sequence" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- server" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- statistics" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subscription" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_null" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- tablespace" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- text_search_configuration" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- text_search_dictionary" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- text_search_parser" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- text_search_template" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- transform" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- trigger" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type_" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- view" + WHITESPACE "\n" + COMMENT_STMT + COMMENT_KW "comment" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__copy_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__copy_ok.snap new file mode 100644 index 00000000..b7574cb4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__copy_ok.snap @@ -0,0 +1,373 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/copy.sql +--- +SOURCE_FILE + COMMENT "-- simple_copy_from" + WHITESPACE "\n" + COPY_STMT + COPY_KW "copy" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "copytest" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + STRING "'/tmp/copy.data'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- copy_to" + WHITESPACE "\n" + COPY_STMT + COPY_KW "COPY" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "country" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + STDOUT_KW "STDOUT" + WHITESPACE " " + L_PAREN "(" + NAME + DELIMITER_KW "DELIMITER" + WHITESPACE " " + LITERAL + STRING "'|'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- copy_from" + WHITESPACE "\n" + COPY_STMT + COPY_KW "COPY" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "country" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + LITERAL + STRING "'/usr1/proj/bray/sql/country_data'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- copy_to_file" + WHITESPACE "\n" + COPY_STMT + COPY_KW "COPY" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "country" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "country_name" + WHITESPACE " " + LIKE_KW "LIKE" + WHITESPACE " " + LITERAL + STRING "'A%'" + R_PAREN ")" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + LITERAL + STRING "'/usr1/proj/bray/sql/a_list_countries.copy'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- copy_to_compress_filed" + WHITESPACE "\n" + COPY_STMT + COPY_KW "COPY" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "country" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + PROGRAM_KW "PROGRAM" + WHITESPACE " " + LITERAL + STRING "'gzip > /usr1/proj/bray/sql/country_data.gz'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- log_setting" + WHITESPACE "\n" + COPY_STMT + COPY_KW "copy" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "x" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "i" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "y" + R_PAREN ")" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + STRING "'/tmp/input.file'" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "on_error" + WHITESPACE " " + IDENT "ignore" + COMMA "," + WHITESPACE " " + NAME + IDENT "log_verbosity" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_error" + WHITESPACE "\n" + COPY_STMT + COPY_KW "copy" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "copytest" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + STRING "'/tmp/copy.data'" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME + IDENT "on_error" + WHITESPACE " " + IDENT "ignore" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_the_options" + WHITESPACE "\n" + COPY_STMT + COPY_KW "copy" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + FORMAT_KW "format" + WHITESPACE " " + CSV_KW "csv" + COMMA "," + WHITESPACE "\n " + NAME + FREEZE_KW "freeze" + COMMA "," + WHITESPACE "\n " + NAME + FREEZE_KW "freeze" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + NAME + FREEZE_KW "freeze" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + NAME + DELIMITER_KW "delimiter" + WHITESPACE " " + LITERAL + STRING "','" + COMMA "," + WHITESPACE "\n " + NAME + NULL_KW "null" + WHITESPACE " " + LITERAL + STRING "'\\n'" + COMMA "," + WHITESPACE "\n " + NAME + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + NAME + HEADER_KW "header" + COMMA "," + WHITESPACE "\n " + NAME + HEADER_KW "header" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + NAME + HEADER_KW "header" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + NAME + HEADER_KW "header" + WHITESPACE " " + MATCH_KW "match" + COMMA "," + WHITESPACE "\n " + NAME + QUOTE_KW "quote" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + NAME + ESCAPE_KW "escape" + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_quote" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_quote" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + COMMA "," + WHITESPACE " " + NAME + IDENT "d" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_not_null" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_not_null" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_null" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "force_null" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "on_error" + WHITESPACE " " + IDENT "stop" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "on_error" + WHITESPACE " " + IDENT "ignore" + COMMA "," + WHITESPACE "\n " + NAME + ENCODING_KW "encoding" + WHITESPACE " " + LITERAL + STRING "'utf8'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "log_verbosity" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_access_method_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_access_method_ok.snap new file mode 100644 index 00000000..3822b33b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_access_method_ok.snap @@ -0,0 +1,62 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_access_method.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_ACCESS_METHOD_STMT + CREATE_KW "create" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "m" + WHITESPACE "\n " + TYPE_KW "type" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_ACCESS_METHOD_STMT + CREATE_KW "create" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "m" + WHITESPACE "\n " + TYPE_KW "type" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_aggregate_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_aggregate_ok.snap new file mode 100644 index 00000000..3ee8eda0 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_aggregate_ok.snap @@ -0,0 +1,1195 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_aggregate.sql +--- +SOURCE_FILE + COMMENT "-- simple_old_syntax" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "create" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "a" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "basetype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full_old_syntax" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "my_aggregate" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "basetype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "input_type" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "state_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "state_type" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sspace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1024" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "final_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_extra" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_modify" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "read_only" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "combinefunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "combine_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "serialfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "serial_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "deserialfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "deserial_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'0'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "moving_state_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minvfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "moving_inverse_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mstype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "moving_state_type" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msspace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "2048" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "moving_final_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc_extra" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc_modify" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "shareable" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minitcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'{\"initial\":\"value\"}'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sortop" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "create" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "a" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "t" + R_PAREN ")" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "a" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + R_PAREN ")" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sspace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1024" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "ff" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_extra" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_modify" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "read_only" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "combinefunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "cf" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "serialfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "sf" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "deserialfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "df" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'0'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "msf" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minvfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "mif" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mstype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "mt" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msspace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "2048" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "mff" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc_extra" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mfinalfunc_modify" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "shareable" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minitcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'{\"initial\":\"value\"}'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sortop" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_ANGLE "<" + COMMA "," + WHITESPACE "\n " + NAME + PARALLEL_KW "parallel" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "safe" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ordered_aggregate" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "percentile_disc" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "p1" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + COMMA "," + WHITESPACE "\n" + COMMENT "-- in p2 text ORDER BY in value1 anyelement," + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "value2" + WHITESPACE " " + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "a" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "result" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "percentile_disc_transition" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "internal" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sspace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1024" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "percentile_disc_final" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_extra" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_modify" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "read_only" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'0.5'" + COMMA "," + WHITESPACE "\n " + NAME + PARALLEL_KW "parallel" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "safe" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "hypothetical" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_1" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "AGGREGATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "array_accum" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "anycompatible" + R_PAREN ")" + WHITESPACE "\n" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "array_append" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "anycompatiblearray" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'{}'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_2" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "AGGREGATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "array_agg" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "anynonarray" + R_PAREN ")" + WHITESPACE "\n" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "array_agg_transfn" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "internal" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "array_agg_finalfn" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_extra" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_3" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "AGGREGATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "percentile_disc" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "float8" + WHITESPACE " " + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "anyelement" + R_PAREN ")" + WHITESPACE "\n" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "ordered_set_transition" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "internal" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "percentile_disc_final" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "finalfunc_extra" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_4" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "AGGREGATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sum" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "complex" + R_PAREN ")" + WHITESPACE "\n" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "complex_add" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "complex" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'(0,0)'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "complex_add" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minvfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "complex_sub" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mstype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "complex" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minitcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'(0,0)'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_5" + WHITESPACE "\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "AGGREGATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "unsafe_sum" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "float8" + R_PAREN ")" + WHITESPACE "\n" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8pl" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mstype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "msfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8pl" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "minvfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8mi" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_cast_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_cast_ok.snap new file mode 100644 index 00000000..f855c217 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_cast_ok.snap @@ -0,0 +1,151 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_cast.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_CAST_STMT + CREATE_KW "create" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE "\n " + WITHOUT_KW "without" + WHITESPACE " " + FUNCTION_KW "function" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- inout" + WHITESPACE "\n" + CREATE_CAST_STMT + CREATE_KW "create" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + INOUT_KW "inout" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + IMPLICIT_KW "implicit" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_CAST_STMT + CREATE_KW "create" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "u" + R_PAREN ")" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + ASSIGNMENT_KW "assignment" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_collation_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_collation_ok.snap new file mode 100644 index 00000000..686b1c8c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_collation_ok.snap @@ -0,0 +1,156 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_collation.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_COLLATION_STMT + CREATE_KW "create" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from_full" + WHITESPACE "\n" + CREATE_COLLATION_STMT + CREATE_KW "create" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_options" + WHITESPACE "\n" + CREATE_COLLATION_STMT + CREATE_KW "create" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "locale" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "lc_collate" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "lc_ctype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "provider" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "deterministic" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "rules" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + COMMA "," + WHITESPACE "\n " + NAME + VERSION_KW "version" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'100'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_conversion_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_conversion_ok.snap new file mode 100644 index 00000000..4cccb1a0 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_conversion_ok.snap @@ -0,0 +1,82 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_conversion.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_CONVERSION_STMT + CREATE_KW "create" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " \n " + FOR_KW "for" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_CONVERSION_STMT + CREATE_KW "create" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " \n " + FOR_KW "for" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_database_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_database_ok.snap new file mode 100644 index 00000000..d002120a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_database_ok.snap @@ -0,0 +1,145 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_database.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_DATABASE_STMT + CREATE_KW "create" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_DATABASE_STMT + CREATE_KW "create" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + OWNER_KW "owner" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + TEMPLATE_KW "template" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + ENCODING_KW "encoding" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'utf-8'" + WHITESPACE "\n " + IDENT "strategy" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + IDENT "locale" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'fr_FR'" + WHITESPACE "\n " + IDENT "lc_collate" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'fr_FR'" + WHITESPACE "\n " + IDENT "lc_ctyep" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + IDENT "builtin_locale" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'en'" + WHITESPACE "\n " + IDENT "icu_locale" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'en'" + WHITESPACE "\n " + IDENT "icu_rules" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + IDENT "locale_provider" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'./foo/bar'" + WHITESPACE "\n " + IDENT "collation_version" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + TABLESPACE_KW "tablespace" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FULL_KW "full" + WHITESPACE "\n " + IDENT "allow_connections" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1000" + WHITESPACE "\n " + IDENT "is_template" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE "\n " + IDENT "oid" + WHITESPACE " " + LITERAL + INT_NUMBER "1010" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_domain_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_domain_ok.snap new file mode 100644 index 00000000..d26d0a6f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_domain_ok.snap @@ -0,0 +1,85 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_domain.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_DOMAIN_STMT + CREATE_KW "create" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_DOMAIN_STMT + CREATE_KW "create" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE "\n " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE "\n " + DEFAULT_CONSTRAINT + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + STRING "'fooooo'" + WHITESPACE "\n " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + NULL_CONSTRAINT + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_event_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_event_trigger_ok.snap new file mode 100644 index 00000000..9d4166a3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_event_trigger_ok.snap @@ -0,0 +1,126 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_event_trigger.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_EVENT_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + IDENT "e" + WHITESPACE "\n " + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_EVENT_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + IDENT "e" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" + WHITESPACE "\n " + AND_KW "and" + WHITESPACE " " + NAME_REF + REAL_KW "real" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'a'" + R_PAREN ")" + WHITESPACE "\n " + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_1" + WHITESPACE "\n" + CREATE_EVENT_TRIGGER_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EVENT_KW "EVENT" + WHITESPACE " " + TRIGGER_KW "TRIGGER" + WHITESPACE " " + NAME + IDENT "abort_ddl" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + IDENT "ddl_command_start" + WHITESPACE "\n " + EXECUTE_KW "EXECUTE" + WHITESPACE " " + FUNCTION_KW "FUNCTION" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "abort_any_command" + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_ext_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_ext_ok.snap new file mode 100644 index 00000000..aa7f2116 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_ext_ok.snap @@ -0,0 +1,84 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_ext.sql +--- +SOURCE_FILE + COMMENT "-- create_extension" + WHITESPACE "\n" + CREATE_EXTENSION_STMT + CREATE_KW "create" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_EXTENSION_STMT + CREATE_KW "create" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "create" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME + IDENT "hstore" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IDENT "addons" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "create" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IDENT "bar" + WHITESPACE "\n " + VERSION_KW "version" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "create" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE "\n " + SCHEMA_KW "schema" + WHITESPACE " " + IDENT "bar" + WHITESPACE "\n " + VERSION_KW "version" + WHITESPACE " " + LITERAL + STRING "'buzz'" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_data_wrapper_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_data_wrapper_ok.snap new file mode 100644 index 00000000..4a3e373b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_data_wrapper_ok.snap @@ -0,0 +1,84 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_foreign_data_wrapper.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_FOREIGN_DATA_WRAPPER_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME + IDENT "w" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_FOREIGN_DATA_WRAPPER_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME + IDENT "w" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + HANDLER_KW "handler" + WHITESPACE "\n " + VALIDATOR_KW "validator" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + VALIDATOR_KW "validator" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_table_ok.snap new file mode 100644 index 00000000..28683095 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_foreign_table_ok.snap @@ -0,0 +1,620 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_foreign_table.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " \n " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " \n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + LITERAL + STRING "'d'" + R_PAREN ")" + WHITESPACE " \n " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE "\n " + NOT_NULL_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + NULL_CONSTRAINT + NULL_KW "null" + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE "\n " + DEFAULT_CONSTRAINT + DEFAULT_KW "default" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE "\n " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + STORED_KW "stored" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "fooo" + WHITESPACE "\n " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n " + INHERITS_KW "inherits" + WHITESPACE " " + L_PAREN "(" + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + LITERAL + STRING "'d'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partitioned_simple" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " \n " + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partitioned" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " \n " + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "u" + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + OPTIONS_KW "options" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + NULL_CONSTRAINT + NULL_KW "null" + WHITESPACE " " + DEFAULT_CONSTRAINT + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + LITERAL + STRING "'d'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partitioned_bound_spec_in" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " \n " + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partitioned_bound_spec_from" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " \n " + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + MINVALUE_KW "minvalue" + COMMA "," + WHITESPACE " " + NAME_REF + MAXVALUE_KW "maxvalue" + R_PAREN ")" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + L_PAREN "(" + NAME_REF + MAXVALUE_KW "maxvalue" + COMMA "," + WHITESPACE " " + NAME_REF + MINVALUE_KW "minvalue" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- partitioned_bound_spec_with" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " \n " + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + IDENT "modulus" + WHITESPACE " " + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + IDENT "remainder" + WHITESPACE " " + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with schema" + WHITESPACE "\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "cal" + DOT "." + PATH_SEGMENT + NAME + IDENT "event_types" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "attrs" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + OBJECT_KW "object" + WHITESPACE " " + LITERAL + STRING "'event-types'" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_err.snap new file mode 100644 index 00000000..01d1541e --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_err.snap @@ -0,0 +1,15 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/create_function.sql +--- +SOURCE_FILE + COMMENT "-- regression partial definition" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE "\n" +--- +ERROR@48: expected path name +ERROR@48: expected L_PAREN diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_ok.snap new file mode 100644 index 00000000..bf3d907f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_function_ok.snap @@ -0,0 +1,3037 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_function.sql +--- +SOURCE_FILE + COMMENT "-- create_func_with_in_out" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "dup" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "f1" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "f2" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + WHITESPACE "\n " + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$ select $1, cast($1 as text) || ' is text' $$" + WHITESPACE "\n " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- security_definer" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + FUNCTION_KW "FUNCTION" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "check_password" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "uname" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "pass" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "RETURNS" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BOOLEAN_KW "BOOLEAN" + WHITESPACE " " + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "AS" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$\nDECLARE passed BOOLEAN;\nBEGIN\n SELECT (pwd = $2) INTO passed\n FROM pwds\n WHERE username = $1;\n\n RETURN passed;\nEND;\n$$" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "LANGUAGE" + WHITESPACE " " + IDENT "plpgsql" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + SECURITY_KW "SECURITY" + WHITESPACE " " + DEFINER_KW "DEFINER" + WHITESPACE "\n " + COMMENT "-- Set a secure search_path: trusted schema(s), then 'pg_temp'." + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "SET" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "search_path" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ADMIN_KW "admin" + COMMA "," + WHITESPACE " " + IDENT "pg_temp" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_function_with_percent_type" + WHITESPACE "\n" + COMMENT "-- column type return" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "a" + WHITESPACE " " + PERCENT_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + PERCENT_TYPE_CLAUSE + PERCENT "%" + TYPE_KW "type" + R_PAREN ")" + WHITESPACE " \n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PERCENT_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + PERCENT_TYPE_CLAUSE + PERCENT "%" + TYPE_KW "type" + WHITESPACE " \n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + IDENT "plpgsql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- setof return" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + SETOF_KW "setof" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- void return" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- omitted return" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + LITERAL + STRING "'sql'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'select 1'" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + LITERAL + STRING "'sql'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + DOT "." + PATH_SEGMENT + NAME + IDENT "d" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'select 1'" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + LITERAL + STRING "'sql'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME + IDENT "a" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_BRACK "[" + R_BRACK "]" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + LITERAL + STRING "'sql'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- returns table" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- transform" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + TRANSFORM_FUNC_OPTION + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- transform with type with args" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "255" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + TRANSFORM_FUNC_OPTION + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- window" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + WINDOW_FUNC_OPTION + WINDOW_KW "window" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- immutable, stable, volatile" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + IMMUTABLE_KW "immutable" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + STABLE_KW "stable" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + VOLATILITY_FUNC_OPTION + VOLATILE_KW "volatile" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- [ not ] leakproof" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LEAKPROOF_FUNC_OPTION + NOT_KW "not" + WHITESPACE " " + LEAKPROOF_KW "leakproof" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LEAKPROOF_FUNC_OPTION + LEAKPROOF_KW "leakproof" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + STRICT_FUNC_OPTION + CALLED_KW "called" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + INPUT_KW "input" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + STRICT_FUNC_OPTION + RETURNS_KW "returns" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + INPUT_KW "input" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + STRICT_FUNC_OPTION + STRICT_KW "strict" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- parallel" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "unsafe" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "restricted" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "safe" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- cost" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + COST_FUNC_OPTION + COST_KW "cost" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rows" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + ROWS_FUNC_OPTION + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- suport" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SUPPORT_FUNC_OPTION + SUPPORT_KW "support" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SUPPORT_FUNC_OPTION + SUPPORT_KW "support" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set configuration_parameter" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- as def" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'select 1'" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- as 'object_file', 'link_symbol'" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- return" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + RETURN_FUNC_OPTION + RETURN_KW "return" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- begin atomic" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + BEGIN_FUNC_OPTION + BEGIN_KW "begin" + WHITESPACE " " + ATOMIC_KW "atomic" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + BEGIN_FUNC_OPTION + BEGIN_KW "begin" + WHITESPACE " " + ATOMIC_KW "atomic" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n " + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lots of ;" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + BEGIN_FUNC_OPTION + BEGIN_KW "begin" + WHITESPACE " " + ATOMIC_KW "atomic" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n" + SEMICOLON ";" + SEMICOLON ";" + WHITESPACE "\n" + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all options" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n " + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n " + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n " + TRANSFORM_FUNC_OPTION + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE "\n " + WINDOW_FUNC_OPTION + WINDOW_KW "window" + WHITESPACE "\n " + VOLATILITY_FUNC_OPTION + IMMUTABLE_KW "immutable" + WHITESPACE "\n " + LEAKPROOF_FUNC_OPTION + NOT_KW "not" + WHITESPACE " " + LEAKPROOF_KW "leakproof" + WHITESPACE "\n " + STRICT_FUNC_OPTION + STRICT_KW "strict" + WHITESPACE "\n " + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n " + PARALLEL_FUNC_OPTION + PARALLEL_KW "parallel" + WHITESPACE " " + IDENT "safe" + WHITESPACE "\n " + COST_FUNC_OPTION + COST_KW "cost" + WHITESPACE " " + LITERAL + INT_NUMBER "1000" + WHITESPACE "\n " + ROWS_FUNC_OPTION + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1000" + WHITESPACE "\n " + SUPPORT_FUNC_OPTION + SUPPORT_KW "support" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE "\n " + RETURN_FUNC_OPTION + RETURN_KW "return" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- regression" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'select 1 + 1'" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "bitmask" + WHITESPACE " " + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "8" + R_PAREN ")" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BOOLEAN_KW "boolean" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'0'" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- argmode" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_INOUT + IN_KW "in" + WHITESPACE " " + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_INOUT + INOUT_KW "inout" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_VARIADIC + VARIADIC_KW "variadic" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_arg_names" + WHITESPACE "\n\n\n" + COMMENT "-- single arg" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi args" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "arg2" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- named and unnamed" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "int4" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- default" + WHITESPACE "\n" + COMMENT "-- =" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "int4" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not a parser error but something to warn about" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "int4" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- default" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + PARAM_DEFAULT + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- expr w/ default" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + PARAM_DEFAULT + DEFAULT_KW "default" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- expr w/ =" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n" + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- param_type_order" + WHITESPACE "\n" + COMMENT "-- mode name type" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "arg" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- mode type" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- name mode type" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "int8" + WHITESPACE " " + PARAM_IN + IN_KW "in" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- name type" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "int8" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + IDENT "int8" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE "\n" + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_group_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_group_ok.snap new file mode 100644 index 00000000..964768dc --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_group_ok.snap @@ -0,0 +1,129 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_group.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_GROUP_STMT + CREATE_KW "create" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + NAME + IDENT "g" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_GROUP_STMT + CREATE_KW "create" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + NAME + IDENT "g" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + IDENT "superuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "createdb" + WHITESPACE "\n " + IDENT "nocreatedb" + WHITESPACE "\n " + IDENT "createrole" + WHITESPACE "\n " + IDENT "nocreaterole" + WHITESPACE "\n " + INHERIT_KW "inherit" + WHITESPACE "\n " + IDENT "noinherit" + WHITESPACE "\n " + IDENT "login" + WHITESPACE "\n " + IDENT "nologin" + WHITESPACE "\n " + IDENT "replication" + WHITESPACE "\n " + IDENT "noreplication" + WHITESPACE "\n " + IDENT "bypassrls" + WHITESPACE "\n " + IDENT "nobypassrls" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + ENCRYPTED_KW "encrypted" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + VALID_KW "valid" + WHITESPACE " " + UNTIL_KW "until" + WHITESPACE " " + LITERAL + STRING "'2042-02-22'" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "foo" + COMMA "," + WHITESPACE " " + IDENT "bar" + COMMA "," + WHITESPACE " " + IDENT "buzz" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + ROLE_KW "role" + WHITESPACE " " + IDENT "r" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + ADMIN_KW "admin" + WHITESPACE " " + IDENT "foo" + COMMA "," + WHITESPACE " " + IDENT "bar" + COMMA "," + WHITESPACE " " + IDENT "buzz" + WHITESPACE "\n " + SYSID_KW "sysid" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_index_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_index_ok.snap new file mode 100644 index 00000000..4d16ae78 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_index_ok.snap @@ -0,0 +1,730 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_index.sql +--- +SOURCE_FILE + COMMENT "-- create_index" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- more options" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + WHITESPACE " \n " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "i" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " \n " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column options" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE " " + ASC_KW "asc" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + LAST_KW "last" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + WHITESPACE " " + DESC_KW "desc" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + FIRST_KW "first" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- opclass" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + IDENT "text_pattern_ops" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "strength" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PRIMARY_KW "primary" + COMMA "," + WHITESPACE " " + NAME + IDENT "variant" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + IDENT "text_pattern_ops" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "strength" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PRIMARY_KW "primary" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column expr" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- trailing options" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_INCLUDE_CLAUSE + INCLUDE_KW "include" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + NULLS_KW "nulls" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE "\n " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "space" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + NULLS_KW "nulls" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_examples" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + UNIQUE_KW "UNIQUE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "title" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + UNIQUE_KW "UNIQUE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "title" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_INCLUDE_CLAUSE + INCLUDE_KW "INCLUDE" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "director" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "rating" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "title" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "WITH" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "deduplicate_items" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + OFF_KW "off" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "lower" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "title" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx_german" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "title" + WHITESPACE " " + COLLATE_KW "COLLATE" + WHITESPACE " " + NAME_REF + IDENT "\"de_DE\"" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx_nulls_low" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "title" + WHITESPACE " " + NULLS_KW "NULLS" + WHITESPACE " " + FIRST_KW "FIRST" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + UNIQUE_KW "UNIQUE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "title_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "title" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "WITH" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "fillfactor" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "70" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "gin_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "documents_table" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "GIN" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "locations" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "WITH" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "fastupdate" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + OFF_KW "off" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "code_idx" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "code" + R_PAREN ")" + WHITESPACE " " + TABLESPACE_KW "TABLESPACE" + WHITESPACE " " + NAME_REF + IDENT "indexspace" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "pointloc" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "points" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "gist" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "box" + ARG_LIST + L_PAREN "(" + NAME_REF + LOCATION_KW "location" + COMMA "," + NAME_REF + LOCATION_KW "location" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + CONCURRENTLY_KW "CONCURRENTLY" + WHITESPACE " " + NAME + IDENT "sales_quantity_index" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "sales_table" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "quantity" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_language_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_language_ok.snap new file mode 100644 index 00000000..5e4559c4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_language_ok.snap @@ -0,0 +1,72 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_language.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_LANGUAGE_STMT + CREATE_KW "create" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME + IDENT "l" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_LANGUAGE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + TRUSTED_KW "trusted" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME + IDENT "l" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + INLINE_KW "inline" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE "\n " + VALIDATOR_KW "validator" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "x" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "y" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_materialized_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_materialized_view_ok.snap new file mode 100644 index 00000000..d3107d0f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_materialized_view_ok.snap @@ -0,0 +1,204 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_materialized_view.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE "\n " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + WHITESPACE "\n " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + DATA_KW "data" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table" + WHITESPACE "\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- values" + WHITESPACE "\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_class_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_class_ok.snap new file mode 100644 index 00000000..8db1e15c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_class_ok.snap @@ -0,0 +1,308 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_operator_class.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_OPERATOR_CLASS_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_OPERATOR_CLASS_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "c" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + AS_KW "as" + WHITESPACE " \n " + STORAGE_KW "storage" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + COMMA "," + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + COMMA "," + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + SEARCH_KW "search" + COMMA "," + WHITESPACE "\n " + OPERATOR_KW "operator" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + L_PAREN "(" + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1010" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1010" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + FUNCTION_KW "function" + WHITESPACE " " + LITERAL + INT_NUMBER "1010" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + R_PAREN ")" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_family_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_family_ok.snap new file mode 100644 index 00000000..b58b05ab --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_family_ok.snap @@ -0,0 +1,50 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_operator_family.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_OPERATOR_FAMILY_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_OPERATOR_FAMILY_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME + IDENT "b" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_ok.snap new file mode 100644 index 00000000..72edde93 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_operator_ok.snap @@ -0,0 +1,194 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_operator.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_OPERATOR_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + FUNCTION_KW "function" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- procedure" + WHITESPACE "\n" + CREATE_OPERATOR_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + PROCEDURE_KW "procedure" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "p" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_OPERATOR_STMT + CREATE_KW "create" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + MINUS "-" + POUND "#" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + FUNCTION_KW "function" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "leftarg" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "rightarg" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "commutator" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + AMP "&" + AMP "&" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "negator" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + MINUS "-" + R_ANGLE ">" + COMMA "," + WHITESPACE "\n " + NAME + RESTRICT_KW "restrict" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + COMMA "," + WHITESPACE "\n " + NAME + JOIN_KW "join" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "j" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "hashes" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "merges" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_policy_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_policy_ok.snap new file mode 100644 index 00000000..6a3db115 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_policy_ok.snap @@ -0,0 +1,252 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_policy.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- as_" + WHITESPACE "\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + IDENT "permissive" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + IDENT "restrictive" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + IDENT "permissive" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + IDENT "public" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + SESSION_USER_KW "session_user" + WHITESPACE "\n " + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- for_" + WHITESPACE "\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + SELECT_KW "select" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + INSERT_KW "insert" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + UPDATE_KW "update" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_POLICY_STMT + CREATE_KW "create" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + DELETE_KW "delete" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_procedure_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_procedure_ok.snap new file mode 100644 index 00000000..1bb59d74 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_procedure_ok.snap @@ -0,0 +1,281 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_procedure.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_PROCEDURE_STMT + CREATE_KW "create" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "p" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_PROCEDURE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "p" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PARAM_DEFAULT + DEFAULT_KW "DEFAULT" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + PARAM_DEFAULT + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + TRANSFORM_FUNC_OPTION + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n" + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + INVOKER_KW "invoker" + WHITESPACE "\n" + SECURITY_FUNC_OPTION + EXTERNAL_KW "external" + WHITESPACE " " + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n" + SECURITY_FUNC_OPTION + SECURITY_KW "security" + WHITESPACE " " + DEFINER_KW "definer" + WHITESPACE "\n" + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n" + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE "\n" + SET_FUNC_OPTION + SET_KW "set" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n" + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE "\n" + RETURN_FUNC_OPTION + RETURN_KW "return" + WHITESPACE " " + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_select_body" + WHITESPACE "\n" + CREATE_PROCEDURE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "p" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE "\n" + BEGIN_FUNC_OPTION + BEGIN_KW "begin" + WHITESPACE " " + ATOMIC_KW "atomic" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_publication_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_publication_ok.snap new file mode 100644 index 00000000..6f1af9ea --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_publication_ok.snap @@ -0,0 +1,256 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_publication.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_PUBLICATION_STMT + CREATE_KW "create" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_tables" + WHITESPACE "\n" + CREATE_PUBLICATION_STMT + CREATE_KW "create" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table" + WHITESPACE "\n" + CREATE_PUBLICATION_STMT + CREATE_KW "create" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " \n " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " \n " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " \n " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " \n " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + NEQ "!=" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_in_schema" + WHITESPACE "\n" + CREATE_PUBLICATION_STMT + CREATE_KW "create" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "p" + WHITESPACE "\n " + FOR_KW "for" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + CURRENT_SCHEMA_KW "current_schema" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple tables" + WHITESPACE "\n" + CREATE_PUBLICATION_STMT + CREATE_KW "create" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME + IDENT "pub" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "chats" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "users" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_role_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_role_ok.snap new file mode 100644 index 00000000..189026be --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_role_ok.snap @@ -0,0 +1,116 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_role.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_ROLE_STMT + CREATE_KW "create" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_ROLE_STMT + CREATE_KW "create" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + NAME + IDENT "u" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + IDENT "superuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "createdb" + WHITESPACE "\n " + IDENT "nocreatedb" + WHITESPACE "\n " + IDENT "createrole" + WHITESPACE "\n " + IDENT "nocreaterole" + WHITESPACE "\n " + INHERIT_KW "inherit" + WHITESPACE "\n " + IDENT "noinherit" + WHITESPACE "\n " + IDENT "login" + WHITESPACE "\n " + IDENT "nologin" + WHITESPACE "\n " + IDENT "replication" + WHITESPACE "\n " + IDENT "noreplication" + WHITESPACE "\n " + IDENT "bypassrls" + WHITESPACE "\n " + IDENT "nobypassrls" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + ENCRYPTED_KW "encrypted" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + VALID_KW "valid" + WHITESPACE " " + UNTIL_KW "until" + WHITESPACE " " + LITERAL + STRING "'2042-02-22'" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "foo" + COMMA "," + WHITESPACE " " + IDENT "bar" + COMMA "," + WHITESPACE " " + IDENT "buzz" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + ADMIN_KW "admin" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + SYSID_KW "sysid" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_rule_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_rule_ok.snap new file mode 100644 index 00000000..e5b35006 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_rule_ok.snap @@ -0,0 +1,358 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_rule.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_RULE_STMT + CREATE_KW "create" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME + IDENT "r" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_RULE_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME + IDENT "r" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + NEW_KW "new" + DOT "." + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + OLD_KW "old" + DOT "." + NAME_REF + IDENT "foo" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + OLD_KW "old" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + NEQ "!=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + NEW_KW "new" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n " + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n " + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n " + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n " + NOTIFY_STMT + NOTIFY_KW "notify" + WHITESPACE " " + NAME + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_1" + WHITESPACE "\n" + CREATE_RULE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + RULE_KW "RULE" + WHITESPACE " " + NAME + IDENT "\"_RETURN\"" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + SELECT_KW "SELECT" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE "\n " + DO_KW "DO" + WHITESPACE " " + INSTEAD_KW "INSTEAD" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "t2" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_RULE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + RULE_KW "RULE" + WHITESPACE " " + NAME + IDENT "\"_RETURN\"" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + SELECT_KW "SELECT" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + WHITESPACE "\n " + DO_KW "DO" + WHITESPACE " " + INSTEAD_KW "INSTEAD" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_2" + WHITESPACE "\n" + CREATE_RULE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + RULE_KW "RULE" + WHITESPACE " " + NAME + IDENT "notify_me" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + UPDATE_KW "UPDATE" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "mytable" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + ALSO_KW "ALSO" + WHITESPACE " " + NOTIFY_STMT + NOTIFY_KW "NOTIFY" + WHITESPACE " " + NAME + IDENT "mytable" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "mytable" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "42" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_sequence_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_sequence_ok.snap new file mode 100644 index 00000000..9764c0d1 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_sequence_ok.snap @@ -0,0 +1,121 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_sequence.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_SEQUENCE_STMT + CREATE_KW "create" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_SEQUENCE_STMT + CREATE_KW "create" + WHITESPACE " " + TEMPORARY_KW "temporary" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE "\n " + INCREMENT_KW "increment" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + MINVALUE_KW "minvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MINVALUE_KW "minvalue" + WHITESPACE "\n " + MAXVALUE_KW "maxvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MAXVALUE_KW "maxvalue" + WHITESPACE "\n " + START_KW "start" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + CACHE_KW "cache" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + CYCLE_KW "cycle" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- unlogged" + WHITESPACE "\n" + CREATE_SEQUENCE_STMT + CREATE_KW "create" + WHITESPACE " " + UNLOGGED_KW "unlogged" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_server_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_server_ok.snap new file mode 100644 index 00000000..b6f15ba6 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_server_ok.snap @@ -0,0 +1,123 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_server.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_SERVER_STMT + CREATE_KW "create" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "f" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_SERVER_STMT + CREATE_KW "create" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " \n " + TYPE_KW "type" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " \n " + VERSION_KW "version" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "f" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- docs_1" + WHITESPACE "\n" + CREATE_SERVER_STMT + CREATE_KW "CREATE" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME + IDENT "myserver" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + DATA_KW "DATA" + WHITESPACE " " + WRAPPER_KW "WRAPPER" + WHITESPACE " " + NAME_REF + IDENT "postgres_fdw" + WHITESPACE " " + OPTIONS_KW "OPTIONS" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "host" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + NAME + IDENT "dbname" + WHITESPACE " " + LITERAL + STRING "'foodb'" + COMMA "," + WHITESPACE " " + NAME + IDENT "port" + WHITESPACE " " + LITERAL + STRING "'5432'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_statistics_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_statistics_ok.snap new file mode 100644 index 00000000..45cb77b4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_statistics_ok.snap @@ -0,0 +1,228 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_statistics.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_STATISTICS_STMT + CREATE_KW "create" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_STATISTICS_STMT + CREATE_KW "create" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "s" + L_PAREN "(" + NAME_REF + IDENT "mcv" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "ndistinct" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "dependencies" + R_PAREN ")" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "foo" + R_PAREN ")" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + COMMA "," + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n" + FROM_KW "from" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- docs_1" + WHITESPACE "\n" + CREATE_STATISTICS_STMT + CREATE_KW "CREATE" + WHITESPACE " " + STATISTICS_KW "STATISTICS" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s1" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "dependencies" + R_PAREN ")" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- docs_2" + WHITESPACE "\n" + CREATE_STATISTICS_STMT + CREATE_KW "CREATE" + WHITESPACE " " + STATISTICS_KW "STATISTICS" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s2" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "mcv" + R_PAREN ")" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- docs_3" + WHITESPACE "\n" + CREATE_STATISTICS_STMT + CREATE_KW "CREATE" + WHITESPACE " " + STATISTICS_KW "STATISTICS" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s3" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "ndistinct" + R_PAREN ")" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'day'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t3" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_subscription_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_subscription_ok.snap new file mode 100644 index 00000000..b12b2f0b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_subscription_ok.snap @@ -0,0 +1,207 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_subscription.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_SUBSCRIPTION_STMT + CREATE_KW "create" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_SUBSCRIPTION_STMT + CREATE_KW "create" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LITERAL + STRING "'host=10.0.0.1 port=5432 user=u dbname=d'" + WHITESPACE "\n " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "connect" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "create_slot" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "enabled" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "slot_name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + BINARY_KW "binary" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "copy_data" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "synchronous_commit" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + OFF_KW "off" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "two_phase" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "disable_on_error" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "password_required" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "run_as_owner" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "origin" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "failover" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_as_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_as_ok.snap new file mode 100644 index 00000000..3bcd7f94 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_as_ok.snap @@ -0,0 +1,165 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_table_as.sql +--- +SOURCE_FILE + COMMENT "-- execute" + WHITESPACE "\n" + CREATE_TABLE_AS_STMT + CREATE_KW "create" + WHITESPACE " " + TEMP_KW "temp" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + COMMIT_KW "commit" + WHITESPACE " " + DROP_KW "drop" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + EXECUTE_STMT + EXECUTE_KW "execute" + WHITESPACE " " + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select" + WHITESPACE "\n" + CREATE_TABLE_AS_STMT + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table" + WHITESPACE "\n" + CREATE_TABLE_AS_STMT + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- values" + WHITESPACE "\n" + CREATE_TABLE_AS_STMT + CREATE_KW "create" + WHITESPACE " " + TEMPORARY_KW "temporary" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE_AS_STMT + CREATE_KW "create" + WHITESPACE " " + TEMPORARY_KW "temporary" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_err.snap new file mode 100644 index 00000000..137a9c7a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_err.snap @@ -0,0 +1,414 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/create_table.sql +--- +SOURCE_FILE + CREATE_TABLE + COMMENT "-- with missing table name" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "sensor_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "INTEGER" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- missing type" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- trailing comma" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + ERROR + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- missing columns / constraints" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COMMA "," + COMMA "," + COMMA "," + COMMA "," + ERROR + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- a column list with SET DEFAULT is only supported for ON DELETE actions" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + CASCADE_KW "cascade" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NULL_KW "null" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "d" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "e" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- conflicting options" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + UNLOGGED_KW "unlogged" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + SEQUENCE_OPTION_LIST + L_PAREN "(" + WHITESPACE "\n " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE "\n " + CACHE_KW "cache" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + INCREMENT_KW "increment" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + INCREMENT_KW "increment" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_KW "name" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE "\n " + RESTART_KW "restart" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "500" + WHITESPACE "\n " + LOGGED_KW "logged" + WHITESPACE "\n " + UNLOGGED_KW "unlogged" + WHITESPACE "\n " + START_KW "start" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + START_KW "start" + WHITESPACE " " + LITERAL + INT_NUMBER "25" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NONE_KW "none" + WHITESPACE "\n " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "fooo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + MAXVALUE_KW "maxvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "70" + WHITESPACE "\n " + MINVALUE_KW "minvalue" + WHITESPACE " " + LITERAL + INT_NUMBER "150" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MINVALUE_KW "minvalue" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + CYCLE_KW "cycle" + WHITESPACE "\n " + NO_KW "no" + WHITESPACE " " + MAXVALUE_KW "maxvalue" + WHITESPACE "\n " + CYCLE_KW "cycle" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@39: expected path name +ERROR@99: expected type name +ERROR@143: unexpected trailing comma +ERROR@201: unexpected trailing comma diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_ok.snap new file mode 100644 index 00000000..16bcb89b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_ok.snap @@ -0,0 +1,3024 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_table.sql +--- +SOURCE_FILE + CREATE_TABLE + COMMENT "-- create_table" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- with schema prefix" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- like source_table" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + LIKE_CLAUSE + LIKE_KW "like" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "large_data_table" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- like option" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + LIKE_CLAUSE + LIKE_KW "like" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + INCLUDING_KW "including" + WHITESPACE " " + COMMENTS_KW "comments" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- like options" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + LIKE_CLAUSE + LIKE_KW "like" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + INCLUDING_KW "including" + WHITESPACE " " + COMMENTS_KW "comments" + WHITESPACE " " + INCLUDING_KW "including" + WHITESPACE " " + CONSTRAINTS_KW "constraints" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + DEFAULTS_KW "defaults" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + GENERATED_KW "generated" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + INDEXES_KW "indexes" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + INCLUDING_KW "including" + WHITESPACE " " + STORAGE_KW "storage" + WHITESPACE " " + EXCLUDING_KW "excluding" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- with prefix options" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + GLOBAL_KW "global" + WHITESPACE " " + TEMPORARY_KW "temporary" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + LOCAL_KW "local" + WHITESPACE " " + TEMP_KW "temp" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- unlogged" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + UNLOGGED_KW "unlogged" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- inherits from parent" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + INHERITS_KW "inherits" + WHITESPACE " " + L_PAREN "(" + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition range" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + RANGE_KW "range" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + BIN_EXPR + NAME_REF + IDENT "foo" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE " " + IDENT "text_pattern_ops" + COMMA "," + WHITESPACE " \n " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + MONTH_KW "month" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition list" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "hash" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "z" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition hash" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "list" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "z" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- using" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + USING_KW "using" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- with" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- without" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + WITHOUT_KW "without" + WHITESPACE " " + OIDS_KW "OIDS" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- on commit" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + COMMIT_KW "commit" + WHITESPACE " " + PRESERVE_KW "preserve" + WHITESPACE " " + ROWS_KW "rows" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + COMMIT_KW "commit" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + ROWS_KW "rows" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + COMMIT_KW "commit" + WHITESPACE " " + DROP_KW "drop" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- tablespace" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n" + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "-- like_column" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "u" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " \n " + COLUMN + NAME_REF + IDENT "\"like\"" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " \n " + LIKE_CLAUSE + LIKE_KW "like" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- create_table_column_constraints" + WHITESPACE "\n" + COMMENT "-- not null" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- null" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NULL_CONSTRAINT + NULL_KW "null" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- default" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + DEFAULT_CONSTRAINT + DEFAULT_KW "default" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- unique constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "fillfactor" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "toast_tuple_target" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "parallel_workers" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "autovacuum_enabled" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "autovacuum_vacuum_cost_delay" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "10.1" + WHITESPACE "\n " + COMMENT "-- others omitted" + WHITESPACE "\n " + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "d" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + CONSTRAINT_INDEX_TABLESPACE + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- references actions order" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + ACTION_KW "action" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + ACTION_KW "action" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- primary key" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "autovacuum_enabled" + WHITESPACE " " + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- check constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- defer" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + DEFERRABLE_CONSTRAINT_OPTION + DEFERRABLE_KW "deferrable" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + INITALLY_DEFERRED_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + DEFERRED_KW "deferred" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "d" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + INITIALLY_IMMEDIATE_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + IMMEDIATE_KW "immediate" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + NULL_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- generated stored" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + UNLOGGED_KW "unlogged" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + ALWAYS_KW "always" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + STORED_KW "stored" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_table_table_constraints" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- named constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- check constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- unique constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- unique with name constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + DEFERRABLE_CONSTRAINT_OPTION + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITALLY_DEFERRED_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + DEFERRED_KW "deferred" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- primary key constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_INDEX_TABLESPACE + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- exclude constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_INDEX_METHOD + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "btree" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + DOT "." + PATH_SEGMENT + R_ANGLE ">" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- exclude constraint multiple exclusions" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_INDEX_METHOD + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "btree" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + DOT "." + PATH_SEGMENT + R_ANGLE ">" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " \n " + CONSTRAINT_WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'%foo'" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- exclude constraint all clauses exclusions" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_INDEX_METHOD + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "btree" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " \n " + CONSTRAINT_INCLUDE_CLAUSE + INCLUDE_KW "include" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "z" + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_INDEX_TABLESPACE + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE "\n " + CONSTRAINT_WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'%foo'" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n " + CONSTRAINT_OPTION_LIST + DEFERRABLE_CONSTRAINT_OPTION + DEFERRABLE_KW "deferrable" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- foreign key constraint" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + WHITESPACE " " + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bizz" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- everything" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CONSTRAINT_KW "constraint" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + INHERIT_KW "inherit" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE " " + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_INDEX_TABLESPACE + USING_KW "using" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE "\n " + EXCLUDE_CONSTRAINT + EXCLUDE_KW "exclude" + WHITESPACE " " + CONSTRAINT_INDEX_METHOD + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "btree" + WHITESPACE " " + CONSTRAINT_EXCLUSIONS + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + DOT "." + PATH_SEGMENT + R_ANGLE ">" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + FOREIGN_KEY_CONSTRAINT + FOREIGN_KW "foreign" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + WHITESPACE " " + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bizz" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + DEFERRABLE_CONSTRAINT_OPTION + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITALLY_DEFERRED_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + DEFERRED_KW "deferred" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + NAME_REF + IDENT "o" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_OPTION_LIST + NOT_DEFERRABLE_CONSTRAINT_OPTION + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + WHITESPACE " " + INITIALLY_IMMEDIATE_CONSTRAINT_OPTION + INITIALLY_KW "initially" + WHITESPACE " " + IMMEDIATE_KW "immediate" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "-- multi_dimensional_arrays" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sal_emp" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + NAME_KW "name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "pay_by_quarter" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "schedule" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + L_BRACK "[" + R_BRACK "]" + L_BRACK "[" + R_BRACK "]" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- array_with_params" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "tictactoe" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "squares" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- array_alt_syntax" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "tictactoe" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "pay_by_quarter" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE " " + ARRAY_KW "ARRAY" + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "pay_by_quarter" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE " " + ARRAY_KW "ARRAY" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- create_table_of_type" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- with column defs" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "c" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + OPTIONS_KW "options" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "not" + WHITESPACE " " + NULL_KW "null" + COMMA "," + WHITESPACE "\n " + CHECK_CONSTRAINT + CHECK_KW "check" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- create_table_partition_of" + WHITESPACE "\n" + COMMENT "-- default" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition with" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " \n" + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + IDENT "modulus" + WHITESPACE " " + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + IDENT "remainder" + WHITESPACE " " + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition in" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " \n" + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- partition from to" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE "\n" + PARTITION_KW "partition" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n" + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + R_PAREN ")" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'buzz'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- missing entries" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- regression" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sensors_uncompressed" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "sensor_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "INTEGER" + COMMA "," + WHITESPACE " \n " + COLUMN + NAME_REF + IDENT "ts" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "TIMESTAMPTZ" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + COMMA "," + WHITESPACE " \n " + COLUMN + NAME_REF + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + REAL_KW "REAL" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_pg17_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_pg17_ok.snap new file mode 100644 index 00000000..a895dc96 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_table_pg17_ok.snap @@ -0,0 +1,398 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_table_pg17.sql +--- +SOURCE_FILE + CREATE_TABLE + COMMENT "-- match partial not implemented yet" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "references" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + MATCH_KW "match" + WHITESPACE " " + PARTIAL_KW "partial" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + ACTION_KW "action" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + WHITESPACE " " + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "-- temporal_foreign_key" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "orders" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + IDENTITY_KW "IDENTITY" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "address_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "address_valid_at" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "tstzrange" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + CONTENT_KW "content" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + FOREIGN_KEY_CONSTRAINT + CONSTRAINT_KW "CONSTRAINT" + WHITESPACE " " + NAME + IDENT "order_address" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + KEY_KW "KEY" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + WHITESPACE " " + COLUMN + NAME_REF + IDENT "address_id" + COMMA "," + WHITESPACE " " + COLUMN + PERIOD_KW "PERIOD" + WHITESPACE " " + NAME_REF + IDENT "address_valid_at" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + REFERENCES_KW "REFERENCES" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "addresses" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + PERIOD_KW "PERIOD" + WHITESPACE " " + NAME_REF + IDENT "valid_range" + WHITESPACE " " + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- unique_constraint_without_overlaps" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + UNIQUE_CONSTRAINT + UNIQUE_KW "unique" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + OVERLAPS_KW "overlaps" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "-- temporal_primary_key" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "addresses" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + IDENTITY_KW "IDENTITY" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "valid_range" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "tstzrange" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + WHITESPACE " " + DEFAULT_CONSTRAINT + DEFAULT_KW "DEFAULT" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "tstzrange" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'infinity'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'[)'" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "recipient" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + COMMA "," + WHITESPACE "\n " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "PRIMARY" + WHITESPACE " " + KEY_KW "KEY" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "valid_range" + WHITESPACE " " + WITHOUT_KW "WITHOUT" + WHITESPACE " " + OVERLAPS_KW "OVERLAPS" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_tablespace_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_tablespace_ok.snap new file mode 100644 index 00000000..7450d6c1 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_tablespace_ok.snap @@ -0,0 +1,91 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_tablespace.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TABLESPACE_STMT + CREATE_KW "create" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + LOCATION_KW "location" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TABLESPACE_STMT + CREATE_KW "create" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " \n " + OWNER_KW "owner" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + LOCATION_KW "location" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "seq_page_cost" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "random_page_cost" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "effective_io_concurrency" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + COMMA "," + WHITESPACE "\n " + PATH + PATH_SEGMENT + NAME_REF + IDENT "maintenance_io_concurrency" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_config_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_config_ok.snap new file mode 100644 index 00000000..a740d0ce --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_config_ok.snap @@ -0,0 +1,74 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_text_search_config.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + PARSER_KW "parser" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "parser_name" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "config" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "source_config" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_dict_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_dict_ok.snap new file mode 100644 index 00000000..e231e385 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_dict_ok.snap @@ -0,0 +1,98 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_text_search_dict.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + TEMPLATE_KW "template" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + TEMPLATE_KW "template" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_parser_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_parser_ok.snap new file mode 100644 index 00000000..43628ebc --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_parser_ok.snap @@ -0,0 +1,158 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_text_search_parser.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + START_KW "start" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "start_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "gettoken" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "gettoken_function" + COMMA "," + WHITESPACE "\n " + NAME + END_KW "end" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "end_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "lextypes" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "lextypes_function" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + START_KW "start" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "start_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "gettoken" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "gettoken_function" + COMMA "," + WHITESPACE "\n " + NAME + END_KW "end" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "end_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "lextypes" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "lextypes_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "headline" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "headline_function" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_template_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_template_ok.snap new file mode 100644 index 00000000..cad1b597 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_text_search_template_ok.snap @@ -0,0 +1,86 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_text_search_template.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "lexize" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TEXT_SEARCH_PARSER_STMT + CREATE_KW "create" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + NAME_KW "name" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "INIT" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "init_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "lexize" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "lexize_function" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_transform_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_transform_ok.snap new file mode 100644 index 00000000..4b5e4cd1 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_transform_ok.snap @@ -0,0 +1,147 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_transform.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TRANSFORM_STMT + CREATE_KW "create" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "g" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_TRANSFORM_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10231" + R_PAREN ")" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + SQL_KW "sql" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "g" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_trigger_ok.snap new file mode 100644 index 00000000..4139004b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_trigger_ok.snap @@ -0,0 +1,322 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_trigger.sql +--- +SOURCE_FILE + COMMENT "-- create_trigger" + WHITESPACE "\n" + CREATE_TRIGGER_STMT + CREATE_KW "CREATE" + WHITESPACE " " + TRIGGER_KW "TRIGGER" + WHITESPACE " " + NAME + IDENT "update_foo_column" + WHITESPACE "\n" + BEFORE_KW "BEFORE" + WHITESPACE " " + INSERT_KW "INSERT" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "core_recipe" + WHITESPACE "\n" + FOR_KW "FOR" + WHITESPACE " " + EACH_KW "EACH" + WHITESPACE " " + ROW_KW "ROW" + WHITESPACE "\n" + EXECUTE_KW "EXECUTE" + WHITESPACE " " + PROCEDURE_KW "PROCEDURE" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo_update_trigger" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_most_fields" + WHITESPACE "\n" + CREATE_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "buzz" + WHITESPACE " " + INSTEAD_KW "instead" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + INSERT_KW "insert" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " \n" + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE "\n" + REFERENCING_KW "referencing" + WHITESPACE " \n " + OLD_KW "old" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE "\n " + NEW_KW "new" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n" + FOR_KW "for" + WHITESPACE " " + EACH_KW "each" + WHITESPACE " " + STATEMENT_KW "statement" + WHITESPACE " \n" + WHEN_KW "when" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + NULL_KW "null" + R_PAREN ")" + WHITESPACE "\n" + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + CALL_EXPR + FIELD_EXPR + FIELD_EXPR + NAME_REF + IDENT "x" + DOT "." + NAME_REF + IDENT "y" + DOT "." + NAME_REF + IDENT "z" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "2" + COMMA "," + LITERAL + STRING "'3'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- constraint" + WHITESPACE "\n" + CREATE_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + CONSTRAINT_KW "constraint" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + AFTER_KW "after" + WHITESPACE " " + INSERT_KW "insert" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " \n" + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE "\n" + FOR_KW "for" + WHITESPACE " " + EACH_KW "each" + WHITESPACE " " + ROW_KW "row" + WHITESPACE "\n" + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_most_fields_part2" + WHITESPACE "\n" + CREATE_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " " + AFTER_KW "after" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE "\n" + REFERENCING_KW "referencing" + WHITESPACE " \n " + NEW_KW "new" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n " + OLD_KW "old" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE "\n" + FOR_KW "for" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " \n" + EXECUTE_KW "execute" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " " + BEFORE_KW "before" + WHITESPACE " " + TRUNCATE_KW "truncate" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + DELETE_KW "delete" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + INSERT_KW "insert" + WHITESPACE "\n" + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE "\n" + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "a" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_type_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_type_ok.snap new file mode 100644 index 00000000..aa221027 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_type_ok.snap @@ -0,0 +1,545 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_type.sql +--- +SOURCE_FILE + COMMENT "-- create_type_as" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"fr_FR\"" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "c" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_type_as_enum" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ENUM_KW "enum" + WHITESPACE " " + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ENUM_KW "enum" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'a'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ENUM_KW "enum" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'c'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_type_as_range" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + RANGE_KW "range" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "subtype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + DOT "." + PATH_SEGMENT + NAME + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_type_name" + WHITESPACE "\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + INPUT_KW "input" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "func_name" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "output" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "func_name" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TYPE_STMT + CREATE_KW "create" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + INPUT_KW "input" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "func_name" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "output" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "func_name" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "receive" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "receive_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "send" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "send_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "typmod_in" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "type_modifier_input_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "typmod_out" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "type_modifier_output_function" + COMMA "," + WHITESPACE "\n " + NAME + ANALYZE_KW "analyze" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "analyze_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "subscript" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "subscript_function" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "internallength" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "variable" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "passedbyvalue" + COMMA "," + WHITESPACE "\n " + COMMENT "-- The allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries." + WHITESPACE "\n " + NAME + IDENT "alignment" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + NAME + STORAGE_KW "storage" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "plain" + COMMA "," + WHITESPACE "\n " + NAME + LIKE_KW "like" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "like_type" + COMMA "," + WHITESPACE "\n " + COMMENT "-- see: https://www.postgresql.org/docs/17/catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE" + WHITESPACE "\n " + NAME + IDENT "category" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'U'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "preferred" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + NAME + DEFAULT_KW "default" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NULL_KW "null" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "element" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float4" + COMMA "," + WHITESPACE "\n " + NAME + DELIMITER_KW "delimiter" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "','" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "collatable" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_user_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_user_ok.snap new file mode 100644 index 00000000..1b8d49f7 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_user_ok.snap @@ -0,0 +1,124 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_user.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + CREATE_USER_STMT + CREATE_KW "create" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + CREATE_USER_STMT + CREATE_KW "create" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME + IDENT "u" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + IDENT "superuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "nosuperuser" + WHITESPACE "\n " + IDENT "createdb" + WHITESPACE "\n " + IDENT "nocreatedb" + WHITESPACE "\n " + IDENT "createrole" + WHITESPACE "\n " + IDENT "nocreaterole" + WHITESPACE "\n " + INHERIT_KW "inherit" + WHITESPACE "\n " + IDENT "noinherit" + WHITESPACE "\n " + IDENT "login" + WHITESPACE "\n " + IDENT "nologin" + WHITESPACE "\n " + IDENT "replication" + WHITESPACE "\n " + IDENT "noreplication" + WHITESPACE "\n " + IDENT "bypassrls" + WHITESPACE "\n " + IDENT "nobypassrls" + WHITESPACE "\n " + CONNECTION_KW "connection" + WHITESPACE " " + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE "\n " + ENCRYPTED_KW "encrypted" + WHITESPACE " " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'foo'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE "\n " + PASSWORD_KW "password" + WHITESPACE " " + NULL_KW "null" + WHITESPACE "\n " + VALID_KW "valid" + WHITESPACE " " + UNTIL_KW "until" + WHITESPACE " " + LITERAL + STRING "'2042-02-22'" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IDENT "foo" + COMMA "," + WHITESPACE " " + IDENT "bar" + COMMA "," + WHITESPACE " " + IDENT "buzz" + WHITESPACE "\n " + IN_KW "in" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + ROLE_KW "role" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + ADMIN_KW "admin" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + USER_KW "user" + WHITESPACE " " + IDENT "foo" + WHITESPACE "\n " + SYSID_KW "sysid" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__create_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_view_ok.snap new file mode 100644 index 00000000..aee0d9ef --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__create_view_ok.snap @@ -0,0 +1,520 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/create_view.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "vista" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + STRING "'Hello World'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "vista" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + TEXT_KW "text" + WHITESPACE " " + LITERAL + STRING "'Hello World'" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "hello" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "comedies" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "films" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Comedy'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "universal_comedies" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "comedies" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "classification" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'U'" + WHITESPACE "\n " + WITH_KW "WITH" + WHITESPACE " " + LOCAL_KW "LOCAL" + WHITESPACE " " + CHECK_KW "CHECK" + WHITESPACE " " + OPTION_KW "OPTION" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "pg_comedies" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "comedies" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "classification" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'PG'" + WHITESPACE "\n " + WITH_KW "WITH" + WHITESPACE " " + CASCADED_KW "CASCADED" + WHITESPACE " " + CHECK_KW "CHECK" + WHITESPACE " " + OPTION_KW "OPTION" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "comedies" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + STAR "*" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "country_code_to_name" + ARG_LIST + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "country_code" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "country" + COMMA "," + WHITESPACE "\n " + TARGET + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "r" + DOT "." + NAME_REF + IDENT "rating" + R_PAREN ")" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "user_ratings" + WHITESPACE " " + ALIAS + NAME + IDENT "r" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "r" + DOT "." + NAME_REF + IDENT "film_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "id" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "avg_rating" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "films" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Comedy'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + RECURSIVE_KW "RECURSIVE" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "public" + DOT "." + PATH_SEGMENT + NAME + IDENT "nums_1_100" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "n" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + COMPOUND_SELECT + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "n" + PLUS "+" + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "nums_1_100" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "n" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- complete_syntax" + WHITESPACE "\n" + CREATE_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + TEMP_KW "temp" + WHITESPACE " " + RECURSIVE_KW "recursive" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n" + CONSTRAINT_STORAGE_PARAMS + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE "\n" + AS_KW "as" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_VIEW_STMT + CREATE_KW "create" + WHITESPACE " " + TEMPORARY_KW "temporary" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE "\n" + AS_KW "as" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + WHITESPACE "\n" + WITH_KW "with" + WHITESPACE " " + LOCAL_KW "local" + WHITESPACE " " + CHECK_KW "check" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__deallocate_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__deallocate_ok.snap new file mode 100644 index 00000000..416bce95 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__deallocate_ok.snap @@ -0,0 +1,28 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/deallocate.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + DEALLOCATE_STMT + DEALLOCATE_KW "deallocate" + WHITESPACE " " + PREPARE_KW "prepare" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + DEALLOCATE_STMT + DEALLOCATE_KW "deallocate" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + DEALLOCATE_STMT + DEALLOCATE_KW "deallocate" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__declare_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__declare_ok.snap new file mode 100644 index 00000000..eaf95d3c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__declare_ok.snap @@ -0,0 +1,116 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/declare.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + DECLARE_STMT + DECLARE_KW "DECLARE" + WHITESPACE " " + NAME + IDENT "cursor_name" + WHITESPACE " " + CURSOR_KW "CURSOR" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DECLARE_STMT + DECLARE_KW "declare" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + BINARY_KW "binary" + WHITESPACE " " + INSENSITIVE_KW "insensitive" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + SCROLL_KW "scroll" + WHITESPACE " " + CURSOR_KW "cursor" + WHITESPACE " " + WITHOUT_KW "without" + WHITESPACE " " + HOLD_KW "hold" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + DECLARE_STMT + DECLARE_KW "declare" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " \n" + BINARY_KW "binary" + WHITESPACE " \n" + ASENSITIVE_KW "asensitive" + WHITESPACE " \n" + SCROLL_KW "scroll" + WHITESPACE " \n" + CURSOR_KW "cursor" + WHITESPACE " \n " + WITH_KW "with" + WHITESPACE " " + HOLD_KW "hold" + WHITESPACE " \n " + FOR_KW "for" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + DECLARE_STMT + DECLARE_KW "declare" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + CURSOR_KW "cursor" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__delete_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__delete_ok.snap new file mode 100644 index 00000000..8ba6168c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__delete_ok.snap @@ -0,0 +1,986 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/delete.sql +--- +SOURCE_FILE + COMMENT "-- delete" + WHITESPACE "\n" + COMMENT "-- with where" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "price" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- no where" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- only" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- *" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alias" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using, where, return" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "a" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " \n" + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + ALIAS + NAME + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "order_items" + WHITESPACE " " + ALIAS + NAME + IDENT "oi" + WHITESPACE "\n " + JOIN + LEFT_KW "left" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "orders" + WHITESPACE " " + ALIAS + NAME + IDENT "o" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "oi" + DOT "." + NAME_REF + IDENT "order_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "o" + DOT "." + NAME_REF + IDENT "id" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "user_sessions" + WHITESPACE " " + IDENT "us" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "users" + WHITESPACE " " + ALIAS + NAME + IDENT "u" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "max" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "login_time" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "last_login" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "login_history" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "lh" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- where return" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- returning" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees" + WHITESPACE " " + IDENT "e" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "department_id" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "department_id" + WHITESPACE " \n " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "departments" + WHITESPACE " \n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "budget" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "50000" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + RETURNING_KW "returning" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "employee_id" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "department_id" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cursor" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "invoices" + WHITESPACE " \n" + WHERE_KW "where" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + IDENT "invoice_cursor" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- returning" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " \n" + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "foo" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "foo" + DOT "." + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- with" + WHITESPACE "\n" + DELETE_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "q" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "a" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "q" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "a" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + IDENT "id" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + RECURSIVE_KW "recursive" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "q" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "a" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "q" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "a" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + IDENT "id" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- nested" + WHITESPACE "\n" + DELETE_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t2" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "t2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg_docs" + WHITESPACE "\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "producers" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "producer_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "producers" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "producers" + DOT "." + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "producer_id" + WHITESPACE " " + IN_KW "IN" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "id" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "producers" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'foo'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "kind" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + STRING "'Musical'" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tasks" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "status" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'DONE'" + WHITESPACE " " + RETURNING_KW "RETURNING" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tasks" + WHITESPACE " " + WHERE_KW "WHERE" + WHITESPACE " " + CURRENT_KW "CURRENT" + WHITESPACE " " + OF_KW "OF" + WHITESPACE " " + IDENT "c_tasks" + SEMICOLON ";" + WHITESPACE "\n\n" + DELETE_STMT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "delete_batch" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "ctid" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "user_logs" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "l" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "status" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'archived'" + WHITESPACE "\n " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "creation_date" + WHITESPACE "\n " + LOCKING_CLAUSE + FOR_KW "FOR" + WHITESPACE " " + UPDATE_KW "UPDATE" + WHITESPACE "\n " + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "10000" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "user_logs" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + IDENT "dl" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "delete_batch" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "del" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "dl" + DOT "." + NAME_REF + IDENT "ctid" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "del" + DOT "." + NAME_REF + IDENT "ctid" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__discard_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__discard_ok.snap new file mode 100644 index 00000000..fd94cdef --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__discard_ok.snap @@ -0,0 +1,37 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/discard.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + DISCARD_STMT + DISCARD_KW "DISCARD" + WHITESPACE " " + ALL_KW "ALL" + SEMICOLON ";" + WHITESPACE "\n" + DISCARD_STMT + DISCARD_KW "DISCARD" + WHITESPACE " " + PLANS_KW "PLANS" + SEMICOLON ";" + WHITESPACE "\n" + DISCARD_STMT + DISCARD_KW "DISCARD" + WHITESPACE " " + SEQUENCES_KW "SEQUENCES" + SEMICOLON ";" + WHITESPACE "\n" + DISCARD_STMT + DISCARD_KW "DISCARD" + WHITESPACE " " + TEMPORARY_KW "TEMPORARY" + SEMICOLON ";" + WHITESPACE "\n" + DISCARD_STMT + DISCARD_KW "DISCARD" + WHITESPACE " " + TEMP_KW "TEMP" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__do_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__do_ok.snap new file mode 100644 index 00000000..43c3edb5 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__do_ok.snap @@ -0,0 +1,27 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/do.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + DO_STMT + DO_KW "DO" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$DECLARE r record;\nBEGIN\n FOR r IN SELECT table_schema, table_name FROM information_schema.tables\n WHERE table_type = 'VIEW' AND table_schema = 'public'\n LOOP\n EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';\n END LOOP;\nEND$$" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- do_with_language" + WHITESPACE "\n" + DO_STMT + DO_KW "do" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + IDENT "plpgsql" + WHITESPACE " " + LITERAL + STRING "'select 1'" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_access_method_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_access_method_ok.snap new file mode 100644 index 00000000..7d516313 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_access_method_ok.snap @@ -0,0 +1,56 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_access_method.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_ACCESS_METHOD_STMT + DROP_KW "drop" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_ACCESS_METHOD_STMT + DROP_KW "drop" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_ACCESS_METHOD_STMT + DROP_KW "drop" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + METHOD_KW "method" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_aggregate_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_aggregate_ok.snap new file mode 100644 index 00000000..d336ebe8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_aggregate_ok.snap @@ -0,0 +1,243 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_aggregate.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_AGGREGATE_STMT + DROP_KW "drop" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + CALL_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_AGGREGATE_STMT + DROP_KW "drop" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " \n " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " \n " + CALL_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + COMMA "," + WHITESPACE " \n " + CALL_EXPR + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + COMMA "," + WHITESPACE " \n " + CALL_EXPR + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "bar" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n " + R_PAREN ")" + COMMA "," + WHITESPACE " \n " + CALL_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggregate" + WHITESPACE "\n" + DROP_AGGREGATE_STMT + DROP_KW "drop" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + CALL_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_AGGREGATE_STMT + DROP_KW "drop" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + CALL_EXPR + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_cast_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_cast_ok.snap new file mode 100644 index 00000000..f637fc8d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_cast_ok.snap @@ -0,0 +1,99 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_cast.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_CAST_STMT + DROP_KW "drop" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_CAST_STMT + DROP_KW "drop" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_CAST_STMT + DROP_KW "drop" + WHITESPACE " " + CAST_KW "cast" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_collation_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_collation_ok.snap new file mode 100644 index 00000000..3cb928aa --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_collation_ok.snap @@ -0,0 +1,61 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_collation.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_COLLATION_STMT + DROP_KW "drop" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_COLLATION_STMT + DROP_KW "drop" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_COLLATION_STMT + DROP_KW "drop" + WHITESPACE " " + COLLATION_KW "collation" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_conversion_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_conversion_ok.snap new file mode 100644 index 00000000..1ba7c4eb --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_conversion_ok.snap @@ -0,0 +1,66 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_conversion.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_CONVERSION_STMT + DROP_KW "drop" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_CONVERSION_STMT + DROP_KW "drop" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_CONVERSION_STMT + DROP_KW "drop" + WHITESPACE " " + CONVERSION_KW "conversion" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_database_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_database_ok.snap new file mode 100644 index 00000000..a699c1e7 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_database_ok.snap @@ -0,0 +1,86 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_database.sql +--- +SOURCE_FILE + COMMENT "-- drop_database" + WHITESPACE "\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + FORCE_KW "force" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + WHITESPACE " " + FORCE_KW "force" + COMMA "," + WHITESPACE " " + FORCE_KW "force" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "\"table_name\"" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "\"table_name\"" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_DATABASE_STMT + DROP_KW "drop" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "\"table_name\"" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_domain_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_domain_ok.snap new file mode 100644 index 00000000..85d087cd --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_domain_ok.snap @@ -0,0 +1,85 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_domain.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_DOMAIN_STMT + DROP_KW "drop" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_DOMAIN_STMT + DROP_KW "drop" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_DOMAIN_STMT + DROP_KW "drop" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_event_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_event_trigger_ok.snap new file mode 100644 index 00000000..922af47d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_event_trigger_ok.snap @@ -0,0 +1,56 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_event_trigger.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_EVENT_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_EVENT_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_EVENT_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_extension_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_extension_ok.snap new file mode 100644 index 00000000..00ca4762 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_extension_ok.snap @@ -0,0 +1,66 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_extension.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_EXTENSION_STMT + DROP_KW "drop" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_EXTENSION_STMT + DROP_KW "drop" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_EXTENSION_STMT + DROP_KW "drop" + WHITESPACE " " + EXTENSION_KW "extension" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_data_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_data_ok.snap new file mode 100644 index 00000000..bab4afb0 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_data_ok.snap @@ -0,0 +1,78 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_foreign_data.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_FOREIGN_DATA_WRAPPER_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_FOREIGN_DATA_WRAPPER_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_FOREIGN_DATA_WRAPPER_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_table_ok.snap new file mode 100644 index 00000000..6718ac30 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_foreign_table_ok.snap @@ -0,0 +1,91 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_foreign_table.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_FOREIGN_TABLE_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_FOREIGN_TABLE_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_FOREIGN_TABLE_STMT + DROP_KW "drop" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_function_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_function_ok.snap new file mode 100644 index 00000000..8ca0420b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_function_ok.snap @@ -0,0 +1,109 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_function.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_FUNCTION_STMT + DROP_KW "drop" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_FUNCTION_STMT + DROP_KW "drop" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "f" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_FUNCTION_STMT + DROP_KW "drop" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_group_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_group_ok.snap new file mode 100644 index 00000000..f5cd174d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_group_ok.snap @@ -0,0 +1,40 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_group.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_GROUP_STMT + DROP_KW "drop" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_GROUP_STMT + DROP_KW "drop" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_index_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_index_ok.snap new file mode 100644 index 00000000..659053e3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_index_ok.snap @@ -0,0 +1,118 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_index.sql +--- +SOURCE_FILE + COMMENT "-- drop_index" + WHITESPACE "\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "d" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"field_name_idx\"" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "drop" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"field_name_idx\"" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_language_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_language_ok.snap new file mode 100644 index 00000000..146e3ab6 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_language_ok.snap @@ -0,0 +1,52 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_language.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_LANGUAGE_STMT + DROP_KW "drop" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_LANGUAGE_STMT + DROP_KW "drop" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_LANGUAGE_STMT + DROP_KW "drop" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_materialized_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_materialized_view_ok.snap new file mode 100644 index 00000000..aea3419a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_materialized_view_ok.snap @@ -0,0 +1,91 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_materialized_view.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_MATERIALIZED_VIEW_STMT + DROP_KW "drop" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_MATERIALIZED_VIEW_STMT + DROP_KW "drop" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_MATERIALIZED_VIEW_STMT + DROP_KW "drop" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_class_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_class_ok.snap new file mode 100644 index 00000000..e65fd8b4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_class_ok.snap @@ -0,0 +1,87 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_operator_class.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_OPERATOR_CLASS_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_OPERATOR_CLASS_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_OPERATOR_CLASS_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CLASS_KW "class" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_family_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_family_ok.snap new file mode 100644 index 00000000..d097f436 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_family_ok.snap @@ -0,0 +1,87 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_operator_family.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_OPERATOR_FAMILY_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "n" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_OPERATOR_FAMILY_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "f" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_OPERATOR_FAMILY_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + FAMILY_KW "family" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "i" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_ok.snap new file mode 100644 index 00000000..a9554b09 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_operator_ok.snap @@ -0,0 +1,333 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_operator.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CARET "^" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + CARET "^" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "f" + DOT "." + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- unary" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + WHITESPACE " " + L_PAREN "(" + NONE_KW "none" + COMMA "," + WHITESPACE " " + BIT_TYPE + BIT_KW "bit" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + WHITESPACE " " + L_PAREN "(" + NONE_KW "none" + COMMA "," + WHITESPACE " " + BIT_TYPE + BIT_KW "bit" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CARET "^" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + L_PAREN "(" + NONE_KW "NONE" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CUSTOM_OP + AT "@" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CUSTOM_OP + POUND "#" + POUND "#" + WHITESPACE " " + L_PAREN "(" + NONE_KW "none" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + R_PAREN ")" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + CUSTOM_OP + BANG "!" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- non_default_operator" + WHITESPACE "\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + CUSTOM_OP + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + BANG "!" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_OPERATOR_STMT + DROP_KW "drop" + WHITESPACE " " + OPERATOR_KW "operator" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + CUSTOM_OP + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + AT "@" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_owned_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_owned_ok.snap new file mode 100644 index 00000000..44fb9eb3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_owned_ok.snap @@ -0,0 +1,52 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_owned.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_OWNED_STMT + DROP_KW "drop" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_OWNED_STMT + DROP_KW "drop" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "a" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + COMMA "," + WHITESPACE " " + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_OWNED_STMT + DROP_KW "drop" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SESSION_USER_KW "session_user" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_policy_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_policy_ok.snap new file mode 100644 index 00000000..4372d3c2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_policy_ok.snap @@ -0,0 +1,76 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_policy.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_POLICY_STMT + DROP_KW "drop" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_POLICY_STMT + DROP_KW "drop" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t_name" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_POLICY_STMT + DROP_KW "drop" + WHITESPACE " " + POLICY_KW "policy" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_procedure_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_procedure_ok.snap new file mode 100644 index 00000000..e488a920 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_procedure_ok.snap @@ -0,0 +1,109 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_procedure.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_PROCEDURE_STMT + DROP_KW "drop" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_PROCEDURE_STMT + DROP_KW "drop" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "f" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_PROCEDURE_STMT + DROP_KW "drop" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_publication_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_publication_ok.snap new file mode 100644 index 00000000..81f14060 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_publication_ok.snap @@ -0,0 +1,66 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_publication.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_PUBLICATION_STMT + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_PUBLICATION_STMT + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_PUBLICATION_STMT + DROP_KW "drop" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_role_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_role_ok.snap new file mode 100644 index 00000000..3301204d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_role_ok.snap @@ -0,0 +1,62 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_role.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_ROLE_STMT + DROP_KW "drop" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_ROLE_STMT + DROP_KW "drop" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n" + DROP_ROLE_STMT + DROP_KW "drop" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_routine_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_routine_ok.snap new file mode 100644 index 00000000..560df4fb --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_routine_ok.snap @@ -0,0 +1,109 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_routine.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_ROUTINE_STMT + DROP_KW "drop" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_ROUTINE_STMT + DROP_KW "drop" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "c" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "f" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + PATH_TYPE + TEXT_KW "text" + R_PAREN ")" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_ROUTINE_STMT + DROP_KW "drop" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_rule_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_rule_ok.snap new file mode 100644 index 00000000..731a9451 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_rule_ok.snap @@ -0,0 +1,77 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_rule.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_RULE_STMT + DROP_KW "drop" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_RULE_STMT + DROP_KW "drop" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t_name" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_RULE_STMT + DROP_KW "drop" + WHITESPACE " " + RULE_KW "rule" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "r" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_sequence_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_sequence_ok.snap new file mode 100644 index 00000000..3805202f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_sequence_ok.snap @@ -0,0 +1,85 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_sequence.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_SEQUENCE_STMT + DROP_KW "drop" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_SEQUENCE_STMT + DROP_KW "drop" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SEQUENCE_STMT + DROP_KW "drop" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_server_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_server_ok.snap new file mode 100644 index 00000000..8eec386d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_server_ok.snap @@ -0,0 +1,66 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_server.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_SERVER_STMT + DROP_KW "drop" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_SERVER_STMT + DROP_KW "drop" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SERVER_STMT + DROP_KW "drop" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_statistics_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_statistics_ok.snap new file mode 100644 index 00000000..53109791 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_statistics_ok.snap @@ -0,0 +1,85 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_statistics.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_STATISTICS_STMT + DROP_KW "drop" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_STATISTICS_STMT + DROP_KW "drop" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_STATISTICS_STMT + DROP_KW "drop" + WHITESPACE " " + STATISTICS_KW "statistics" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_subscription_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_subscription_ok.snap new file mode 100644 index 00000000..7d8be720 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_subscription_ok.snap @@ -0,0 +1,50 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_subscription.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_SUBSCRIPTION_STMT + DROP_KW "drop" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_SUBSCRIPTION_STMT + DROP_KW "drop" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SUBSCRIPTION_STMT + DROP_KW "drop" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_table_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_table_ok.snap new file mode 100644 index 00000000..ca913f09 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_table_ok.snap @@ -0,0 +1,148 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_table.sql +--- +SOURCE_FILE + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "some_table" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "some_table" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- duo" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- if exists" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cascade" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- restrict" + WHITESPACE "\n" + DROP_TABLE + DROP_KW "drop" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_tablespace_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_tablespace_ok.snap new file mode 100644 index 00000000..809d3386 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_tablespace_ok.snap @@ -0,0 +1,32 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_tablespace.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TABLESPACE_STMT + DROP_KW "drop" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TABLESPACE_STMT + DROP_KW "drop" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_config_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_config_ok.snap new file mode 100644 index 00000000..78636b0d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_config_ok.snap @@ -0,0 +1,59 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_text_search_config.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TEXT_SEARCH_CONFIG_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TEXT_SEARCH_CONFIG_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- restrict" + WHITESPACE "\n" + DROP_TEXT_SEARCH_CONFIG_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + CONFIGURATION_KW "configuration" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_dict_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_dict_ok.snap new file mode 100644 index 00000000..c262f488 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_dict_ok.snap @@ -0,0 +1,59 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_text_search_dict.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TEXT_SEARCH_DICT_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TEXT_SEARCH_DICT_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- restrict" + WHITESPACE "\n" + DROP_TEXT_SEARCH_DICT_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + DICTIONARY_KW "dictionary" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_parser_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_parser_ok.snap new file mode 100644 index 00000000..8de2e9c3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_parser_ok.snap @@ -0,0 +1,59 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_text_search_parser.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TEXT_SEARCH_PARSER_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TEXT_SEARCH_PARSER_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- restrict" + WHITESPACE "\n" + DROP_TEXT_SEARCH_PARSER_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + PARSER_KW "parser" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_template_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_template_ok.snap new file mode 100644 index 00000000..0ab25aea --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_text_search_template_ok.snap @@ -0,0 +1,59 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_text_search_template.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TEXT_SEARCH_TEMPLATE_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TEXT_SEARCH_TEMPLATE_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- restrict" + WHITESPACE "\n" + DROP_TEXT_SEARCH_TEMPLATE_STMT + DROP_KW "drop" + WHITESPACE " " + TEXT_KW "text" + WHITESPACE " " + SEARCH_KW "search" + WHITESPACE " " + TEMPLATE_KW "template" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_transform_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_transform_ok.snap new file mode 100644 index 00000000..e6fff5c5 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_transform_ok.snap @@ -0,0 +1,80 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_transform.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_TRANSFORM_STMT + DROP_KW "drop" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_TRANSFORM_STMT + DROP_KW "drop" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type_args" + WHITESPACE "\n" + DROP_TRANSFORM_STMT + DROP_KW "drop" + WHITESPACE " " + TRANSFORM_KW "transform" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "l" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_trigger_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_trigger_ok.snap new file mode 100644 index 00000000..ab245f10 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_trigger_ok.snap @@ -0,0 +1,114 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_trigger.sql +--- +SOURCE_FILE + DROP_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tr" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tr" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tr" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tr" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TRIGGER_STMT + DROP_KW "drop" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tr" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_type_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_type_ok.snap new file mode 100644 index 00000000..382636d7 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_type_ok.snap @@ -0,0 +1,132 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_type.sql +--- +SOURCE_FILE + COMMENT "-- drop_type" + WHITESPACE "\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TYPE_STMT + DROP_KW "drop" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_mapping_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_mapping_ok.snap new file mode 100644 index 00000000..e32254a1 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_mapping_ok.snap @@ -0,0 +1,48 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_user_mapping.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_USER_MAPPING_STMT + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_USER_MAPPING_STMT + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + MAPPING_KW "mapping" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "some_server_name" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_ok.snap new file mode 100644 index 00000000..34c185f2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_user_ok.snap @@ -0,0 +1,40 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_user.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + DROP_USER_STMT + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_USER_STMT + DROP_KW "drop" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_view_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_view_ok.snap new file mode 100644 index 00000000..c0ec753a --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__drop_view_ok.snap @@ -0,0 +1,63 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/drop_view.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + DROP_VIEW_STMT + DROP_KW "DROP" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "kinds" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + DROP_VIEW_STMT + DROP_KW "drop" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_VIEW_STMT + DROP_KW "drop" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__execute_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__execute_ok.snap new file mode 100644 index 00000000..ab7f7943 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__execute_ok.snap @@ -0,0 +1,54 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/execute.sql +--- +SOURCE_FILE + COMMENT "-- execute" + WHITESPACE "\n" + EXECUTE_STMT + EXECUTE_KW "EXECUTE" + WHITESPACE " " + NAME_REF + IDENT "fooplan" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Hunter Valley'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'t'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "200.00" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + EXECUTE_STMT + EXECUTE_KW "EXECUTE" + WHITESPACE " " + NAME_REF + IDENT "usrrptplan" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + NAME_REF + CURRENT_DATE_KW "current_date" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + EXECUTE_STMT + EXECUTE_KW "EXECUTE" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__explain_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__explain_ok.snap new file mode 100644 index 00000000..fa58637c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__explain_ok.snap @@ -0,0 +1,620 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/explain.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "explain" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- explain_analyze" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "explain" + WHITESPACE " " + ANALYZE_KW "analyze" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all_options" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "explain" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + ANALYZE_KW "analyze" + COMMA "," + WHITESPACE "\n " + VERBOSE_KW "verbose" + COMMA "," + WHITESPACE "\n " + IDENT "costs" + COMMA "," + WHITESPACE " \n " + IDENT "costs" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " \n " + IDENT "costs" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE " \n " + IDENT "settings" + COMMA "," + WHITESPACE "\n " + IDENT "generic_plan" + COMMA "," + WHITESPACE "\n " + IDENT "buffers" + COMMA "," + WHITESPACE "\n " + IDENT "serialize" + COMMA "," + WHITESPACE "\n " + IDENT "serialize" + WHITESPACE " " + NONE_KW "none" + COMMA "," + WHITESPACE "\n " + IDENT "serialize" + WHITESPACE " " + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + IDENT "serialize" + WHITESPACE " " + BINARY_KW "binary" + COMMA "," + WHITESPACE "\n " + IDENT "wal" + COMMA "," + WHITESPACE "\n " + IDENT "timing" + COMMA "," + WHITESPACE "\n " + IDENT "summary" + COMMA "," + WHITESPACE "\n " + IDENT "memory" + COMMA "," + WHITESPACE "\n " + FORMAT_KW "format" + WHITESPACE " " + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + FORMAT_KW "format" + WHITESPACE " " + XML_KW "xml" + COMMA "," + WHITESPACE "\n " + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE "\n " + FORMAT_KW "format" + WHITESPACE " " + IDENT "yaml" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_1" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + FORMAT_KW "FORMAT" + WHITESPACE " " + JSON_KW "JSON" + R_PAREN ")" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_2" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_3" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + FORMAT_KW "FORMAT" + WHITESPACE " " + IDENT "YAML" + R_PAREN ")" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + EQ "=" + LITERAL + STRING "'4'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_4" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + IDENT "COSTS" + WHITESPACE " " + LITERAL + FALSE_KW "FALSE" + R_PAREN ")" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_5" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "i" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_6" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "PREPARE" + WHITESPACE " " + NAME + IDENT "query" + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "test" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + PARAM "$1" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + PARAM "$2" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + ANALYZE_KW "ANALYZE" + WHITESPACE " " + EXECUTE_STMT + EXECUTE_KW "EXECUTE" + WHITESPACE " " + NAME_REF + IDENT "query" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "200" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_7" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + IDENT "GENERIC_PLAN" + R_PAREN ")" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "test" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + PARAM "$1" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + PARAM "$2" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_8" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + IDENT "GENERIC_PLAN" + R_PAREN ")" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "test" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + LITERAL + PARAM "$1" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + CAST_EXPR + LITERAL + PARAM "$2" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- parens_select" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "explain" + WHITESPACE " " + ANALYZE_KW "analyze" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- parens_values" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "explain" + WHITESPACE " " + ANALYZE_KW "analyze" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__fetch_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__fetch_ok.snap new file mode 100644 index 00000000..113fca84 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__fetch_ok.snap @@ -0,0 +1,220 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/fetch.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "fetch" + WHITESPACE " " + NEXT_KW "next" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "fetch" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "fetch" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "fetch" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + NEXT_KW "NEXT" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + PRIOR_KW "PRIOR" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + FIRST_KW "FIRST" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + LAST_KW "LAST" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + ABSOLUTE_KW "ABSOLUTE" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + RELATIVE_KW "RELATIVE" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + FETCH_STMT + FETCH_KW "FETCH" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__grant_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__grant_ok.snap new file mode 100644 index 00000000..76d4de3b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__grant_ok.snap @@ -0,0 +1,1485 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/grant.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + INSERT_KW "insert" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + COMMA "," + WHITESPACE " " + DELETE_KW "delete" + COMMA "," + WHITESPACE " " + TRUNCATE_KW "truncate" + COMMA "," + WHITESPACE " " + REFERENCES_KW "references" + COMMA "," + WHITESPACE " " + TRIGGER_KW "trigger" + COMMA "," + WHITESPACE " " + IDENT "maintain" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_table" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE "\n " + GRANTED_KW "granted" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "public" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_all_tables" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- columns" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + INSERT_KW "insert" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + UPDATE_KW "update" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + REFERENCES_KW "references" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- sequence" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- database" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + CREATE_KW "create" + COMMA "," + WHITESPACE " " + IDENT "connect" + COMMA "," + WHITESPACE " " + TEMPORARY_KW "temporary" + COMMA "," + WHITESPACE " " + TEMP_KW "temp" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- domain" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_data" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_server" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "z" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + FUNCTIONS_KW "functions" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PROCEDURES_KW "procedures" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + ROUTINES_KW "routines" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- language" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- large_object" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1012" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1231" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1012" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1231" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- param" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + BEGIN_KW "begin" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + BEGIN_KW "begin" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- edge_case" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE " \n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " \n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE " \n\n" + COMMENT "-- schema" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + CREATE_KW "create" + COMMA "," + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + IDENT "public" + COMMA "," + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + IDENT "foo" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + COMMA "," + WHITESPACE " " + SESSION_USER_KW "session_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- tablespace" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type_" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- option" + WHITESPACE "\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + ADMIN_KW "admin" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + COMMA "," + WHITESPACE " " + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE "\n " + WITH_KW "with" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + OPTION_KW "option" + SEMICOLON ";" + WHITESPACE "\n\n" + GRANT_STMT + GRANT_KW "grant" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + TO_KW "to" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__import_foreign_schema_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__import_foreign_schema_ok.snap new file mode 100644 index 00000000..786154e7 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__import_foreign_schema_ok.snap @@ -0,0 +1,206 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/import_foreign_schema.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "import" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + INTO_KW "into" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- except" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "import" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "some_schema_name" + WHITESPACE "\n " + EXCEPT_KW "EXCEPT" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "t1" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "t2" + R_PAREN ")" + WHITESPACE "\n " + FROM_KW "FROM" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "server_name" + WHITESPACE "\n " + INTO_KW "INTO" + WHITESPACE " " + NAME_REF + IDENT "local_schema" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- options" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "import" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE "\n " + INTO_KW "into" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "foo" + WHITESPACE " " + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- options_multi" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "import" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE "\n " + INTO_KW "into" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "foo" + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_1" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "IMPORT" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + SCHEMA_KW "SCHEMA" + WHITESPACE " " + NAME_REF + IDENT "foreign_films" + WHITESPACE "\n " + FROM_KW "FROM" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "film_server" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + NAME_REF + IDENT "films" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_2" + WHITESPACE "\n" + IMPORT_FOREIGN_SCHEMA + IMPORT_KW "IMPORT" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + SCHEMA_KW "SCHEMA" + WHITESPACE " " + NAME_REF + IDENT "foreign_films" + WHITESPACE " " + LIMIT_KW "LIMIT" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "actors" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "directors" + R_PAREN ")" + WHITESPACE "\n " + FROM_KW "FROM" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "film_server" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + NAME_REF + IDENT "films" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_err.snap new file mode 100644 index 00000000..14704039 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_err.snap @@ -0,0 +1,171 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/insert.sql +--- +SOURCE_FILE + COMMENT "-- missing comma in column list" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + CONFLICT_KW "conflict" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- missing column in column list & trailing comma" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + ERROR + COMMA "," + COLUMN + NAME_REF + IDENT "c" + ERROR + COMMA "," + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + CONFLICT_KW "conflict" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- missing comma in values & trailing comma" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "4" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "5" + WHITESPACE " " + LITERAL + INT_NUMBER "6" + ERROR + COMMA "," + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + CONFLICT_KW "conflict" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@51: expected COMMA +ERROR@168: missing column +ERROR@170: unexpected trailing comma +ERROR@301: expected COMMA +ERROR@304: unexpected trailing comma diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_ok.snap new file mode 100644 index 00000000..48292f0c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__insert_ok.snap @@ -0,0 +1,1308 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/insert.sql +--- +SOURCE_FILE + COMMENT "-- insert" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Cheese'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "9.99" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "product_no" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "price" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Cheese'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "9.99" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "price" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "product_no" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'Cheese'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "9.99" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + VALUES_KW "values" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "product_no" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "price" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE "\n " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Cheese'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "9.99" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Bread'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.99" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Milk'" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "2.99" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "product_no" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "price" + R_PAREN ")" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "product_no" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "price" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "new_products" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "release_date" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'today'" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- schema_from_docs" + WHITESPACE "\n" + INSERT_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + RECURSIVE_KW "recursive" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "foo" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n" + OVERRIDING_KW "overriding" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg_docs_examples" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'UA502'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Bananas'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "105" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'1971-07-13'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Comedy'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'82 minutes'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "code" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "date_prod" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "kind" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'T_601'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Yojimbo'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "106" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'1961-06-16'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Drama'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'UA502'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Bananas'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "105" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Comedy'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'82 minutes'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "code" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "date_prod" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "kind" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'T_601'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Yojimbo'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "106" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Drama'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE " " + VALUES_KW "VALUES" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "code" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "date_prod" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "kind" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'B6717'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Tampopo'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "110" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'1985-02-10'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Comedy'" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'HG120'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'The Dinner Game'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "140" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Comedy'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tmp_films" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "date_prod" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + STRING "'2004-05-07'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Create an empty 3x3 gameboard for noughts-and-crosses" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tictactoe" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "game" + COMMA "," + WHITESPACE " " + COLUMN + INDEX_EXPR + INDEX_EXPR + NAME_REF + IDENT "board" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COLON ":" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COLON ":" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'{{\" \",\" \",\" \"},{\" \",\" \",\" \"},{\" \",\" \",\" \"}}'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- The subscripts in the above example aren't really needed" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tictactoe" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "game" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "board" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'{{X,\" \",\" \"},{\" \",O,\" \"},{\" \",X,\" \"}}'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'XYZ Widgets'" + R_PAREN ")" + WHITESPACE "\n " + RETURNING_KW "RETURNING" + WHITESPACE " " + NAME_REF + IDENT "did" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "upd" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "sales_count" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "sales_count" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE "\n " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "sales_person" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "accounts" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Acme Corporation'" + R_PAREN ")" + WHITESPACE "\n " + RETURNING_KW "RETURNING" + WHITESPACE " " + STAR "*" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees_log" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + CURRENT_TIMESTAMP_KW "current_timestamp" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "upd" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Gizmo Transglobal'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "6" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Associated Computing, Inc'" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + CONFLICT_KW "CONFLICT" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "did" + R_PAREN ")" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "dname" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "EXCLUDED" + DOT "." + NAME_REF + IDENT "dname" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "7" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Redline GmbH'" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + CONFLICT_KW "CONFLICT" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "did" + R_PAREN ")" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + NOTHING_KW "NOTHING" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Don't update existing distributors based in a certain ZIP code" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "8" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Anvil Distribution'" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + CONFLICT_KW "CONFLICT" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "did" + R_PAREN ")" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + UPDATE_KW "UPDATE" + WHITESPACE "\n " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "dname" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "EXCLUDED" + DOT "." + NAME_REF + IDENT "dname" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "' (formerly '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + IDENT "dname" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "')'" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + IDENT "zipcode" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + STRING "'21201'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Name a constraint directly in the statement (uses associated" + WHITESPACE "\n" + COMMENT "-- index to arbitrate taking the DO NOTHING action)" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "9" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Antwerp Design'" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + CONFLICT_KW "CONFLICT" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + CONSTRAINT_KW "CONSTRAINT" + WHITESPACE " " + NAME_REF + IDENT "distributors_pkey" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + NOTHING_KW "NOTHING" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- This statement could infer a partial unique index on \"did\"" + WHITESPACE "\n" + COMMENT "-- with a predicate of \"WHERE is_active\", but it could also" + WHITESPACE "\n" + COMMENT "-- just use a regular unique constraint on \"did\"" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "distributors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "dname" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Conrad International'" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + CONFLICT_KW "CONFLICT" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "did" + R_PAREN ")" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + NAME_REF + IDENT "is_active" + WHITESPACE " " + DO_KW "DO" + WHITESPACE " " + NOTHING_KW "NOTHING" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with schema" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__listen_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__listen_ok.snap new file mode 100644 index 00000000..8d944b21 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__listen_ok.snap @@ -0,0 +1,21 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/listen.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + LISTEN_STMT + LISTEN_KW "listen" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + LISTEN_STMT + LISTEN_KW "LISTEN" + WHITESPACE " " + NAME + IDENT "virtual" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__load_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__load_ok.snap new file mode 100644 index 00000000..ca2b6661 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__load_ok.snap @@ -0,0 +1,14 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/load.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + LOAD_STMT + LOAD_KW "load" + WHITESPACE " " + LITERAL + STRING "'foo'" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__lock_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__lock_ok.snap new file mode 100644 index 00000000..8fa39914 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__lock_ok.snap @@ -0,0 +1,222 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/lock.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_names" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lock_mode" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + ACCESS_KW "access" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + LOCK_STMT + LOCK_KW "lock" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + EXCLUSIVE_KW "exclusive" + WHITESPACE " " + MODE_KW "mode" + WHITESPACE " " + NOWAIT_KW "nowait" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_ok.snap new file mode 100644 index 00000000..e308900c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_ok.snap @@ -0,0 +1,606 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/merge.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aliases_with_as" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "f" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "b" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using_rows_from" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aliases_no_as" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + NAME + IDENT "b" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "b" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_with_star" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table_with_only" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- paren_query" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "id" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "id" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "f" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "bar" + DOT "." + NAME_REF + IDENT "id" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "id" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- when_clauses_dupe" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_pg17_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_pg17_ok.snap new file mode 100644 index 00000000..38758be1 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__merge_pg17_ok.snap @@ -0,0 +1,1441 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/merge_pg17.sql +--- +SOURCE_FILE + WHITESPACE "\n" + COMMENT "-- when_clauses_all" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- when_clauses_all_with_conditions" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "buzz" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- returning_all" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- returning_many" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + IDENT "b" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + MERGE_ACTION_KW "merge_action" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_insert_simple" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + INSERT_KW "insert" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE " " + VALUES_KW "values" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_insert_default" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + INSERT_KW "insert" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + OVERRIDING_KW "overriding" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE " " + VALUES_KW "values" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_insert_values" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + INSERT_KW "insert" + WHITESPACE "\n " + OVERRIDING_KW "overriding" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "default" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + BIN_EXPR + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_update" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "e" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "f" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ROW_KW "row" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "g" + WHITESPACE " " + EQ "=" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "h" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_delete" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DELETE_KW "delete" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DELETE_KW "delete" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_select" + WHITESPACE "\n" + MERGE_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE "\n" + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_1" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "MERGE" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "customer_account" + WHITESPACE " " + ALIAS + NAME + IDENT "ca" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "recent_transactions" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n" + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "ca" + DOT "." + NAME_REF + IDENT "customer_id" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "balance" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "balance" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "transaction_value" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + INSERT_KW "INSERT" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "balance" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "transaction_value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_2" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "MERGE" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "customer_account" + WHITESPACE " " + ALIAS + NAME + IDENT "ca" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "transaction_value" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "recent_transactions" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE "\n" + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "ca" + DOT "." + NAME_REF + IDENT "customer_id" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "balance" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "balance" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "transaction_value" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + INSERT_KW "INSERT" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "balance" + R_PAREN ")" + WHITESPACE "\n " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "transaction_value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_3" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "MERGE" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wines" + WHITESPACE " " + ALIAS + NAME + IDENT "w" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "wine_stock_changes" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + WHITESPACE "\n" + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "winename" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + INSERT_KW "INSERT" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + R_PAREN ")" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "stock" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + DELETE_KW "DELETE" + WHITESPACE "\n" + RETURNING_KW "RETURNING" + WHITESPACE " " + CALL_EXPR + NAME_REF + MERGE_ACTION_KW "merge_action" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc_example_4" + WHITESPACE "\n" + MERGE_STMT + MERGE_KW "MERGE" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wines" + WHITESPACE " " + ALIAS + NAME + IDENT "w" + WHITESPACE "\n" + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "new_wine_list" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + WHITESPACE "\n" + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "winename" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + TARGET_KW "TARGET" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + INSERT_KW "INSERT" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" + R_PAREN ")" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + NEQ "!=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "stock" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE "\n" + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + SOURCE_KW "SOURCE" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + DELETE_KW "DELETE" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__misc_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__misc_ok.snap new file mode 100644 index 00000000..9e346c43 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__misc_ok.snap @@ -0,0 +1,6680 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/misc.sql +--- +SOURCE_FILE + CREATE_TABLE + COMMENT "-- https://www.timescale.com/blog/boosting-postgres-insert-performance/" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sensors" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "sensorid" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "ts" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "TIMESTAMPTZ" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "FLOAT8" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "sensors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "ts" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "sensorid" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + VALUE_KW "value" + R_PAREN ")" + WHITESPACE " \n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " \n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "unnest" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + CAST_EXPR + LITERAL + PARAM "$1" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE " \n " + CAST_EXPR + LITERAL + PARAM "$2" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE " \n " + CAST_EXPR + LITERAL + PARAM "$3" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + L_BRACK "[" + R_BRACK "]" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "sensors" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "sensorid" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "ts" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + VALUE_KW "value" + R_PAREN ")" + WHITESPACE "\n" + SELECT + VALUES_KW "VALUES" + WHITESPACE " \n " + L_PAREN "(" + LITERAL + PARAM "$1" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$2" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$3" + R_PAREN ")" + COMMA "," + WHITESPACE " \n " + L_PAREN "(" + LITERAL + PARAM "$4" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$5" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$6" + R_PAREN ")" + COMMA "," + WHITESPACE " \n " + COMMENT "-- ..., " + WHITESPACE "\n " + L_PAREN "(" + LITERAL + PARAM "$2998" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$2999" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$3000" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.timescale.com/blog/combining-semantic-search-and-full-text-search-in-postgresql-with-cohere-pgvector-and-pgai/" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "movies" + WHITESPACE "\n" + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "embedding" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "ai" + DOT "." + NAME_REF + IDENT "cohere_embed" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'embed-english-v3.0'" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "CONCAT_WS" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'. '" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + COALESCE_KW "COALESCE" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "overview" + COMMA "," + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "input_type" + FAT_ARROW "=>" + LITERAL + STRING "'search_document'" + WHITESPACE "\n " + COMMENT "-- , api_key=>%s" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "api_key" + FAT_ARROW "=>" + LITERAL + PARAM "$1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "embedding" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "overview" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "movies" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "plainto_tsquery" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'english'" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$1" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "query" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "to_tsvector" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'english'" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "title" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "' '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CALL_EXPR + NAME_REF + COALESCE_KW "COALESCE" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "overview" + COMMA "," + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + AT "@" + AT "@" + WHITESPACE " " + NAME_REF + IDENT "query" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "ts_rank_cd" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "to_tsvector" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'english'" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "title" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "' '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CALL_EXPR + NAME_REF + COALESCE_KW "COALESCE" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "overview" + COMMA "," + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + R_PAREN ")" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "query" + R_PAREN ")" + WHITESPACE " " + DESC_KW "DESC" + WHITESPACE "\n" + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "query_embedding" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "cohere_embed" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'embed-english-v3.0'" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$1" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "_input_type" + FAT_ARROW "=>" + LITERAL + STRING "'search_query'" + WHITESPACE "\n " + COMMENT "-- , _api_key=>%s" + WHITESPACE "\n " + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "_api_key" + FAT_ARROW "=>" + LITERAL + PARAM "$2" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "embedding" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "overview" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "movies" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "query_embedding" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "movies" + DOT "." + NAME_REF + IDENT "embedding" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + EQ "=" + R_ANGLE ">" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "query_embedding" + DOT "." + NAME_REF + IDENT "embedding" + WHITESPACE "\n" + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE "\n " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "x" + DOT "." + NAME_REF + IDENT "\"index\"" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "x" + DOT "." + NAME_REF + DOCUMENT_KW "document" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'text'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "\"text\"" + COMMA "," + WHITESPACE "\n " + TARGET + FIELD_EXPR + NAME_REF + IDENT "x" + DOT "." + NAME_REF + IDENT "relevance_score" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "jsonb_to_recordset" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + BIN_EXPR + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "ai" + DOT "." + NAME_REF + IDENT "cohere_rerank" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'rerank-english-v3.0'" + COMMA "," + WHITESPACE "\n " + COMMENT "-- %s," + WHITESPACE "\n " + LITERAL + PARAM "$1" + COMMA "," + WHITESPACE "\n " + COMMENT "-- %s::jsonb," + WHITESPACE "\n " + CAST_EXPR + LITERAL + PARAM "$2" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + COMMA "," + WHITESPACE "\n " + NAMED_ARG + NAME_REF + IDENT "return_documents" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + COMMENT "-- api_key=>%s" + WHITESPACE "\n " + NAMED_ARG + NAME_REF + IDENT "api_key" + FAT_ARROW "=>" + LITERAL + PARAM "$3" + WHITESPACE "\n " + R_PAREN ")" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + LITERAL + STRING "'results'" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "x" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "\"index\"" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "\"document\"" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "relevance_score" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + R_PAREN ")" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "relevance_score" + WHITESPACE " " + DESC_KW "DESC" + WHITESPACE "\n" + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.depesz.com/2024/11/15/grouping-data-into-array-of-sums-fun-with-custom-aggregates/" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + FUNCTION_KW "FUNCTION" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sum_per_hour" + PARAM_LIST + L_PAREN "(" + WHITESPACE " " + PARAM + PARAM_INOUT + INOUT_KW "INOUT" + WHITESPACE " " + NAME + IDENT "p_state" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE " " + PARAM + PARAM_IN + IN_KW "IN" + WHITESPACE " " + NAME + IDENT "p_hour" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + COMMA "," + WHITESPACE " " + PARAM + PARAM_IN + IN_KW "IN" + WHITESPACE " " + NAME + IDENT "p_count" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + RET_TYPE + RETURNS_KW "RETURNS" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + WHITESPACE " " + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "LANGUAGE" + WHITESPACE " " + IDENT "plpgsql" + WHITESPACE " " + AS_FUNC_OPTION + AS_KW "AS" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$\nDECLARE\nBEGIN\n -- sanity checks\n IF p_hour < 0 THEN\n raise exception 'Hour can''t be < 0 : %', p_hour;\n END IF;\n IF p_hour > 23 THEN\n raise exception 'Hour can''t be > 23 : %', p_hour;\n END IF;\n \n -- actual count modification\n p_state[ p_hour ] := p_state[ p_hour ] + p_count;\n \n RETURN;\nEND;\n$$" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum_per_hour" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + LITERAL + STRING "'[0:23]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "15" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_AGGREGATE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sum_per_hour" + PARAM_LIST + L_PAREN "(" + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "int4" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + IDENT "int4" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "sfunc" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "sum_per_hour" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "stype" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "initcond" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'[0:23]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE "\n " + TARGET_LIST + TARGET + NAME_REF + IDENT "category_id" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "object_id" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + LITERAL + STRING "'day'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "interaction_ts" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "interaction_date" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum_per_hour" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + CAST_EXPR + CALL_EXPR + NAME_REF + EXTRACT_KW "EXTRACT" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + STRING "'hour'" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "interaction_ts" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "interaction_count" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + FILTER_CLAUSE + FILTER_KW "FILTER" + WHITESPACE " " + L_PAREN "(" + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "interaction_type" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'a'" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "a_counts" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum_per_hour" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + CAST_EXPR + CALL_EXPR + NAME_REF + EXTRACT_KW "EXTRACT" + ARG_LIST + L_PAREN "(" + WHITESPACE " " + STRING "'hour'" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "interaction_ts" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int4" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "interaction_count" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + FILTER_CLAUSE + FILTER_KW "FILTER" + WHITESPACE " " + L_PAREN "(" + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "interaction_type" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "b_counts" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE "\n " + NAME_REF + IDENT "input_data" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + FUNCTION_KW "FUNCTION" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "sum_hour_arrays" + PARAM_LIST + L_PAREN "(" + WHITESPACE " " + PARAM + PARAM_IN + IN_KW "IN" + WHITESPACE " " + NAME + IDENT "p_left" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE " " + PARAM + PARAM_IN + IN_KW "IN" + WHITESPACE " " + NAME + IDENT "p_right" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + WHITESPACE " " + R_PAREN ")" + WHITESPACE " " + RET_TYPE + RETURNS_KW "RETURNS" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + WHITESPACE " " + FUNC_OPTION_LIST + AS_FUNC_OPTION + AS_KW "AS" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$\nDECLARE\n i int4;\n v_result int8[];\nBEGIN\n FOR i IN 0..23 LOOP\n v_result[i] := p_left[i] + p_right[i];\n END LOOP;\n RETURN v_result;\nEND;\n$$" + WHITESPACE " " + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "LANGUAGE" + WHITESPACE " " + IDENT "plpgsql" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.crunchydata.com/blog/postgres-partitioning-with-a-default-partition" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "col3" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'2024-12-25'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME + IDENT "time_taptest_table_default" + WHITESPACE " " + PARTITION_KW "PARTITION" + WHITESPACE " " + OF_KW "OF" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "col3" + R_PAREN ")" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'2024-12-25'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "partman_test" + DOT "." + NAME_REF + IDENT "time_taptest_table_default" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + TABLE_KW "Table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"partman_test.time_taptest_table_p20241124\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + TABLE_KW "Table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"partman_test.time_taptest_table_default\"" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME + IDENT "time_taptest_table_p20241225" + WHITESPACE " " + PARTITION_KW "PARTITION" + WHITESPACE " " + OF_KW "OF" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + VALUES_KW "VALUES" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-25'" + R_PAREN ")" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-26'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + BEGIN_STMT + BEGIN_KW "BEGIN" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TEMP_KW "TEMP" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "clean_default_temp" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + LIKE_CLAUSE + LIKE_KW "LIKE" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table_default" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "partition_data" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table_default" + WHITESPACE " " + RETURNING_KW "RETURNING" + WHITESPACE " " + STAR "*" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "clean_default_temp" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "col1" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "col2" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "col3" + R_PAREN ")" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "col1" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "col2" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "col3" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "partition_data" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME + IDENT "time_taptest_table_p20241225" + WHITESPACE " " + PARTITION_KW "PARTITION" + WHITESPACE " " + OF_KW "OF" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + VALUES_KW "VALUES" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-25'" + R_PAREN ")" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-26'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + INSERT_STMT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "partition_data" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + DELETE_STMT + DELETE_KW "DELETE" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "clean_default_temp" + WHITESPACE " " + RETURNING_KW "RETURNING" + WHITESPACE " " + STAR "*" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "col1" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "col2" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "col3" + R_PAREN ")" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "col1" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "col2" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "col3" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "partition_data" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_TABLE + DROP_KW "DROP" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "clean_default_temp" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMIT_STMT + COMMIT_KW "COMMIT" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "partman_test" + DOT "." + NAME_REF + IDENT "time_taptest_table_default" + WHITESPACE " " + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "partman_test" + DOT "." + NAME_REF + IDENT "time_taptest_table" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "partman_test" + DOT "." + NAME_REF + IDENT "time_taptest_table_p20241225" + WHITESPACE " " + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "partman" + DOT "." + NAME_REF + IDENT "check_default" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "partman" + DOT "." + NAME_REF + IDENT "check_default" + ARG_LIST + L_PAREN "(" + LITERAL + FALSE_KW "false" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "partman_test" + DOT "." + NAME_REF + IDENT "time_taptest_table_default" + SEMICOLON ";" + WHITESPACE "\n\n" + CALL_STMT + CALL_KW "CALL" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman" + DOT "." + PATH_SEGMENT + NAME + IDENT "partition_data_proc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'partman_test.time_taptest_table'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + VACUUM_STMT + VACUUM_KW "VACUUM" + WHITESPACE " " + ANALYZE_KW "ANALYZE" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "partman_test" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "time_taptest_table" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "partman" + DOT "." + NAME_REF + IDENT "partition_gap_fill" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'partman_test.time_taptest_table'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.crunchydata.com/blog/smarter-postgres-llm-with-retrieval-augmented-generation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "openai" + DOT "." + NAME_REF + IDENT "prompt" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'You are a science fiction expert!'" + COMMA "," + WHITESPACE "\n " + LITERAL + STRING "'What is the Star Trek episode where Deanna and her\n mother are kidnapped?'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "tng" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "title" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "plot" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COPY_STMT + COPY_KW "COPY" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "tng" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "plot" + R_PAREN ")" + WHITESPACE "\n " + FROM_KW "FROM" + WHITESPACE " " + PROGRAM_KW "PROGRAM" + WHITESPACE " " + LITERAL + STRING "'curl https://raw.githubusercontent.com/pramsey/pgsql-openai/refs/heads/main/examples/rag/tng.txt'" + WHITESPACE "\n " + WITH_KW "WITH" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + FORMAT_KW "FORMAT" + WHITESPACE " " + CSV_KW "csv" + COMMA "," + WHITESPACE "\n " + NAME + DELIMITER_KW "DELIMITER" + WHITESPACE " " + LITERAL + ESC_STRING "E'\\t'" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Enable pgvector" + WHITESPACE "\n" + CREATE_EXTENSION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EXTENSION_KW "EXTENSION" + WHITESPACE " " + NAME + IDENT "pgvector" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Add an emedding column to the table" + WHITESPACE "\n" + ALTER_TABLE + ALTER_KW "ALTER" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tng" + WHITESPACE "\n " + ADD_COLUMN + ADD_KW "ADD" + WHITESPACE " " + COLUMN_KW "COLUMN" + WHITESPACE " " + NAME_REF + IDENT "vec" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "vector" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Populate the column with embeddings from an LLM model" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "tng" + WHITESPACE "\n " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "vec" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CAST_EXPR + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "openai" + DOT "." + NAME_REF + IDENT "vector" + ARG_LIST + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "title" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "' -- '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + NAME_REF + IDENT "plot" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "vector" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "title" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tng" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "vec" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "openai" + DOT "." + NAME_REF + IDENT "vector" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'What is the Star Trek episode where Deanna and her mother are kidnapped?'" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "vector" + R_PAREN ")" + WHITESPACE "\n" + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FUNCTION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + OR_REPLACE + OR_KW "OR" + WHITESPACE " " + REPLACE_KW "REPLACE" + WHITESPACE " " + FUNCTION_KW "FUNCTION" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "trektrivia" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "query_text" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + R_PAREN ")" + WHITESPACE "\n " + RET_TYPE + RETURNS_KW "RETURNS" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + WHITESPACE "\n " + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "LANGUAGE" + WHITESPACE " " + LITERAL + STRING "'plpgsql'" + WHITESPACE " " + AS_FUNC_OPTION + AS_KW "AS" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$$\nDECLARE\n query_embedding VECTOR;\n context_chunks TEXT;\nBEGIN\n -- Step 1: Get the embedding vector for the query text\n query_embedding := openai.vector(query_text)::VECTOR;\n\n -- Step 2: Find the 5 closest plot summaries to the query embedding\n -- Step 3: Lump together results into a context lump\n SELECT string_agg('Episode: { Title: ' || title || ' } Summary: {' || plot, E'}}\\n\\n\\n') INTO context_chunks\n FROM (\n SELECT plot, title\n FROM tng\n ORDER BY vec <-> query_embedding\n LIMIT 5\n ) AS similar_plots;\n\n -- Step 4: Run the query against the LLM with the augmented context\n RETURN openai.prompt(context_chunks, query_text);\nEND;\n$$" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "trektrivia" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'What is the Star Trek episode where Deanna and her mother are kidnapped?'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.crunchydata.com/blog/pg_incremental-incremental-data-processing-in-postgres" + WHITESPACE "\n\n" + CREATE_TABLE + COMMENT "/* define the raw data and summary table */" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "event_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bigserial" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "event_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "user_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "response_time" + WHITESPACE " " + DOUBLE_TYPE + DOUBLE_KW "double" + WHITESPACE " " + PRECISION_KW "precision" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "view_counts" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + DAY_KW "day" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "user_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "count" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + DAY_KW "day" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "user_id" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* enable fast range scans on the sequence column */" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "brin" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "event_id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* for demo: generate some random data */" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "event_time" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "response_time" + R_PAREN ")" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "random" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "random" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "generate_series" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "1000000" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* define a sequence pipeline that periodically upserts view counts */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "incremental" + DOT "." + NAME_REF + IDENT "create_sequence_pipeline" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'view-count-pipeline'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'events'" + COMMA "," + WHITESPACE "\n " + LITERAL + DOLLAR_QUOTED_STRING "$$\n insert into view_counts\n select date_trunc('day', event_time), user_id, count(*)\n from events where event_id between $1 and $2\n group by 1, 2\n on conflict (day, user_id) do update set count = view_counts.count + EXCLUDED.count;\n $$" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* get the most active users of today */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "count" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "view_counts" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + DAY_KW "day" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CAST_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + DESC_KW "desc" + WHITESPACE " " + LIMIT_CLAUSE + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "/* create a table with a single JSONB column and a sequence to track new objects */" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events_json" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + GENERATED_CONSTRAINT + GENERATED_KW "generated" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENTITY_KW "identity" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "payload" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events_json" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "brin" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* load some data from a local newline-delimited JSON file */" + WHITESPACE "\n" + COMMENT "-- \\copy events_json (payload) from '2024-12-15-00.json' with (format 'csv', quote e'\\x01', delimiter e'\\x02', escape e'\\x01')" + WHITESPACE "\n\n\n" + COMMENT "/* periodically unpack the new JSON objects into the events table */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "incremental" + DOT "." + NAME_REF + IDENT "create_sequence_pipeline" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'unpack-json-pipeline'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'events_json'" + COMMA "," + WHITESPACE "\n " + LITERAL + DOLLAR_QUOTED_STRING "$$\n insert into events (event_id, event_time, user_id, response_time)\n select\n nextval('events_event_id_seq'),\n (payload->>'created_at')::timestamptz,\n (payload->'actor'->>'id')::bigint,\n (payload->>'response_time')::double precision\n from events_json\n where id between $1 and $2\n $$" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "/* create a table for number of active users per hour */" + WHITESPACE "\n" + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "user_counts" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + HOUR_KW "hour" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "user_count" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + COMMA "," + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "primary" + WHITESPACE " " + KEY_KW "key" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + HOUR_KW "hour" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* enable fast range scans on the event_time column */" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "create" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "brin" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "event_time" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* aggregates a range of 1 hour intervals after an hour has passed */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "incremental" + DOT "." + NAME_REF + IDENT "create_time_interval_pipeline" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'distinct-user-count'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'1 hour'" + COMMA "," + WHITESPACE "\n " + LITERAL + DOLLAR_QUOTED_STRING "$$\n insert into view_counts\n select date_trunc('hour', event_time), count(distinct user_id)\n from events where event_time >= $1 and event_time < $2\n group by 1\n $$" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* get number of active users per hour */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + HOUR_KW "hour" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "user_count" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "user_counts" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* define a function that wraps a COPY TO command to export data */" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "export_events" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + IDENT "start_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE " " + PARAM + NAME + IDENT "end_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE " " + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + IDENT "plpgsql" + WHITESPACE " " + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$function$ begin\n\n /* select all rows in a time range and export them to a Parquet file */\n execute format(\n 'copy (select * from events where event_time >= %L and event_time < %L) to %L',\n start_time, end_time, format('s3://mybucket/events/%s.parquet', start_time::date)\n );\n\nend; $function$" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* export data as 1 file per day, starting at Jan 1st */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "incremental" + DOT "." + NAME_REF + IDENT "create_time_interval_pipeline" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'export-events'" + COMMA "," + WHITESPACE "\n " + LITERAL + STRING "'1 day'" + COMMA "," + WHITESPACE "\n " + LITERAL + STRING "'select export_events($1, $2)'" + COMMA "," + WHITESPACE "\n\n " + NAMED_ARG + NAME_REF + IDENT "source_table_name" + WHITESPACE " " + COLONEQ ":=" + WHITESPACE " " + LITERAL + STRING "'events'" + COMMA "," + WHITESPACE " " + COMMENT "/* wait for writes on events to finish */" + WHITESPACE "\n " + NAMED_ARG + NAME_REF + IDENT "batched" + WHITESPACE " " + COLONEQ ":=" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE " " + COMMENT "/* separate execution for each day */" + WHITESPACE "\n " + NAMED_ARG + NAME_REF + IDENT "start_time" + WHITESPACE " " + COLONEQ ":=" + WHITESPACE " " + LITERAL + STRING "'2024-01-01'" + WHITESPACE " " + COMMENT "/* export all days from Jan 1st now */" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "/* define function that wraps a COPY FROM command to import data */" + WHITESPACE "\n" + CREATE_FUNCTION_STMT + CREATE_KW "create" + WHITESPACE " " + OR_REPLACE + OR_KW "or" + WHITESPACE " " + REPLACE_KW "replace" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "import_events" + PARAM_LIST + L_PAREN "(" + PARAM + NAME + PATH_KW "path" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + WHITESPACE "\n" + RET_TYPE + RETURNS_KW "returns" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "void" + WHITESPACE " " + FUNC_OPTION_LIST + LANGUAGE_FUNC_OPTION + LANGUAGE_KW "language" + WHITESPACE " " + IDENT "plpgsql" + WHITESPACE " " + AS_FUNC_OPTION + AS_KW "as" + WHITESPACE " " + LITERAL + DOLLAR_QUOTED_STRING "$function$ begin\n\n /* load a file into the events table */\n execute format('copy events from %L', path);\n\nend; $function$" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "/* load all the files under a prefix, and automatically load new files, one at a time */" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "incremental" + DOT "." + NAME_REF + IDENT "create_file_list_pipeline" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + LITERAL + STRING "'import-events'" + COMMA "," + WHITESPACE "\n " + LITERAL + STRING "'s3://mybucket/events/*.csv'" + COMMA "," + WHITESPACE "\n " + LITERAL + STRING "'select import_events($1)'" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "jobname" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "start_time" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "status" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "return_message" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "cron" + DOT "." + NAME_REF + IDENT "job_run_details" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "cron" + DOT "." + NAME_REF + IDENT "job" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "jobid" + R_PAREN ")" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "jobname" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'pipeline:event-import%'" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + DESC_KW "desc" + WHITESPACE " " + LIMIT_CLAUSE + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- https://supabase.com/blog/calendars-in-postgres-using-foreign-data-wrappers" + WHITESPACE "\n\n" + CREATE_FOREIGN_DATA_WRAPPER_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME + IDENT "wasm_wrapper" + WHITESPACE "\n " + HANDLER_KW "handler" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wasm_fdw_handler" + WHITESPACE "\n " + VALIDATOR_KW "validator" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wasm_fdw_validator" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SERVER_STMT + CREATE_KW "create" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME + IDENT "cal_server" + WHITESPACE "\n " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "wasm_wrapper" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "fdw_package_url" + WHITESPACE " " + LITERAL + STRING "'https://github.com/supabase/wrappers/releases/download/wasm_cal_fdw_v0.1.0/cal_fdw.wasm'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "fdw_package_name" + WHITESPACE " " + LITERAL + STRING "'supabase:cal-fdw'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "fdw_package_version" + WHITESPACE " " + LITERAL + STRING "'0.1.0'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "fdw_package_checksum" + WHITESPACE " " + LITERAL + STRING "'4afe4fac8c51f2caa1de8483b3817d2cec3a14cd8a65a3942c8b4ff6c430f08a'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "api_key" + WHITESPACE " " + LITERAL + STRING "''" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "cal" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "cal" + DOT "." + PATH_SEGMENT + NAME + IDENT "event_types" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "attrs" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + OBJECT_KW "object" + WHITESPACE " " + LITERAL + STRING "'event-types'" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "create" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "cal" + DOT "." + PATH_SEGMENT + NAME + IDENT "bookings" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "attrs" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "cal_server" + WHITESPACE "\n " + OPTIONS_KW "options" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + OBJECT_KW "object" + WHITESPACE " " + LITERAL + STRING "'bookings'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "rowid_column" + WHITESPACE " " + LITERAL + STRING "'attrs'" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract event types" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "etg" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + BIN_EXPR + LITERAL + STRING "'profile'" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'name'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "profile" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + NAME_REF + IDENT "et" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'id'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "id" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + NAME_REF + IDENT "et" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'title'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "title" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "cal" + DOT "." + NAME_REF + IDENT "event_types" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n " + JOIN + CROSS_KW "cross" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "json_array_elements" + ARG_LIST + L_PAREN "(" + CAST_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "attrs" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + LITERAL + STRING "'eventTypeGroups'" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "etg" + WHITESPACE "\n " + JOIN + CROSS_KW "cross" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "json_array_elements" + ARG_LIST + L_PAREN "(" + CAST_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "etg" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + LITERAL + STRING "'eventTypes'" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "et" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract bookings" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "bk" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'id'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "id" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + NAME_REF + IDENT "bk" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'title'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "title" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + NAME_REF + IDENT "bk" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + BIN_EXPR + LITERAL + STRING "'responses'" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'name'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + NAME_KW "name" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + NAME_REF + IDENT "bk" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + LITERAL + STRING "'startTime'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "start_time" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "cal" + DOT "." + NAME_REF + IDENT "bookings" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n " + JOIN + CROSS_KW "cross" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "json_array_elements" + ARG_LIST + L_PAREN "(" + CAST_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "attrs" + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + LITERAL + STRING "'bookings'" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "bk" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- make a 15 minutes meeting with Elon Musk" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "insert" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "cal" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bookings" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "attrs" + R_PAREN ")" + WHITESPACE "\n" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + CAST_EXPR + LITERAL + STRING "'{\n \"start\": \"2025-01-01T23:30:00.000Z\",\n \"eventTypeId\": 1398027,\n \"attendee\": {\n \"name\": \"Elon Musk\",\n \"email\": \"elon.musk@x.com\",\n \"timeZone\": \"America/New_York\"\n }\n }'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- https://www.tinybird.co/blog-posts/outgrowing-postgres-how-to-run-olap-workloads-on-postgres" + WHITESPACE "\n\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "hourly_stats" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE "\n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'hour'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "event_time" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + HOUR_KW "hour" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "events" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + DISTINCT_KW "distinct" + WHITESPACE " " + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "users" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + UNIQUE_KW "UNIQUE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "hourly_stats" + INDEX_PARAMS + L_PAREN "(" + NAME_REF + HOUR_KW "hour" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "user_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + PARTITION_KW "PARTITION" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + RANGE_KW "RANGE" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "event_time" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COMMENT "-- Frequently queried columns" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "user_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COMMENT "-- Rarely queried metadata" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "user_agent" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "ip_address" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "inet" + COMMA "," + WHITESPACE "\n " + COMMENT "-- Large payload rarely used in aggregations" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_data" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events_core" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bigserial" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "PRIMARY" + WHITESPACE " " + KEY_KW "KEY" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "timestamptz" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "user_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events_metadata" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "PRIMARY" + WHITESPACE " " + KEY_KW "KEY" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "REFERENCES" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events_core" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "user_agent" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "ip_address" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "inet" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "events_payload" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE " " + PRIMARY_KEY_CONSTRAINT + PRIMARY_KW "PRIMARY" + WHITESPACE " " + KEY_KW "KEY" + WHITESPACE " " + REFERENCES_CONSTRAINT + REFERENCES_KW "REFERENCES" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events_core" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "event_data" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- -- Instead of one simple insert" + WHITESPACE "\n" + COMMENT "-- INSERT INTO events VALUES (...);" + WHITESPACE "\n\n" + COMMENT "-- -- You now need transaction-wrapped multi-table inserts" + WHITESPACE "\n" + COMMENT "-- BEGIN;" + WHITESPACE "\n" + COMMENT "-- INSERT INTO events_core (...) RETURNING event_id;" + WHITESPACE "\n" + COMMENT "-- INSERT INTO events_metadata (...);" + WHITESPACE "\n" + COMMENT "-- INSERT INTO events_payload (...);" + WHITESPACE "\n" + COMMENT "-- COMMIT;" + WHITESPACE "\n\n" + COMMENT "-- Simple query becomes a three-way join" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "event_time" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "event_type" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "m" + DOT "." + NAME_REF + IDENT "user_agent" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "event_data" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events_core" + WHITESPACE " " + ALIAS + NAME + IDENT "e" + WHITESPACE "\n" + JOIN + LEFT_KW "LEFT" + WHITESPACE " " + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "events_metadata" + WHITESPACE " " + ALIAS + NAME + IDENT "m" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "event_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "m" + DOT "." + NAME_REF + IDENT "event_id" + WHITESPACE "\n" + JOIN + LEFT_KW "LEFT" + WHITESPACE " " + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "events_payload" + WHITESPACE " " + ALIAS + NAME + IDENT "p" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "event_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "event_id" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "event_time" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1 day'" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EXTENSION_KW "EXTENSION" + WHITESPACE " " + NAME + IDENT "cstore_fdw" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SERVER_STMT + CREATE_KW "CREATE" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME + IDENT "cstore_server" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + DATA_KW "DATA" + WHITESPACE " " + WRAPPER_KW "WRAPPER" + WHITESPACE " " + NAME_REF + IDENT "cstore_fdw" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "metrics_columnar" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + DAY_KW "day" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "metric_name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + NAME + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + R_PAREN ")" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "cstore_server" + WHITESPACE "\n" + OPTIONS_KW "OPTIONS" + L_PAREN "(" + NAME + COMPRESSION_KW "compression" + WHITESPACE " " + LITERAL + STRING "'pglz'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EXTENSION_KW "EXTENSION" + WHITESPACE " " + NAME + IDENT "pg_analytics" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_FOREIGN_TABLE_STMT + CREATE_KW "CREATE" + WHITESPACE " " + FOREIGN_KW "FOREIGN" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "metrics" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + DAY_KW "day" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "metric_name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + NAME + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + SERVER_KW "SERVER" + WHITESPACE " " + NAME_REF + IDENT "parquet_server" + WHITESPACE "\n" + OPTIONS_KW "OPTIONS" + WHITESPACE " " + L_PAREN "(" + NAME + IDENT "files" + WHITESPACE " " + LITERAL + STRING "'s3://bucket/metrics/*.parquet'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EXTENSION_KW "EXTENSION" + WHITESPACE " " + NAME + IDENT "pg_duckdb" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "metrics" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE " \n " + COLUMN + NAME_REF + DAY_KW "day" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "metric_name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "duckdb" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_EXTENSION_STMT + CREATE_KW "CREATE" + WHITESPACE " " + EXTENSION_KW "EXTENSION" + WHITESPACE " " + NAME + IDENT "pg_mooncake" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_TABLE + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "metrics" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + DAY_KW "day" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "date" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "metric_name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + VALUE_KW "value" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "columnstore" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Instead of this complex self-join" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "revenue" + COMMA "," + WHITESPACE "\n " + TARGET + PAREN_EXPR + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "AVG" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + WHITESPACE " \n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "monthly_revenues" + WHITESPACE " " + ALIAS + NAME + IDENT "m2" + WHITESPACE " \n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "m2" + DOT "." + NAME_REF + MONTH_KW "month" + WHITESPACE " " + LTEQ "<=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "m1" + DOT "." + NAME_REF + MONTH_KW "month" + WHITESPACE " \n " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "m2" + DOT "." + NAME_REF + MONTH_KW "month" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "m1" + DOT "." + NAME_REF + MONTH_KW "month" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'3 months'" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "rolling_avg" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "monthly_revenues" + WHITESPACE " " + ALIAS + NAME + IDENT "m1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Use this cleaner window function" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "revenue" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "AVG" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + WHITESPACE " " + OVER_CLAUSE + OVER_KW "OVER" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + WINDOW_DEF + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + MONTH_KW "month" + WHITESPACE " \n " + ROWS_KW "ROWS" + WHITESPACE " " + BETWEEN_KW "BETWEEN" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + PRECEDING_KW "PRECEDING" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + CURRENT_KW "CURRENT" + WHITESPACE " " + ROW_KW "ROW" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "rolling_avg" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "monthly_revenues" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE "\n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "customer_segment" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "revenue" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + OVER_CLAUSE + OVER_KW "OVER" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + WINDOW_DEF + PARTITION_KW "PARTITION" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "customer_segment" + WHITESPACE "\n " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "running_total" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "transactions" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Use CTEs to break down complex analytics" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "monthly_stats" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + DISTINCT_KW "DISTINCT" + WHITESPACE " " + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "users" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "revenue" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE " \n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "NOW" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'12 months'" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + COMMA "," + WHITESPACE "\n" + WITH_TABLE + NAME + IDENT "user_segments" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE "\n " + TARGET + CASE_EXPR + CASE_KW "CASE" + WHITESPACE " \n " + WHEN_CLAUSE + WHEN_KW "WHEN" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "lifetime_value" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "1000" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE " " + LITERAL + STRING "'high'" + WHITESPACE "\n " + WHEN_CLAUSE + WHEN_KW "WHEN" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "lifetime_value" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE " " + LITERAL + STRING "'medium'" + WHITESPACE "\n " + ELSE_KW "ELSE" + WHITESPACE " " + LITERAL + STRING "'low'" + WHITESPACE "\n " + END_KW "END" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "segment" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "users" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "segment" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + DISTINCT_KW "DISTINCT" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "users" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "revenue" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "revenue" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE " " + ALIAS + NAME + IDENT "e" + WHITESPACE "\n" + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "user_segments" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + WHITESPACE "\n " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "e" + DOT "." + NAME_REF + IDENT "user_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "user_id" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + ANALYZE_KW "ANALYZE" + WHITESPACE " \n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + MONTH_KW "month" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "events" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + DISTINCT_KW "DISTINCT" + WHITESPACE " " + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "users" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Key settings for parallel queries" + WHITESPACE "\n" + SET_STMT + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "max_parallel_workers_per_gather" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- Workers per query" + WHITESPACE "\n" + SET_STMT + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "parallel_setup_cost" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- Lower = more parallelism" + WHITESPACE "\n" + SET_STMT + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "parallel_tuple_cost" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "0.001" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- Lower = more parallelism" + WHITESPACE "\n" + SET_STMT + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "min_parallel_table_scan_size" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'8MB'" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- Table size threshold" + WHITESPACE "\n\n" + COMMENT "-- Get detailed buffering info" + WHITESPACE "\n" + EXPLAIN_STMT + EXPLAIN_KW "EXPLAIN" + WHITESPACE " " + L_PAREN "(" + ANALYZE_KW "ANALYZE" + COMMA "," + WHITESPACE " " + IDENT "BUFFERS" + R_PAREN ")" + WHITESPACE " \n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + COMMENT "/* your query */" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Look for:" + WHITESPACE "\n" + COMMENT "-- \"Parallel Seq Scan\" - Is parallelism being used?" + WHITESPACE "\n" + COMMENT "-- \"Hash Join\" vs \"Nested Loop\" - Right join strategy?" + WHITESPACE "\n" + COMMENT "-- \"Sort Method: quicksort\" vs \"external sort\" - Enough work_mem?" + WHITESPACE "\n" + COMMENT "-- \"Rows Removed by Filter\" - Could an index help?" + WHITESPACE "\n\n" + COMMENT "-- Sorts intermediate results unnecessarily" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " \n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + DISTINCT_CLAUSE + DISTINCT_KW "DISTINCT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + WHITESPACE " \n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE " \n " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Remove unnecessary ORDER BY" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "COUNT" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " \n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + DISTINCT_CLAUSE + DISTINCT_KW "DISTINCT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + WHITESPACE " \n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "events" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Gets all rows then filters" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "status" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "user_status" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + TUPLE_EXPR + L_PAREN "(" + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + IN_KW "IN" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "MAX" + ARG_LIST + L_PAREN "(" + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "user_status" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "user_id" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Uses DISTINCT ON" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + DISTINCT_CLAUSE + DISTINCT_KW "DISTINCT" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "user_id" + R_PAREN ")" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "status" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "user_status" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "user_id" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + DESC_KW "DESC" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "idx_events_month" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "events" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + WHITESPACE "\n " + CALL_EXPR + NAME_REF + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "event_logs_ts_brin" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "event_logs" + WHITESPACE "\n" + USING_KW "USING" + WHITESPACE " " + NAME_REF + IDENT "brin" + INDEX_PARAMS + L_PAREN "(" + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + CONSTRAINT_STORAGE_PARAMS + WITH_KW "WITH" + WHITESPACE " " + L_PAREN "(" + PATH + PATH_SEGMENT + NAME_REF + IDENT "pages_per_range" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "128" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "corr" + ARG_LIST + L_PAREN "(" + CAST_EXPR + CAST_EXPR + NAME_REF + IDENT "ctid" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + COMMA "," + WHITESPACE " " + CAST_EXPR + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "float8" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "event_logs" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- https://www.crunchydata.com/blog/indexing-materialized-views-in-postgres" + WHITESPACE "\n" + CREATE_MATERIALIZED_VIEW_STMT + CREATE_KW "CREATE" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "recent_product_sales" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE "\n " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "sku" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "SUM" + ARG_LIST + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "po" + DOT "." + NAME_REF + IDENT "qty" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "total_quantity" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE "\n " + NAME_REF + IDENT "products" + WHITESPACE " " + ALIAS + NAME + IDENT "p" + WHITESPACE "\n " + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "product_orders" + WHITESPACE " " + ALIAS + NAME + IDENT "po" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "sku" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "po" + DOT "." + NAME_REF + IDENT "sku" + WHITESPACE "\n " + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "orders" + WHITESPACE " " + ALIAS + NAME + IDENT "o" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "po" + DOT "." + NAME_REF + IDENT "order_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "o" + DOT "." + NAME_REF + IDENT "order_id" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE "\n " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "o" + DOT "." + NAME_REF + IDENT "status" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Shipped'" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE "\n " + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "sku" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE "\n " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + DESC_KW "DESC" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "sku_index" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "recent_product_sales" + WHITESPACE " " + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "sku" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + REFRESH_STMT + REFRESH_KW "REFRESH" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "recent_product_sales" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_INDEX_STMT + CREATE_KW "CREATE" + WHITESPACE " " + UNIQUE_KW "UNIQUE" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "unique_idx_recent_product_sales" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "recent_product_sales" + INDEX_PARAMS + L_PAREN "(" + NAME_REF + IDENT "sku" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_INDEX_STMT + DROP_KW "DROP" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "sku_index" + SEMICOLON ";" + WHITESPACE "\n\n" + REFRESH_STMT + REFRESH_KW "REFRESH" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + CONCURRENTLY_KW "CONCURRENTLY" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "recent_product_sales" + SEMICOLON ";" + WHITESPACE "\n\n\n" + CREATE_TABLE + COMMENT "-- https://www.timescale.com/blog/iot-renewable-energy-models-building-the-future-with-time-series-data" + WHITESPACE "\n" + COMMENT "-- Example time series data structure for a solar panel" + WHITESPACE "\n" + CREATE_KW "CREATE" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "solar_panel_metrics" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + WHITESPACE "\n " + COLUMN + NAME_REF + TIME_KW "time" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "TIMESTAMPTZ" + WHITESPACE " " + NOT_NULL_CONSTRAINT + NOT_KW "NOT" + WHITESPACE " " + NULL_KW "NULL" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "panel_id" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "TEXT" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "voltage" + WHITESPACE " " + DOUBLE_TYPE + DOUBLE_KW "DOUBLE" + WHITESPACE " " + PRECISION_KW "PRECISION" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + CURRENT_KW "current" + WHITESPACE " " + DOUBLE_TYPE + DOUBLE_KW "DOUBLE" + WHITESPACE " " + PRECISION_KW "PRECISION" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "temperature" + WHITESPACE " " + DOUBLE_TYPE + DOUBLE_KW "DOUBLE" + WHITESPACE " " + PRECISION_KW "PRECISION" + COMMA "," + WHITESPACE "\n " + COLUMN + NAME_REF + IDENT "irradiance" + WHITESPACE " " + DOUBLE_TYPE + DOUBLE_KW "DOUBLE" + WHITESPACE " " + PRECISION_KW "PRECISION" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Create a hypertable for efficient time series operations" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "create_hypertable" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'solar_panel_metrics'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'time'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Calculate daily energy production and compare with expected output" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "time_bucket" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'1 day'" + COMMA "," + WHITESPACE " " + NAME_REF + TIME_KW "time" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + DAY_KW "day" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "panel_id" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "voltage" + WHITESPACE " " + STAR "*" + WHITESPACE " " + NAME_REF + CURRENT_KW "current" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "actual_power" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "expected_power" + COMMA "," + WHITESPACE "\n " + TARGET + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "voltage" + WHITESPACE " " + STAR "*" + WHITESPACE " " + NAME_REF + CURRENT_KW "current" + R_PAREN ")" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + NAME_REF + IDENT "expected_power" + R_PAREN ")" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "performance_ratio" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "solar_panel_metrics" + WHITESPACE "\n" + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "panel_specifications" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "panel_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "specs_id" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "INTERVAL" + WHITESPACE " " + LITERAL + STRING "'30 days'" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + DAY_KW "day" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "panel_id" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "expected_power" + WHITESPACE "\n" + HAVING_CLAUSE + HAVING_KW "HAVING" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "performance_ratio" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "90" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Detect abnormal vibration patterns in wind turbines" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "baseline_stats" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + IDENT "turbine_id" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "vibration_level" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "avg_vibration" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "stddev" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "vibration_level" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "stddev_vibration" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "turbine_metrics" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "INTERVAL" + WHITESPACE " " + LITERAL + STRING "'90 days'" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "turbine_id" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "time_bucket" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'5 minutes'" + COMMA "," + WHITESPACE " " + NAME_REF + TIME_KW "time" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "bucket" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "turbine_id" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "vibration_level" + COMMA "," + WHITESPACE "\n " + TARGET + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "vibration_level" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + NAME_REF + IDENT "avg_vibration" + R_PAREN ")" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + NAME_REF + IDENT "stddev_vibration" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "z_score" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "turbine_metrics" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n" + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "baseline_stats" + WHITESPACE " " + ALIAS + NAME + IDENT "b" + WHITESPACE " " + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "turbine_id" + R_PAREN ")" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " \n " + BIN_EXPR + BIN_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "INTERVAL" + WHITESPACE " " + LITERAL + STRING "'1 day'" + WHITESPACE "\n " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "abs" + ARG_LIST + L_PAREN "(" + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "vibration_level" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + NAME_REF + IDENT "avg_vibration" + R_PAREN ")" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + NAME_REF + IDENT "stddev_vibration" + R_PAREN ")" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Monitor aggregate power availability across resources" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "time_bucket" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'5 minutes'" + COMMA "," + WHITESPACE " " + NAME_REF + TIME_KW "time" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + INTERVAL_KW "interval" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "resource_type" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "available_power" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "total_power" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "storage_capacity" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "total_storage" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "vpp_resources" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "INTERVAL" + WHITESPACE " " + LITERAL + STRING "'1 hour'" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + INTERVAL_KW "interval" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "resource_type" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + DESC_KW "DESC" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Identify optimal trading windows" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "price_analysis" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "time_bucket" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'1 hour'" + COMMA "," + WHITESPACE " " + NAME_REF + TIME_KW "time" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + HOUR_KW "hour" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "price" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "avg_price" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "percentile_cont" + ARG_LIST + L_PAREN "(" + LITERAL + FLOAT_NUMBER "0.75" + R_PAREN ")" + WHITESPACE " " + WITHIN_CLAUSE + WITHIN_KW "WITHIN" + WHITESPACE " " + GROUP_KW "GROUP" + WHITESPACE " " + L_PAREN "(" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "price" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "price_75th" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "energy_prices" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + INTERVAL_KW "INTERVAL" + WHITESPACE " " + LITERAL + STRING "'30 days'" + WHITESPACE "\n " + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + HOUR_KW "hour" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " \n " + TARGET_LIST + TARGET + NAME_REF + HOUR_KW "hour" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "avg_price" + COMMA "," + WHITESPACE "\n " + TARGET + NAME_REF + IDENT "price_75th" + COMMA "," + WHITESPACE "\n " + TARGET + CASE_EXPR + CASE_KW "CASE" + WHITESPACE " \n " + WHEN_CLAUSE + WHEN_KW "WHEN" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "avg_price" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "price_75th" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE " " + LITERAL + STRING "'SELL'" + WHITESPACE "\n " + WHEN_CLAUSE + WHEN_KW "WHEN" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "avg_price" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + NAME_REF + IDENT "price_75th" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE " " + LITERAL + STRING "'BUY'" + WHITESPACE "\n " + ELSE_KW "ELSE" + WHITESPACE " " + LITERAL + STRING "'HOLD'" + WHITESPACE "\n " + END_KW "END" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "trading_signal" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "price_analysis" + WHITESPACE "\n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + HOUR_KW "hour" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__move_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__move_ok.snap new file mode 100644 index 00000000..81013ce2 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__move_ok.snap @@ -0,0 +1,220 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/move.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + NEXT_KW "next" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + PRIOR_KW "prior" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + NEXT_KW "NEXT" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + PRIOR_KW "PRIOR" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + FIRST_KW "FIRST" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + LAST_KW "LAST" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + ABSOLUTE_KW "ABSOLUTE" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + RELATIVE_KW "RELATIVE" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + FORWARD_KW "FORWARD" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n" + MOVE_STMT + MOVE_KW "move" + WHITESPACE " " + BACKWARD_KW "BACKWARD" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + NAME + IDENT "cursor_name" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__notify_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__notify_ok.snap new file mode 100644 index 00000000..aad8ebb8 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__notify_ok.snap @@ -0,0 +1,25 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/notify.sql +--- +SOURCE_FILE + COMMENT "-- notify_stmt" + WHITESPACE "\n" + NOTIFY_STMT + NOTIFY_KW "NOTIFY" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + NOTIFY_STMT + NOTIFY_KW "NOTIFY" + WHITESPACE " " + NAME + IDENT "virtual" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'This is the payload'" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__precedence_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__precedence_ok.snap new file mode 100644 index 00000000..e7bd144c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__precedence_ok.snap @@ -0,0 +1,142 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/precedence.sql +--- +SOURCE_FILE + COMMENT "-- see: https://github.com/postgres/postgres/blob/028b4b21df26fee67b3ce75c6f14fcfd3c7cf2ee/src/backend/parser/gram.y#L12699" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + PAREN_EXPR + L_PAREN "(" + COMPOUND_SELECT + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- TODO!" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "bar" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "baz" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- equal to:" + WHITESPACE "\n" + PAREN_EXPR + L_PAREN "(" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "bar" + R_PAREN ")" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "baz" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__prepare_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__prepare_ok.snap new file mode 100644 index 00000000..30e4dc76 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__prepare_ok.snap @@ -0,0 +1,401 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/prepare.sql +--- +SOURCE_FILE + COMMENT "-- insert" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "PREPARE" + WHITESPACE " " + NAME + IDENT "fooplan" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "bool" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + LITERAL + PARAM "$1" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$2" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$3" + COMMA "," + WHITESPACE " " + LITERAL + PARAM "$4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n\n" + COMMENT "-- select" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "PREPARE" + WHITESPACE " " + NAME + IDENT "usrrptplan" + WHITESPACE " " + L_PAREN "(" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "users" + WHITESPACE " " + ALIAS + NAME + IDENT "u" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "logs" + WHITESPACE " " + ALIAS + NAME + IDENT "l" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "usrid" + EQ "=" + LITERAL + PARAM "$1" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "u" + DOT "." + NAME_REF + IDENT "usrid" + EQ "=" + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "usrid" + WHITESPACE "\n " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "date" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + PARAM "$2" + SEMICOLON ";" + WHITESPACE "\n\n" + PREPARE_STMT + PREPARE_KW "PREPARE" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + AS_KW "AS" + WHITESPACE "\n " + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- update" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "prepare" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- delete" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "prepare" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + DELETE_STMT + DELETE_KW "delete" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "prepare" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t2" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t1" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- values" + WHITESPACE "\n" + PREPARE_STMT + PREPARE_KW "prepare" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'one'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'two'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__reassign_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__reassign_ok.snap new file mode 100644 index 00000000..e207387b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__reassign_ok.snap @@ -0,0 +1,44 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/reassign.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + REASSIGN_STMT + REASSIGN_KW "reassign" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + COMMA "," + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + IDENT "foo" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SESSION_USER_KW "session_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REASSIGN_STMT + REASSIGN_KW "reassign" + WHITESPACE " " + OWNED_KW "owned" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + CURRENT_USER_KW "current_user" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__refresh_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__refresh_ok.snap new file mode 100644 index 00000000..76a9fcee --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__refresh_ok.snap @@ -0,0 +1,58 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/refresh.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + REFRESH_STMT + REFRESH_KW "REFRESH" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "order_summary" + SEMICOLON ";" + WHITESPACE "\n\n" + REFRESH_STMT + REFRESH_KW "REFRESH" + WHITESPACE " " + MATERIALIZED_KW "MATERIALIZED" + WHITESPACE " " + VIEW_KW "VIEW" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "annual_statistics_basis" + WHITESPACE " " + WITH_KW "WITH" + WHITESPACE " " + NO_KW "NO" + WHITESPACE " " + DATA_KW "DATA" + SEMICOLON ";" + WHITESPACE "\n\n" + REFRESH_STMT + REFRESH_KW "refresh" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "v" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + DATA_KW "data" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__reindex_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__reindex_ok.snap new file mode 100644 index 00000000..1b99d13d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__reindex_ok.snap @@ -0,0 +1,104 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/reindex.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + REINDEX_STMT + REINDEX_KW "REINDEX" + WHITESPACE " " + INDEX_KW "INDEX" + WHITESPACE " " + NAME + IDENT "my_index" + SEMICOLON ";" + WHITESPACE "\n\n" + REINDEX_STMT + REINDEX_KW "REINDEX" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + NAME + IDENT "my_table" + SEMICOLON ";" + WHITESPACE "\n\n" + REINDEX_STMT + REINDEX_KW "REINDEX" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + CONCURRENTLY_KW "CONCURRENTLY" + WHITESPACE " " + NAME + IDENT "my_broken_table" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- complete_syntax" + WHITESPACE "\n" + REINDEX_STMT + REINDEX_KW "reindex" + WHITESPACE " " + L_PAREN "(" + CONCURRENTLY_KW "concurrently" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME + IDENT "fooo" + COMMA "," + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + LITERAL + FALSE_KW "false" + R_PAREN ")" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + CONCURRENTLY_KW "concurrently" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + REINDEX_STMT + REINDEX_KW "reindex" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + REINDEX_STMT + REINDEX_KW "reindex" + WHITESPACE " " + INDEX_KW "index" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + REINDEX_STMT + REINDEX_KW "reindex" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + REINDEX_STMT + REINDEX_KW "reindex" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__reset_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__reset_ok.snap new file mode 100644 index 00000000..3b8d926f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__reset_ok.snap @@ -0,0 +1,20 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/reset.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + RESET_STMT + RESET_KW "reset" + WHITESPACE " " + NAME_REF + IDENT "some_config_param" + SEMICOLON ";" + WHITESPACE "\n" + RESET_STMT + RESET_KW "reset" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__revoke_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__revoke_ok.snap new file mode 100644 index 00000000..c3d7799d --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__revoke_ok.snap @@ -0,0 +1,1435 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/revoke.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + INSERT_KW "insert" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + COMMA "," + WHITESPACE " " + DELETE_KW "delete" + COMMA "," + WHITESPACE " " + TRUNCATE_KW "truncate" + COMMA "," + WHITESPACE " " + REFERENCES_KW "references" + COMMA "," + WHITESPACE " " + TRIGGER_KW "trigger" + COMMA "," + WHITESPACE " " + IDENT "maintain" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_table" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " \n " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + COMMA "," + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + GRANTED_KW "granted" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_all_tables" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " \n " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + TABLES_KW "tables" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + WHITESPACE "\n " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- columns" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + INSERT_KW "insert" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + UPDATE_KW "update" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + REFERENCES_KW "references" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " \n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- sequence" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + IDENT "usage" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SEQUENCES_KW "sequences" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- database" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + CREATE_KW "create" + COMMA "," + WHITESPACE " " + IDENT "connect" + COMMA "," + WHITESPACE " " + TEMPORARY_KW "temporary" + COMMA "," + WHITESPACE " " + TEMP_KW "temp" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- domain" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_data" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + DATA_KW "data" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_server" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + SERVER_KW "server" + WHITESPACE " " + NAME_REF + IDENT "d" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + GRANT_KW "grant" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + EXECUTE_KW "execute" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "z" + PARAM_LIST + L_PAREN "(" + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + R_PAREN ")" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "r" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + FUNCTIONS_KW "functions" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PROCEDURES_KW "procedures" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + ROUTINES_KW "routines" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + PARAM_LIST + L_PAREN "(" + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE " " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- language" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + IDENT "usage" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- large_object" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SELECT_KW "select" + COMMA "," + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1012" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1231" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + PRIVILEGES_KW "privileges" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1012" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1231" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- param" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALTER_KW "alter" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + BEGIN_KW "begin" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PARAMETER_KW "parameter" + WHITESPACE " " + NAME_REF + BEGIN_KW "begin" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- edge_case" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " \n " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE " \n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + COMMA "," + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE " \n\n" + COMMENT "-- schema" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "s" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + CREATE_KW "create" + COMMA "," + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- tablespace" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + CREATE_KW "create" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type_" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + IDENT "usage" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " \n " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- option" + WHITESPACE "\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + ADMIN_KW "admin" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "public" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + INHERIT_KW "inherit" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "public" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + OPTION_KW "option" + WHITESPACE " " + FOR_KW "for" + WHITESPACE "\n " + IDENT "public" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + REVOKE_STMT + REVOKE_KW "revoke" + WHITESPACE " " + IDENT "public" + WHITESPACE "\n " + FROM_KW "from" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__schemas_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__schemas_ok.snap new file mode 100644 index 00000000..55ef1614 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__schemas_ok.snap @@ -0,0 +1,609 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/schemas.sql +--- +SOURCE_FILE + COMMENT "-- create_schema" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "myschema" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + SESSION_USER_KW "session_user" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_NOT_EXISTS + IF_KW "if" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE "\n " + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + WHITESPACE "\n " + CREATE_TABLE + CREATE_KW "create" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t1" + WHITESPACE " " + TABLE_ARGS + L_PAREN "(" + COLUMN + NAME_REF + IDENT "z" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + SCHEMA_KW "schema" + DOT "." + PATH_SEGMENT + NAME_REF + TABLE_KW "table" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + DATABASE_KW "database" + DOT "." + PATH_SEGMENT + NAME_REF + SCHEMA_KW "schema" + DOT "." + PATH_SEGMENT + NAME_REF + TABLE_KW "table" + SEMICOLON ";" + WHITESPACE "\n\n" + DROP_SCHEMA_STMT + DROP_KW "drop" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "myschema" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SCHEMA_STMT + DROP_KW "drop" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "myschema" + WHITESPACE " " + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SCHEMA_STMT + DROP_KW "drop" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "myschema" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n" + DROP_SCHEMA_STMT + DROP_KW "drop" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + IF_EXISTS + IF_KW "if" + WHITESPACE " " + EXISTS_KW "exists" + WHITESPACE " " + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + NAME + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "schema_name" + WHITESPACE " " + AUTHORIZATION_KW "authorization" + WHITESPACE " " + IDENT "user_name" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_schema_with_sequence" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE "\n " + CREATE_SEQUENCE_STMT + CREATE_KW "create" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- create_schema_with_trigger" + WHITESPACE "\n" + CREATE_SCHEMA_STMT + CREATE_KW "create" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + NAME + IDENT "s" + WHITESPACE "\n " + CREATE_TRIGGER_STMT + CREATE_KW "create" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + AFTER_KW "after" + WHITESPACE " " + INSERT_KW "insert" + WHITESPACE "\n " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "u" + WHITESPACE "\n " + EXECUTE_KW "execute" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- search_path" + WHITESPACE "\n" + SHOW_STMT + SHOW_KW "show" + WHITESPACE " " + NAME_REF + IDENT "search_path" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "search_path" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "myschema" + COMMA "," + IDENT "public" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "search_path" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "myschema" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'America/Los_Angeles'" + SEMICOLON ";" + WHITESPACE "\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LOCAL_KW "local" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + SET_STMT + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "10.0" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- operator" + WHITESPACE "\n" + COMMENT "-- binary" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "3" + WHITESPACE " " + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + IDENT "pg_catalog" + DOT "." + PLUS "+" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "3" + WHITESPACE " " + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + PLUS "+" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + IDENT "a" + DOT "." + CUSTOM_OP + AMP "&" + AMP "&" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- unary" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + IDENT "pg_catalog" + DOT "." + MINUS "-" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + MINUS "-" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + OPERATOR_CALL + OPERATOR_KW "operator" + L_PAREN "(" + IDENT "a" + DOT "." + IDENT "b" + DOT "." + MINUS "-" + R_PAREN ")" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__security_label_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__security_label_ok.snap new file mode 100644 index 00000000..b7032761 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__security_label_ok.snap @@ -0,0 +1,1011 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/security_label.sql +--- +SOURCE_FILE + COMMENT "-- table" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "SECURITY" + WHITESPACE " " + LABEL_KW "LABEL" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + IDENT "selinux" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "mytable" + WHITESPACE " " + IS_KW "IS" + WHITESPACE " " + LITERAL + STRING "'system_u:object_r:sepgsql_table_t:s0'" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "SECURITY" + WHITESPACE " " + LABEL_KW "LABEL" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + IDENT "selinux" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + TABLE_KW "TABLE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "mytable" + WHITESPACE " " + IS_KW "IS" + WHITESPACE " " + NULL_KW "NULL" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + COLUMN_KW "column" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_aggregate_star" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + PARAM_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_aggregate_args" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "bar" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- on_aggregate_args_with_order_by" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + AGGREGATE_KW "aggregate" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + COMMA "," + WHITESPACE "\n " + PARAM + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + TEXT_KW "text" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + STRING "''" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- database" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DATABASE_KW "database" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- domain" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + DOMAIN_KW "domain" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- event_trigger" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EVENT_KW "event" + WHITESPACE " " + TRIGGER_KW "trigger" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- foreign_table" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FOREIGN_KW "foreign" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + FUNCTION_KW "function" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE "\n " + PARAM + PARAM_OUT + OUT_KW "out" + WHITESPACE " " + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + COMMA "," + WHITESPACE "\n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- large_object" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LARGE_KW "large" + WHITESPACE " " + OBJECT_KW "object" + WHITESPACE " " + LITERAL + INT_NUMBER "1234" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- materialized_view" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- language" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURAL_KW "procedural" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LANGUAGE_KW "language" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- procedure" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PROCEDURE_KW "procedure" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " \n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- publication" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PUBLICATION_KW "publication" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- role" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROLE_KW "role" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- routine" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ROUTINE_KW "routine" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + PARAM_LIST + L_PAREN "(" + WHITESPACE "\n " + PARAM + PARAM_IN + IN_KW "in" + WHITESPACE " " + NAME + IDENT "foo" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " \n " + PARAM + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- schema" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SCHEMA_KW "schema" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- sequence" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SEQUENCE_KW "sequence" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subscription" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SUBSCRIPTION_KW "subscription" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- tablespace" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TABLESPACE_KW "tablespace" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- type_" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + TYPE_KW "type" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- view" + WHITESPACE "\n" + SECURITY_LABEL_STMT + SECURITY_KW "security" + WHITESPACE " " + LABEL_KW "label" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + VIEW_KW "view" + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_casts_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_casts_ok.snap new file mode 100644 index 00000000..106f622c --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_casts_ok.snap @@ -0,0 +1,2792 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_casts.sql +--- +SOURCE_FILE + COMMENT "-- type_casts" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + NUMERIC_KW "numeric" + WHITESPACE " " + LITERAL + STRING "'1234'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'1234'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + LITERAL + STRING "'1234'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "int8" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'1234'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + INT_NUMBER "44" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + PREFIX_EXPR + MINUS "-" + LITERAL + INT_NUMBER "44" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "12" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_EXPR + LITERAL + STRING "'1110'" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "4" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'{1,2,3}'" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + IDENT "foo" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + IDENT "foo" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_EXPR + CAST_EXPR + LITERAL + STRING "'{}'" + WHITESPACE " " + COLON2 "::" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + L_BRACK "[" + R_BRACK "]" + WHITESPACE " " + COLON2 "::" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + WHITESPACE " " + COLON2 "::" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_EXPR + CAST_EXPR + LITERAL + STRING "'{}'" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + L_BRACK "[" + R_BRACK "]" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- based on postgres' gram.y" + WHITESPACE "\n\n" + COMMENT "-- Bit" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'1001'" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'1001'" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + WHITESPACE " " + VARYING_KW "varying" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Character" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + CHARACTER_KW "character" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + CHARACTER_KW "character" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + CHAR_KW "char" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + CHAR_KW "char" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + VARCHAR_KW "varchar" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NATIONAL_KW "national" + WHITESPACE " " + CHARACTER_KW "character" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NATIONAL_KW "national" + WHITESPACE " " + CHARACTER_KW "character" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NATIONAL_KW "national" + WHITESPACE " " + CHAR_KW "char" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NATIONAL_KW "national" + WHITESPACE " " + CHAR_KW "char" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NCHAR_KW "nchar" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + NCHAR_KW "nchar" + WHITESPACE " " + VARYING_KW "varying" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + ARRAY_TYPE + CHAR_TYPE + NCHAR_KW "nchar" + WHITESPACE " " + VARYING_KW "varying" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ConstDatetime" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + WITH_TIMEZONE + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + WITHOUT_TIMEZONE + WITHOUT_KW "without" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + WITH_TIMEZONE + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + WITHOUT_TIMEZONE + WITHOUT_KW "without" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + WITH_TIMEZONE + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + WITHOUT_TIMEZONE + WITHOUT_KW "without" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + WHITESPACE " " + WITH_TIMEZONE + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'2024-01-01 12:34:56.123456'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIME_KW "time" + WHITESPACE " " + WITHOUT_TIMEZONE + WITHOUT_KW "without" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- timestamp with time zone cast" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'2005-04-02 12:00:00-07'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cast w/ at time zone operator" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40-05'" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'america/denver'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- timestamp cast w/ at time zone operator" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40'" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'america/denver'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple at time zone" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + BIN_EXPR + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40'" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'asia/tokyo'" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'america/chicago'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cast and at local" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + POSTFIX_EXPR + CAST_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'20:38:40-05'" + WHITESPACE " " + AT_KW "at" + WHITESPACE " " + LOCAL_KW "local" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + POSTFIX_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + AT_KW "at" + WHITESPACE " " + LOCAL_KW "local" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + POSTFIX_EXPR + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40-05'" + WHITESPACE " " + AT_KW "at" + WHITESPACE " " + LOCAL_KW "local" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ConstInterval" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + YEAR_KW "year" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + MONTH_KW "month" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + DAY_KW "day" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + HOUR_KW "hour" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "100" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + YEAR_KW "year" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MONTH_KW "month" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + HOUR_KW "hour" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + WHITESPACE " " + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'10 days'" + COLON2 "::" + INTERVAL_TYPE + INTERVAL_KW "interval" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- JsonType" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'{}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- jsonb type cast" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'\"foo\"'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'\"foo\"'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- GenericType" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + L_PAREN "(" + ARG_LIST + ARG + NAME_REF + IDENT "buzz" + COMMA "," + WHITESPACE " " + ARG + NAME_REF + IDENT "bizz" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + VARCHAR_KW "varchar" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'abc'" + COLON2 "::" + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + CHAR_TYPE + VARCHAR_KW "varchar" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "255" + R_PAREN ")" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + CHAR_TYPE + VARCHAR_KW "varchar" + L_BRACK "[" + LITERAL + INT_NUMBER "5" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "255" + R_PAREN ")" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + L_BRACK "[" + LITERAL + INT_NUMBER "5" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "255" + R_PAREN ")" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- Numeric" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + SMALLINT_KW "smallint" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BIGINT_KW "bigint" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + FLOAT_KW "float" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + DOUBLE_TYPE + DOUBLE_KW "double" + WHITESPACE " " + PRECISION_KW "precision" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + DECIMAL_KW "decimal" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + DECIMAL_KW "decimal" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + DEC_KW "dec" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + DEC_KW "dec" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + ARG + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + BOOLEAN_KW "boolean" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10" + COMMA "," + ARG + LITERAL + INT_NUMBER "2" + R_PAREN ")" + L_BRACK "[" + LITERAL + INT_NUMBER "10" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- interval_cast_trailing" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + YEAR_KW "year" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + MONTH_KW "month" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + DAY_KW "day" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + HOUR_KW "hour" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + YEAR_KW "year" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MONTH_KW "month" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + HOUR_KW "hour" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pgdoc_char" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "''" + COLON2 "::" + CHAR_TYPE + CHAR_KW "char" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'a '" + COLON2 "::" + CHAR_TYPE + CHAR_KW "CHAR" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + CAST_EXPR + LITERAL + ESC_STRING "E'a\\n'" + COLON2 "::" + CHAR_TYPE + CHAR_KW "CHAR" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + BIN_EXPR + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + NAME_REF + IDENT "x" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cast_array" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + LITERAL + STRING "'{1}'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + WHITESPACE " " + ARRAY_KW "ARRAY" + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + LITERAL + STRING "'{1}'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + WHITESPACE " " + ARRAY_KW "ARRAY" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + LITERAL + STRING "'{1}'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + LITERAL + STRING "'{1}'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'{1}'" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "2" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + L_BRACK "[" + R_BRACK "]" + L_BRACK "[" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "1000" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + R_BRACK "]" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- casts" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + INT_NUMBER "44" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- 0000101100" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + INT_NUMBER "44" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- 100" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + PREFIX_EXPR + MINUS "-" + LITERAL + INT_NUMBER "44" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "12" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- 111111010100" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_EXPR + LITERAL + STRING "'1110'" + COLON2 "::" + BIT_TYPE + BIT_KW "bit" + L_PAREN "(" + ARG_LIST + ARG + LITERAL + INT_NUMBER "4" + R_PAREN ")" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INTEGER_KW "integer" + SEMICOLON ";" + WHITESPACE " " + COMMENT "-- 14" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'1'" + COLON2 "::" + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "pg_catalog" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "int8" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + LITERAL + STRING "'{1}'" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "pg_catalog" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "int8" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- cast" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CAST_KW "cast" + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- treat" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + TREAT_KW "treat" + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + TREAT_KW "treat" + L_PAREN "(" + LITERAL + STRING "'1231'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_err.snap new file mode 100644 index 00000000..4af283e9 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_err.snap @@ -0,0 +1,48 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/select_cte.sql +--- +SOURCE_FILE + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + ERROR + COMMA "," + WHITESPACE " " + COMMENT "-- <--- extra comma!" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@24: unexpected comma diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_ok.snap new file mode 100644 index 00000000..38bb5d24 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_cte_ok.snap @@ -0,0 +1,1278 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_cte.sql +--- +SOURCE_FILE + COMMENT "-- with_merge" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + MERGE_STMT + MERGE_KW "merge" + WHITESPACE " " + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE "\n " + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_values" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column names" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- materialized " + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not materialized " + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATERIALIZED_KW "materialized" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- nested" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + PAREN_EXPR + L_PAREN "(" + WHITESPACE "\n " + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + WHITESPACE " \n " + R_PAREN ")" + WHITESPACE "\n " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- search depth first (from pg docs)" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + RECURSIVE_KW "RECURSIVE" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "search_tree" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "id" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "link" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DATA_KW "data" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + DATA_KW "data" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tree" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n " + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + DATA_KW "data" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tree" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "search_tree" + WHITESPACE " " + ALIAS + NAME + IDENT "st" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "st" + DOT "." + NAME_REF + IDENT "link" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + SEARCH_KW "SEARCH" + WHITESPACE " " + DEPTH_KW "DEPTH" + WHITESPACE " " + FIRST_KW "FIRST" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "id" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "ordercol" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "search_tree" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "ordercol" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- search breadth first (from pg docs)" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + RECURSIVE_KW "RECURSIVE" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "search_tree" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "id" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "link" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DATA_KW "data" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + DATA_KW "data" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tree" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + WHITESPACE "\n " + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + DATA_KW "data" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "tree" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "search_tree" + WHITESPACE " " + ALIAS + NAME + IDENT "st" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "st" + DOT "." + NAME_REF + IDENT "link" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + SEARCH_KW "SEARCH" + WHITESPACE " " + BREADTH_KW "BREADTH" + WHITESPACE " " + FIRST_KW "FIRST" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "id" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "ordercol" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "search_tree" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "ordercol" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- search cycle (from pg docs)" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + RECURSIVE_KW "RECURSIVE" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "search_graph" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "id" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "link" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DATA_KW "data" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DEPTH_KW "depth" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + DATA_KW "data" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "graph" + WHITESPACE " " + ALIAS + NAME + IDENT "g" + WHITESPACE "\n " + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + IDENT "link" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + DATA_KW "data" + COMMA "," + WHITESPACE " " + TARGET + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "sg" + DOT "." + NAME_REF + DEPTH_KW "depth" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "graph" + WHITESPACE " " + ALIAS + NAME + IDENT "g" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "search_graph" + WHITESPACE " " + ALIAS + NAME + IDENT "sg" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "g" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "sg" + DOT "." + NAME_REF + IDENT "link" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + CYCLE_KW "CYCLE" + WHITESPACE " " + NAME_REF + IDENT "id" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "is_cycle" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + NAME_REF + PATH_KW "path" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "search_graph" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- search cycle with to and default values" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + RECURSIVE_KW "RECURSIVE" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "search_graph" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "id" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "link" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DATA_KW "data" + COMMA "," + WHITESPACE " " + COLUMN + NAME + DEPTH_KW "depth" + COMMA "," + WHITESPACE " " + COLUMN + NAME + PATH_KW "path" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + CYCLE_KW "CYCLE" + WHITESPACE " " + NAME_REF + IDENT "id" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "is_cycle" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + LITERAL + TRUE_KW "true" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE " " + LITERAL + FALSE_KW "false" + WHITESPACE " " + USING_KW "USING" + WHITESPACE " " + NAME_REF + PATH_KW "path" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "search_graph" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + COMMA "," + WHITESPACE "\n" + WITH_TABLE + NAME + IDENT "b" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- recursive" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + RECURSIVE_KW "recursive" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t2" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- timestamp_edge_cases" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + TIMESTAMP_KW "timestamp" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + TIME_KW "time" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + TIME_KW "time" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_err.snap new file mode 100644 index 00000000..ef7639da --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_err.snap @@ -0,0 +1,218 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/select.sql +--- +SOURCE_FILE + COMMENT "--- via https://duckdb.org/docs/stable/sql/dialect/friendly_sql.html#trailing-commas" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "42" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "x" + COMMA "," + WHITESPACE "\n " + TARGET + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'c'" + ERROR + COMMA "," + R_BRACK "]" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "y" + COMMA "," + WHITESPACE "\n " + TARGET + LITERAL + STRING "'hello world'" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "z" + ERROR + COMMA "," + WHITESPACE "\n" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- trailing comma in column list" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "u" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + ERROR + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- missing comma" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "b" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + TARGET + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "e" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- ^ ^ comma missing" + WHITESPACE "\n" + COMMENT "-- \\-- this is a label" + WHITESPACE "\n\n" + COMMENT "-- trailing comma in args" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + ERROR + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- missing args" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + ERROR + COMMA "," + ERROR + COMMA "," + ERROR + COMMA "," + ERROR + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- in can only be used with tuples / sub queries" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- trailing comma at EOF" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + ERROR + COMMA "," + WHITESPACE "\n" +--- +ERROR@124: unexpected trailing comma +ERROR@153: unexpected trailing comma +ERROR@213: unexpected trailing comma +ERROR@248: missing comma +ERROR@362: unexpected trailing comma +ERROR@394: expected expression +ERROR@395: expected expression +ERROR@396: expected expression +ERROR@397: expected expression +ERROR@500: unexpected trailing comma diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_ok.snap new file mode 100644 index 00000000..ca61aa7b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_ok.snap @@ -0,0 +1,3743 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_funcs.sql +--- +SOURCE_FILE + COMMENT "-- normalize" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NORMALIZE_KW "normalize" + ARG_LIST + L_PAREN "(" + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NORMALIZE_KW "normalize" + ARG_LIST + L_PAREN "(" + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + NAME_REF + NFC_KW "nfc" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NORMALIZE_KW "normalize" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'c'" + COMMA "," + WHITESPACE " " + NAME_REF + NFD_KW "nfd" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NORMALIZE_KW "normalize" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'d'" + COMMA "," + WHITESPACE " " + NAME_REF + NFKC_KW "nfkc" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NORMALIZE_KW "normalize" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'e'" + COMMA "," + WHITESPACE " " + NAME_REF + NFKD_KW "nfkd" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- nullif" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + NULLIF_KW "nullif" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- coalesce" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + COALESCE_KW "coalesce" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + COALESCE_KW "coalesce" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'foo'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- greater" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "greater" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "greater" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "0" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- least" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + LEAST_KW "least" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + LEAST_KW "least" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "0" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- merge_action" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + MERGE_ACTION_KW "merge_action" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n\n" + COMMENT "-- overlay" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + OVERLAY_KW "overlay" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + PLACING_KW "placing" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "d" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + OVERLAY_KW "overlay" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + PLACING_KW "placing" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + OVERLAY_KW "overlay" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + OVERLAY_KW "overlay" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "a" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- position" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + POSITION_KW "position" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'foo'" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + POSITION_KW "position" + ARG_LIST + L_PAREN "(" + BIN_EXPR + LITERAL + STRING "'f'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "'b'" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "'fb'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "' '" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + POSITION_KW "position" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'c'" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- trim" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + BOTH_KW "both" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + BOTH_KW "both" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + BOTH_KW "both" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + LEADING_KW "leading" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + TRAILING_KW "trailing" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + TRIM_KW "trim" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- substring_fn" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + SIMILAR_KW "similar" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + ESCAPE_KW "escape" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "''" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + SUBSTRING_KW "substring" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'hello world'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlconcat" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLCONCAT_KW "xmlconcat" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlelement" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLELEMENT_KW "xmlelement" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLELEMENT_KW "xmlelement" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "c" + COMMA "," + WHITESPACE " " + XMLATTRIBUTES_KW "xmlattributes" + L_PAREN "(" + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "b" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLELEMENT_KW "xmlelement" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "d" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "e" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "g" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLELEMENT_KW "xmlelement" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "d" + COMMA "," + WHITESPACE " " + XMLATTRIBUTES_KW "xmlattributes" + L_PAREN "(" + NAME_REF + IDENT "buzz" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "c" + R_PAREN ")" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "f" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "g" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlexists" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLEXISTS_KW "xmlexists" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'foo'" + WHITESPACE " " + PASSING_KW "passing" + WHITESPACE " " + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLEXISTS_KW "xmlexists" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'foo'" + WHITESPACE " " + PASSING_KW "passing" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + REF_KW "ref" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLEXISTS_KW "xmlexists" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'foo'" + WHITESPACE " " + PASSING_KW "passing" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + REF_KW "ref" + WHITESPACE " " + NAME_REF + IDENT "bar" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLEXISTS_KW "xmlexists" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'foo'" + WHITESPACE " " + PASSING_KW "passing" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + REF_KW "ref" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + VALUE_KW "value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlforest" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLFOREST_KW "xmlforest" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlparse" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLPARSE_KW "xmlparse" + ARG_LIST + L_PAREN "(" + DOCUMENT_KW "document" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + PRESERVE_KW "preserve" + WHITESPACE " " + WHITESPACE_KW "whitespace" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLPARSE_KW "xmlparse" + ARG_LIST + L_PAREN "(" + CONTENT_KW "content" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + STRIP_KW "strip" + WHITESPACE " " + WHITESPACE_KW "whitespace" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xmlpi" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLPI_KW "xmlpi" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLPI_KW "xmlpi" + ARG_LIST + L_PAREN "(" + NAME_KW "name" + WHITESPACE " " + NAME + IDENT "foo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "bar" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xml_root" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLROOT_KW "xmlroot" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + VERSION_KW "version" + WHITESPACE " " + NAME_REF + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLROOT_KW "xmlroot" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + VERSION_KW "version" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + VALUE_KW "value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLROOT_KW "xmlroot" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + VERSION_KW "version" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + STANDALONE_KW "standalone" + WHITESPACE " " + YES_KW "yes" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLROOT_KW "xmlroot" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + VERSION_KW "version" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + STANDALONE_KW "standalone" + WHITESPACE " " + NO_KW "no" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLROOT_KW "xmlroot" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + VERSION_KW "version" + WHITESPACE " " + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + STANDALONE_KW "standalone" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + VALUE_KW "value" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- xml_serialize" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLSERIALIZE_KW "xmlserialize" + ARG_LIST + L_PAREN "(" + DOCUMENT_KW "document" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + INDENT_KW "indent" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + XMLSERIALIZE_KW "xmlserialize" + ARG_LIST + L_PAREN "(" + DOCUMENT_KW "document" + WHITESPACE " " + NAME_REF + IDENT "x" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + INDENT_KW "indent" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_object" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'{a, 1, b, \"def\", c, 3.5}'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'{foo}'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'{bar}'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + R_BRACK "]" + COMMA "," + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'bar'" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + JSON_KEY_VALUE + LITERAL + STRING "'a'" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + JSON_KEY_VALUE + LITERAL + STRING "'a'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'b'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + ENCODING_KW "encoding" + WHITESPACE " " + NAME_REF + IDENT "utf8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + ABSENT_KW "absent" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'a'" + COLON ":" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + JSON_KEY_VALUE + LITERAL + STRING "'b'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'1'" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE " " + JSON_KEY_VALUE + LITERAL + STRING "'c'" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE " " + LITERAL + STRING "'c'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITH_KW "with" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + KEYS_KW "keys" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITH_KW "with" + WHITESPACE " " + UNIQUE_KW "unique" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITHOUT_KW "without" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + KEYS_KW "keys" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITHOUT_KW "without" + WHITESPACE " " + UNIQUE_KW "unique" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_OBJECT_KW "json_object" + ARG_LIST + L_PAREN "(" + JSON_KEY_VALUE + LITERAL + STRING "'foo'" + COLON ":" + WHITESPACE " " + LITERAL + STRING "'bar'" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_array" + WHITESPACE "\n" + COMMENT "-- value_expression" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + ENCODING_KW "encoding" + WHITESPACE " " + NAME_REF + IDENT "utf8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_NULL_CLAUSE + NULL_KW "null" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_NULL_CLAUSE + ABSENT_KW "absent" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_NULL_CLAUSE + ABSENT_KW "absent" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + NULL_KW "null" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " " + CAST_EXPR + NAME_REF + JSON_KW "json" + WHITESPACE " " + LITERAL + STRING "'{\"a\":null}'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'3'" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- query_expression" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + STRING "'true'" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + STRING "'true'" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_ARRAY_KW "json_array" + ARG_LIST + L_PAREN "(" + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_scalar" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_SCALAR_KW "json_scalar" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- exists" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXISTS_KW "exists" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXISTS_KW "exists" + ARG_LIST + L_PAREN "(" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- exists_values" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXISTS_KW "exists" + ARG_LIST + L_PAREN "(" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- exists_where" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + CALL_EXPR + NAME_REF + EXISTS_KW "exists" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "null" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not_exists" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + NOT_KW "not" + WHITESPACE " " + CALL_EXPR + NAME_REF + EXISTS_KW "exists" + ARG_LIST + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function_call" + WHITESPACE "\n" + COMMENT "-- position notation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "buzz" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'x'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'y'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- named notation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAMED_ARG + NAME_REF + IDENT "a" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + STRING "'foo'" + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "b" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + STRING "'bar'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- mixed notation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "boo" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- colon equals" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "a" + WHITESPACE " " + COLONEQ ":=" + WHITESPACE " " + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "foo" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "bar" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + YEAR_KW "year" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + MONTH_KW "month" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + DAY_KW "day" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + HOUR_KW "hour" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + MINUTE_KW "minute" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + SECOND_KW "second" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + STRING "'minute'" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "epoch" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "timestamptz" + WHITESPACE " " + LITERAL + STRING "'2013-07-01 12:00:00'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "century" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2000-12-16 12:21:13'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "isodow" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2001-02-18 20:38:40'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "isoyear" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2006-01-01'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "julian" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2006-01-01'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "microseconds" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + TIME_KW "time" + WHITESPACE " " + LITERAL + STRING "'17:12:28.5'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "millennium" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + EXTRACT_KW "extract" + ARG_LIST + L_PAREN "(" + IDENT "quarter" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + CAST_EXPR + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + LITERAL + STRING "'2001-02-16 20:38:40'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "transaction_timestamp" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "statement_timestamp" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "clock_timestamp" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "timeofday" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "now" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "pg_sleep" + ARG_LIST + L_PAREN "(" + LITERAL + FLOAT_NUMBER "1.5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "pg_sleep_for" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'5 minutes'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "pg_sleep_until" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'tomorrow 03:00'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- aggs" + WHITESPACE "\n" + COMMENT "-- order by one param" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "array_agg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "v" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "v" + WHITESPACE " " + DESC_KW "desc" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "vals" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- order by param 2" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "jsonb_object_agg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "k" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "v" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "v" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "vals" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- order by param 2 const" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "string_agg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + STRING "','" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- order by param 1" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "string_agg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + LITERAL + STRING "','" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "\"table\"" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- within group" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + LITERAL + FLOAT_NUMBER "0.5" + R_PAREN ")" + WHITESPACE " " + WITHIN_CLAUSE + WITHIN_KW "within" + WHITESPACE " " + GROUP_KW "group" + WHITESPACE " " + L_PAREN "(" + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- filter expr simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + FILTER_CLAUSE + FILTER_KW "filter" + WHITESPACE " " + L_PAREN "(" + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- filter expr" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "unfiltered" + COMMA "," + WHITESPACE "\n " + TARGET + CALL_EXPR + NAME_REF + IDENT "count" + ARG_LIST + L_PAREN "(" + STAR "*" + R_PAREN ")" + WHITESPACE " " + FILTER_CLAUSE + FILTER_KW "filter" + WHITESPACE " " + L_PAREN "(" + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "i" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "filtered" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "generate_series" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "s" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "i" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + ALL_KW "all" + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + DISTINCT_KW "distinct" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- variadic_func_calls" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + VARIADIC_KW "variadic" + WHITESPACE " " + NAME_REF + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + VARIADIC_KW "variadic" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- array" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "b" + ARG_LIST + L_PAREN "(" + VARIADIC_KW "variadic" + WHITESPACE " " + CAST_EXPR + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + R_BRACK "]" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + NUMERIC_KW "numeric" + L_BRACK "[" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- named" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "c" + ARG_LIST + L_PAREN "(" + VARIADIC_KW "variadic" + WHITESPACE " " + NAMED_ARG + NAME_REF + IDENT "arr" + WHITESPACE " " + FAT_ARROW "=>" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- last param" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + VARIADIC_KW "variadic" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- window_func_calls" + WHITESPACE "\n" + COMMENT "-- over partition" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "max" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + OVER_CLAUSE + OVER_KW "over" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + PARTITION_KW "partition" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "c" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- window name" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "max" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + OVER_CLAUSE + OVER_KW "over" + WHITESPACE " " + NAME_REF + IDENT "w_name" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_pg17_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_pg17_ok.snap new file mode 100644 index 00000000..60387b40 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_funcs_pg17_ok.snap @@ -0,0 +1,1142 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_funcs_pg17.sql +--- +SOURCE_FILE + WHITESPACE "\n" + COMMENT "-- json_table" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "jt" + DOT "." + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE "\n " + NAME_REF + IDENT "my_films" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + JSON_TABLE_KW "JSON_TABLE" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "js" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'$.favorites[*]'" + WHITESPACE " " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "kind" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.kind'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "title" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.films[*].title'" + WHITESPACE " " + WITH_KW "WITH" + WHITESPACE " " + WRAPPER_KW "WRAPPER" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "director" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.films[*].director'" + WHITESPACE " " + WITH_KW "WITH" + WHITESPACE " " + WRAPPER_KW "WRAPPER" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "jt" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_table_nested_path" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "jt" + DOT "." + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE "\n " + NAME_REF + IDENT "my_films" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + JSON_TABLE_KW "JSON_TABLE" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "js" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'$.favorites[*] ? (@.films[*].director == $filter)'" + WHITESPACE "\n " + PASSING_KW "PASSING" + WHITESPACE " " + LITERAL + STRING "'Alfred Hitchcock'" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + FILTER_KW "filter" + WHITESPACE "\n " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "kind" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.kind'" + COMMA "," + WHITESPACE "\n " + NESTED_KW "NESTED" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.films[*]'" + WHITESPACE " " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "title" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "FORMAT" + WHITESPACE " " + JSON_KW "JSON" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.title'" + WHITESPACE " " + OMIT_KW "OMIT" + WHITESPACE " " + QUOTES_KW "QUOTES" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "director" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.director'" + WHITESPACE " " + KEEP_KW "KEEP" + WHITESPACE " " + QUOTES_KW "QUOTES" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "jt" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_table_without_filter" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "jt" + DOT "." + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE "\n " + NAME_REF + IDENT "my_films" + COMMA "," + WHITESPACE "\n " + CALL_EXPR + NAME_REF + JSON_TABLE_KW "JSON_TABLE" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + WHITESPACE " " + NAME_REF + IDENT "js" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'$.favorites[*]'" + WHITESPACE "\n " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "kind" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.kind'" + COMMA "," + WHITESPACE "\n " + NESTED_KW "NESTED" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.films[*]'" + WHITESPACE " " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "title" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "FORMAT" + WHITESPACE " " + JSON_KW "JSON" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.title'" + WHITESPACE " " + OMIT_KW "OMIT" + WHITESPACE " " + QUOTES_KW "QUOTES" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "director" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.director'" + WHITESPACE " " + KEEP_KW "KEEP" + WHITESPACE " " + QUOTES_KW "QUOTES" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "jt" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_table_union" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + CALL_EXPR + NAME_REF + JSON_TABLE_KW "JSON_TABLE" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + WHITESPACE "\n" + CAST_EXPR + LITERAL + STRING "'{\"favorites\":\n {\"movies\":\n [{\"name\": \"One\", \"director\": \"John Doe\"},\n {\"name\": \"Two\", \"director\": \"Don Joe\"}],\n \"books\":\n [{\"name\": \"Mystery\", \"authors\": [{\"name\": \"Brown Dan\"}]},\n {\"name\": \"Wonder\", \"authors\": [{\"name\": \"Jun Murakami\"}, {\"name\":\"Craig Doe\"}]}]\n}}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'$.favorites[*]'" + WHITESPACE "\n" + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "user_id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NESTED_KW "NESTED" + WHITESPACE " " + LITERAL + STRING "'$.movies[*]'" + WHITESPACE "\n " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "movie_id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "mname" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.name'" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "director" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NESTED_KW "NESTED" + WHITESPACE " " + LITERAL + STRING "'$.books[*]'" + WHITESPACE "\n " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "book_id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "bname" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.name'" + COMMA "," + WHITESPACE "\n " + NESTED_KW "NESTED" + WHITESPACE " " + LITERAL + STRING "'$.authors[*]'" + WHITESPACE "\n " + COLUMNS_KW "COLUMNS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + NAME + IDENT "author_id" + WHITESPACE " " + FOR_KW "FOR" + WHITESPACE " " + ORDINALITY_KW "ORDINALITY" + COMMA "," + WHITESPACE "\n " + NAME + IDENT "author_name" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + PATH_KW "PATH" + WHITESPACE " " + LITERAL + STRING "'$.name'" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_KW "json" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_KW "json" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITH_KW "with" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + KEYS_KW "keys" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_KW "json" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITH_KW "with" + WHITESPACE " " + UNIQUE_KW "unique" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_KW "json" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITHOUT_KW "without" + WHITESPACE " " + UNIQUE_KW "unique" + WHITESPACE " " + KEYS_KW "keys" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_KW "json" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_KEYS_UNIQUE_CLAUSE + WITHOUT_KW "without" + WHITESPACE " " + UNIQUE_KW "unique" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_serialize" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_SERIALIZE_KW "json_serialize" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_SERIALIZE_KW "json_serialize" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_SERIALIZE_KW "json_serialize" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_SERIALIZE_KW "json_serialize" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_query" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_QUERY_KW "json_query" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + JSON_WRAPPER_BEHAVIOR_CLAUSE + WITH_KW "with" + WHITESPACE " " + WRAPPER_KW "wrapper" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_QUERY_KW "json_query" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE " \n " + NAME_REF + IDENT "b" + WHITESPACE " " + JSON_PASSING_CLAUSE + PASSING_KW "passing" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "foo" + COMMA "," + WHITESPACE " \n " + NAME_REF + IDENT "d" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " \n " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " \n " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE " \n " + JSON_WRAPPER_BEHAVIOR_CLAUSE + WITH_KW "with" + WHITESPACE " " + UNCONDITIONAL_KW "unconditional" + WHITESPACE " " + ARRAY_KW "array" + WHITESPACE " " + WRAPPER_KW "wrapper" + WHITESPACE "\n " + JSON_QUOTES_CLAUSE + KEEP_KW "keep" + WHITESPACE " " + QUOTES_KW "quotes" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + SCALAR_KW "scalar" + WHITESPACE " " + STRING_KW "string" + WHITESPACE "\n " + JSON_BEHAVIOR_CLAUSE + UNKNOWN_KW "unknown" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EMPTY_KW "empty" + WHITESPACE "\n " + EMPTY_KW "empty" + WHITESPACE " " + ARRAY_KW "array" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ERROR_KW "error" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- json_exists" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_EXISTS_KW "json_exists" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_EXISTS_KW "json_exists" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + JSON_PASSING_CLAUSE + PASSING_KW "passing" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE "\n " + JSON_ON_ERROR_CLAUSE + DEFAULT_KW "default" + WHITESPACE " " + NAME_REF + IDENT "z" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ERROR_KW "error" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- doc examples" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_EXISTS_KW "JSON_EXISTS" + ARG_LIST + L_PAREN "(" + CAST_EXPR + NAME_REF + IDENT "jsonb" + WHITESPACE " " + LITERAL + STRING "'{\"key1\": [1,2,3]}'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'strict $.key1[*] ? (@ > $x)'" + WHITESPACE " " + JSON_PASSING_CLAUSE + PASSING_KW "PASSING" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "x" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_EXISTS_KW "JSON_EXISTS" + ARG_LIST + L_PAREN "(" + CAST_EXPR + NAME_REF + IDENT "jsonb" + WHITESPACE " " + LITERAL + STRING "'{\"a\": [1,2,3]}'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'lax $.a[5]'" + WHITESPACE " " + JSON_ON_ERROR_CLAUSE + ERROR_KW "ERROR" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + ERROR_KW "ERROR" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_EXISTS_KW "JSON_EXISTS" + ARG_LIST + L_PAREN "(" + CAST_EXPR + NAME_REF + IDENT "jsonb" + WHITESPACE " " + LITERAL + STRING "'{\"a\": [1,2,3]}'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'strict $.a[5]'" + WHITESPACE " " + JSON_ON_ERROR_CLAUSE + ERROR_KW "ERROR" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + ERROR_KW "ERROR" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_value" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_VALUE_KW "json_value" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + JSON_VALUE_KW "json_value" + ARG_LIST + L_PAREN "(" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + JSON_PASSING_CLAUSE + PASSING_KW "passing" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "d" + WHITESPACE "\n " + JSON_RETURNING_CLAUSE + RETURNING_KW "returning" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + WHITESPACE " " + JSON_FORMAT_CLAUSE + FORMAT_KW "format" + WHITESPACE " " + JSON_KW "json" + WHITESPACE "\n " + JSON_BEHAVIOR_CLAUSE + UNKNOWN_KW "unknown" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + EMPTY_KW "empty" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE " " + NAME_REF + IDENT "z" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + ERROR_KW "error" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_into_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_into_ok.snap new file mode 100644 index 00000000..aa9ed51b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_into_ok.snap @@ -0,0 +1,78 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_into.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + SELECT_INTO_STMT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + INTO_CLAUSE + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "films_recent" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "films" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "date_prod" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + LITERAL + STRING "'2002-01-01'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- more_schema" + WHITESPACE "\n" + SELECT_INTO_STMT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "c" + WHITESPACE " " + INTO_CLAUSE + INTO_KW "into" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "t" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t2" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_ok.snap new file mode 100644 index 00000000..e6bd9f77 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_ok.snap @@ -0,0 +1,5752 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select.sql +--- +SOURCE_FILE + COMMENT "-- parens_and_unions" + WHITESPACE "\n" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "NULL" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "NULL" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMPOUND_SELECT + PAREN_EXPR + L_PAREN "(" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "NULL" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "NULL" + R_PAREN ")" + WHITESPACE " " + UNION_KW "UNION" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- alias_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- from alias" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- non-ident column and table names" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + TARGET_KW "target" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + TARGET_KW "target" + COMMA "," + WHITESPACE " " + COLUMN + NAME + FUNCTION_KW "function" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- from column aliases" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "col1" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "col1" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "col2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- w/o as" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "3" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + TARGET_KW "target" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + TARGET_KW "target" + COMMA "," + WHITESPACE " " + COLUMN + NAME + FUNCTION_KW "function" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- from alias shorthand" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- date_funcs" + WHITESPACE "\n" + COMMENT "-- current_date" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_DATE_KW "current_date" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_time" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_TIME_KW "current_time" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + CURRENT_TIME_KW "current_time" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_timestamp" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_TIMESTAMP_KW "current_timestamp" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + CURRENT_TIMESTAMP_KW "current_timestamp" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- localtime" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + LOCALTIME_KW "localtime" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + LOCALTIME_KW "localtime" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- localtimestamp" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + LOCALTIMESTAMP_KW "localtimestamp" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + LOCALTIMESTAMP_KW "localtimestamp" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- array_select" + WHITESPACE "\n" + COMMENT "-- array with subquery" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + ARRAY_EXPR + ARRAY_KW "array" + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "oid" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "pg_proc" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "proname" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'bytea%'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- positional_param" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + PARAM "$1" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + PARAM "$1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- any_and_all" + WHITESPACE "\n" + COMMENT "-- all" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ALL_KW "all" + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- any" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'c'" + R_BRACK "]" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "3" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- some" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + CALL_EXPR + NAME_REF + SOME_KW "some" + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ALL_KW "all" + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all with array" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + PREFIX_EXPR + NOT_KW "not" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "tag" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ALL_KW "all" + L_PAREN "(" + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'c'" + R_BRACK "]" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- some, an alias for any" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + SOME_KW "some" + L_PAREN "(" + NAME_REF + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- any_values" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ANY_KW "any" + L_PAREN "(" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "c" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "d" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- field_exprs" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "mytable" + DOT "." + NAME_REF + IDENT "mycolumn" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + LITERAL + PARAM "$1" + DOT "." + NAME_REF + IDENT "somecolumn" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + PAREN_EXPR + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "rowfunction" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + NAME_REF + IDENT "b" + R_PAREN ")" + R_PAREN ")" + DOT "." + NAME_REF + IDENT "col3" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "compositecol" + R_PAREN ")" + DOT "." + NAME_REF + IDENT "somefield" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + PAREN_EXPR + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "mytable" + DOT "." + NAME_REF + IDENT "compositecol" + R_PAREN ")" + DOT "." + NAME_REF + IDENT "somefield" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "compositecol" + R_PAREN ")" + DOT "." + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- case_expr" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CASE_EXPR + CASE_KW "case" + WHITESPACE " " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + LITERAL + PARAM "$1" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + LITERAL + PARAM "$2" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + END_KW "end" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- generic conditional case" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE "\n " + TARGET + CASE_EXPR + CASE_KW "case" + WHITESPACE " " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'one'" + WHITESPACE "\n " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'two'" + WHITESPACE "\n " + ELSE_KW "else" + WHITESPACE " " + LITERAL + STRING "'other'" + WHITESPACE "\n " + END_KW "end" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "test" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ommitted else" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE "\n " + TARGET + CASE_EXPR + CASE_KW "case" + WHITESPACE " " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'one'" + WHITESPACE "\n " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'two'" + WHITESPACE "\n " + END_KW "end" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "test" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- switch style case" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE "\n " + TARGET + CASE_EXPR + CASE_KW "case" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'one'" + WHITESPACE "\n " + WHEN_CLAUSE + WHEN_KW "when" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + LITERAL + STRING "'two'" + WHITESPACE "\n " + ELSE_KW "else" + WHITESPACE " " + LITERAL + STRING "'other'" + WHITESPACE "\n " + END_KW "end" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "test" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- col_labels" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + NAME + IDENT "bar" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + NAME + IDENT "bar" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "x" + WHITESPACE " " + NAME + IDENT "y" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select" + WHITESPACE "\n" + COMMENT "-- ident" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi columns" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_quoted_ident" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "\"b.c\"" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_from_clause" + WHITESPACE "\n" + COMMENT "-- from tablename" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "foo" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from only" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from field expr" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "foo" + DOT "." + NAME_REF + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from with everything" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "r" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + WHITESPACE " " + TABLESAMPLE_KW "tablesample" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "sample_method" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "23" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "50" + R_PAREN ")" + WHITESPACE " " + REPEATABLE_KW "repeatable" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "42" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from select stmt" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + LATERAL_KW "lateral" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function call complex" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + ORDINALITY_KW "ordinality" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + ORDINALITY_KW "ordinality" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function with alias" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "bar" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function with column def" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "json_to_record" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'{\"a\": 1, \"b\": \"c\"}'" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- function with collate" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "bar" + DOT "." + PATH_SEGMENT + NAME_REF + IDENT "buzz" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + WHITESPACE " " + COLLATE + COLLATE_KW "collate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "\"bar\"" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple tables" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + ALIAS + NAME + IDENT "x" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "buzz" + WHITESPACE " " + ALIAS + NAME + IDENT "y" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "f" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "boo" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- from_item" + WHITESPACE "\n\n" + COMMENT "-- table_name from_item" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "z" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "z" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + NAME + IDENT "z" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + NAME + IDENT "z" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "foo" + DOT "." + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + NAME + IDENT "z" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with_query_name" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "b" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "x" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "y" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "z" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + NAME + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lateral select" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + LATERAL_KW "lateral" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lateral function_name" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + LATERAL_KW "lateral" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + ORDINALITY_KW "ordinality" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + LATERAL_KW "lateral" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- lateral rows from(" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + LATERAL_KW "lateral" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "x" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + INT_KW "int" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "y" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "z" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "int8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + ORDINALITY_KW "ordinality" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + ORDINALITY_KW "ordinality" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + FROM_KW "from" + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "f" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "t" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "c" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_where_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_limit_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LIMIT_CLAUSE + LIMIT_KW "limit" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_orderby_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- nulls" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + FIRST_KW "first" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + LAST_KW "last" + SEMICOLON ";" + WHITESPACE "\n\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NULLS_KW "nulls" + WHITESPACE " " + LAST_KW "last" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_window_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with window def order by" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with window def frame_start, frame_end" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + RANGE_KW "range" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + GROUPS_KW "groups" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- with window def frame_exclusion" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE " " + ROW_KW "row" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + GROUP_KW "group" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + TIES_KW "ties" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WINDOW_CLAUSE + WINDOW_KW "window" + WHITESPACE " " + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_DEF + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + OTHERS_KW "others" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- select_having_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + HAVING_CLAUSE + HAVING_KW "having" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- select_with_group_by_clause" + WHITESPACE "\n" + COMMENT "-- parens" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple expr" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi expr" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + INT_NUMBER "2" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- distinct" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rollup" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + ROLLUP_KW "rollup" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rollup multi" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + ROLLUP_KW "rollup" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + COMMA "," + WHITESPACE " " + ROLLUP_KW "rollup" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cube" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + CUBE_KW "cube" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- grouping sets" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + GROUP_BY_CLAUSE + GROUP_KW "group" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + GROUPING_KW "grouping" + WHITESPACE " " + SETS_KW "sets" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + WHITESPACE "\n " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_offset_clause" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + OFFSET_CLAUSE + OFFSET_KW "offset" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rows" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + OFFSET_CLAUSE + OFFSET_KW "offset" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ROW_KW "row" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + OFFSET_CLAUSE + OFFSET_KW "offset" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ROWS_KW "rows" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- select_with_fetch_clause" + WHITESPACE "\n" + COMMENT "-- first" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FETCH_KW "fetch" + WHITESPACE " " + FIRST_KW "first" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + WHITESPACE " " + ROWS_KW "rows" + WHITESPACE " " + ONLY_KW "only" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- next" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FETCH_KW "fetch" + WHITESPACE " " + NEXT_KW "next" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ROW_KW "row" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + TIES_KW "ties" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- simple_expr" + WHITESPACE "\n" + COMMENT "-- simple nested select" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + MINUS "-" + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_locking_clause" + WHITESPACE "\n" + COMMENT "-- nowait" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LOCKING_CLAUSE + FOR_KW "for" + WHITESPACE " " + SHARE_KW "share" + WHITESPACE " " + OF_KW "of" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple clauses" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LOCKING_CLAUSE + FOR_KW "for" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + NOWAIT_KW "nowait" + WHITESPACE " " + LOCKING_CLAUSE + FOR_KW "for" + WHITESPACE " " + UPDATE_KW "update" + WHITESPACE " " + SKIP_KW "skip" + WHITESPACE " " + LOCKED_KW "locked" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select from" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + NOT_IN + NOT_KW "not" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- composite_types" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + ROW_KW "row" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'fuzzy dice'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "42" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.99" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + TUPLE_EXPR + L_PAREN "(" + LITERAL + STRING "'fuzzy dice'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "42" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.99" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- join" + WHITESPACE "\n" + COMMENT "-- simple join" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "tb" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "tb" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "id" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- left" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + LEFT_KW "left" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + LEFT_KW "left" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "foo" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- right" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + RIGHT_KW "right" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + FULL_KW "full" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi conditions" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t2" + DOT "." + NAME_REF + IDENT "team_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "team_id" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t2" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "org_id" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- using w/ join alias" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cross join" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "c" + DOT "." + NAME_REF + IDENT "color_name" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "size_name" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "colors" + WHITESPACE " " + ALIAS + NAME + IDENT "c" + WHITESPACE " " + JOIN + CROSS_KW "CROSS" + WHITESPACE " " + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "sizes" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- inner join on true" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "fruit_name" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "c" + DOT "." + NAME_REF + IDENT "color_name" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "fruits" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + WHITESPACE " " + JOIN + INNER_KW "inner" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "colors" + WHITESPACE " " + ALIAS + NAME + IDENT "c" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + TRUE_KW "true" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple join clauses" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + JOIN + LEFT_KW "left" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "u" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "id" + R_PAREN ")" + WHITESPACE "\n" + JOIN + LEFT_KW "left" + WHITESPACE " " + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "k" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + EVENT_KW "event" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- natural" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "employees" + WHITESPACE " " + JOIN + NATURAL_KW "NATURAL" + WHITESPACE " " + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "departments" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg docs" + WHITESPACE "\n\n" + COMMENT "-- using" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "title" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "did" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + NAME_KW "name" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "date_prod" + COMMA "," + WHITESPACE " " + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "kind" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "distributors" + WHITESPACE " " + ALIAS + NAME + IDENT "d" + WHITESPACE " " + JOIN + JOIN_KW "JOIN" + WHITESPACE " " + NAME_REF + IDENT "films" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + WHITESPACE " " + USING_CLAUSE + USING_KW "USING" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "did" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + JOIN + JOIN_KW "join" + WHITESPACE " " + NAME_REF + IDENT "t2" + WHITESPACE " " + USING_CLAUSE + USING_KW "using" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + NAME_REF + IDENT "a_id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lateral" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "m" + DOT "." + NAME_REF + NAME_KW "name" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "mname" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "pname" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "manufacturers" + WHITESPACE " " + ALIAS + NAME + IDENT "m" + WHITESPACE " " + JOIN + LEFT_KW "LEFT" + WHITESPACE " " + JOIN_KW "JOIN" + WHITESPACE " " + LATERAL_KW "LATERAL" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "get_product_names" + ARG_LIST + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "m" + DOT "." + NAME_REF + IDENT "id" + R_PAREN ")" + WHITESPACE " " + ALIAS + NAME + IDENT "pname" + WHITESPACE " " + ON_KW "ON" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- table" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- only" + WHITESPACE "\n" + SELECT + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- star" + WHITESPACE "\n" + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- nested" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PAREN_EXPR + L_PAREN "(" + SELECT + TABLE_KW "table" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- union" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- distinct" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- intersect" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + INTERSECT_KW "intersect" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + INTERSECT_KW "intersect" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- distinct" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + INTERSECT_KW "intersect" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- except" + WHITESPACE "\n" + COMMENT "-- simple" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EXCEPT_KW "except" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EXCEPT_KW "except" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- distinct" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + EXCEPT_KW "except" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ident_edge_cases" + WHITESPACE "\n" + COMMENT "-- select keywords" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + SELECT_KW "select" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + FROM_KW "from" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + NAME + WHERE_KW "where" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NAME + ALL_KW "all" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- column labels that are also operators" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NAME + IS_KW "is" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NAME + AND_KW "and" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NAME + OR_KW "or" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NAME + COLLATE_KW "collate" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "foo" + DOT "." + NAME_REF + IDENT "bar" + WHITESPACE " " + NAME + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "foo" + DOT "." + NAME_REF + IDENT "bar" + WHITESPACE " " + NAME + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "c" + WHITESPACE " " + NAME + DEFAULT_KW "default" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "c" + WHITESPACE " " + NAME + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_special_funcs" + WHITESPACE "\n" + COMMENT "-- collation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + COLLATION_KW "collation" + WHITESPACE " " + FOR_KW "for" + WHITESPACE " " + ARG_LIST + L_PAREN "(" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_role" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_ROLE_KW "current_role" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_user" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_USER_KW "current_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- session_user" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + SESSION_USER_KW "session_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- system_user" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + SYSTEM_USER_KW "system_user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- user" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + USER_KW "user" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_catalog" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_CATALOG_KW "current_catalog" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- current_schema" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + CURRENT_SCHEMA_KW "current_schema" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- order_by_with_custom_op" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + USING_KW "using" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + R_ANGLE ">" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- order_by_regression" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "sensor_id" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "DATE_TRUNC" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'day'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "ts" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + DAY_KW "day" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "MAX" + ARG_LIST + L_PAREN "(" + NAME_REF + VALUE_KW "value" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "max_value" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "MIN" + ARG_LIST + L_PAREN "(" + NAME_REF + VALUE_KW "value" + R_PAREN ")" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "min_value" + WHITESPACE " \n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "sensors_uncompressed" + WHITESPACE " \n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "ts" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "DATE" + WHITESPACE " " + LITERAL + STRING "'2023-12-21'" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "ts" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "DATE" + WHITESPACE " " + LITERAL + STRING "'2023-12-22'" + WHITESPACE "\n" + GROUP_BY_CLAUSE + GROUP_KW "GROUP" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "sensor_id" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "DATE_TRUNC" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'day'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "ts" + R_PAREN ")" + WHITESPACE " \n" + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + NAME_REF + IDENT "sensor_id" + COMMA "," + WHITESPACE " " + NAME_REF + DAY_KW "day" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_from_user_table" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + USER_KW "user" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__select_operators_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_operators_ok.snap new file mode 100644 index 00000000..d2e41336 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__select_operators_ok.snap @@ -0,0 +1,5079 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/select_operators.sql +--- +SOURCE_FILE + COMMENT "-- logical_operators" + WHITESPACE "\n" + COMMENT "-- and" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- or" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + OR_KW "or" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + NOT_KW "not" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not is null" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + NOT_KW "not" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + NOT_KW "not" + WHITESPACE " " + POSTFIX_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + ISNULL_KW "isnull" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- geo_operators" + WHITESPACE "\n\n" + COMMENT "-- add" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(0,0)'" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(2,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- concat" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'[(0,0),(1,1)]'" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'[(2,2),(3,3),(4,4)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subtract" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(0,0)'" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(2,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiply" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'((0,0),(1,0),(1,1))'" + WHITESPACE " " + STAR "*" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(3.0,0)'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'((0,0),(1,0),(1,1))'" + WHITESPACE " " + STAR "*" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "point" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "cosd" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "45" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "sind" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "45" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- divide" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'((0,0),(1,0),(1,1))'" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(2.0,0)'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'((0,0),(1,0),(1,1))'" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "point" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "cosd" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "45" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "sind" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "45" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- length" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + AT "@" + MINUS "-" + AT "@" + WHITESPACE " " + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'[(0,0),(1,0),(1,1)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- center point" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + AT "@" + AT "@" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- number of points" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + POUND "#" + WHITESPACE " " + CAST_EXPR + NAME_REF + PATH_KW "path" + WHITESPACE " " + LITERAL + STRING "'((1,0),(0,1),(-1,0))'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- point intersection" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(0,0),(1,1)]'" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(1,0),(0,1)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- box intersection" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(-1,-1)'" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(-2,-2)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- closest point" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(0,0)'" + WHITESPACE " " + CUSTOM_OP + POUND "#" + POUND "#" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(2,0),(0,2)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- distance between" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(0,0),1>'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(5,0),1>'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first contains" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(0,0),2>'" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(1,1)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first contained in second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(1,1)'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(0,0),2>'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- objects overlap" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(0,0)'" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- object strictly left" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(0,0),1>'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(5,0),1>'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- object strictly right" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(5,0),1>'" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "circle" + WHITESPACE " " + LITERAL + STRING "'<(0,0),1>'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first extended to right of second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(0,0)'" + WHITESPACE " " + CUSTOM_OP + AMP "&" + L_ANGLE "<" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first extends to left of second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(3,3),(0,0)'" + WHITESPACE " " + CUSTOM_OP + AMP "&" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first strictly below second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(3,3),(0,0)'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(5,5),(3,4)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first strictly above second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(3,3),(0,0)'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(5,5),(3,4)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first doesn't extend above second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(1,1),(0,0)'" + WHITESPACE " " + CUSTOM_OP + AMP "&" + L_ANGLE "<" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first doesn't extend below second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(3,3),(0,0)'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + AMP "&" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first below second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'((1,1),(0,0))'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + CARET "^" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'((2,2),(1,1))'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first above second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'((2,2),(1,1))'" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + CARET "^" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'((1,1),(0,0))'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- objects intersect" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(-1,0),(1,0)]'" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + POUND "#" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "box" + WHITESPACE " " + LITERAL + STRING "'(2,2),(-2,-2)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- line horizontal" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + QUESTION "?" + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(-1,0),(1,0)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- points horizontally aligned" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(1,0)'" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + MINUS "-" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- line vertical" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + QUESTION "?" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(-1,0),(1,0)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- points vertically aligned" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(0,1)'" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "point" + WHITESPACE " " + LITERAL + STRING "'(0,0)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lines perpendicular" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(0,0),(0,1)]'" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + MINUS "-" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(0,0),(1,0)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- lines parallel" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(-1,0),(1,0)]'" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + PIPE "|" + PIPE "|" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "lseg" + WHITESPACE " " + LITERAL + STRING "'[(-1,2),(1,2)]'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- objects the same" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "polygon" + WHITESPACE " " + LITERAL + STRING "'((0,0),(1,1))'" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + EQ "=" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "polygon" + WHITESPACE " " + LITERAL + STRING "'((1,1),(0,0))'" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- network_operators" + WHITESPACE "\n\n" + COMMENT "-- subnet contained by or equal" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + EQ "=" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subnet contain or equal subnet" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + EQ "=" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- fts_operators" + WHITESPACE "\n\n" + COMMENT "-- negative tsquery" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + BANG "!" + BANG "!" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'cat'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "tsquery" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subnet contain or equal subnet" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + EQ "=" + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "inet" + WHITESPACE " " + LITERAL + STRING "'192.168.1/24'" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- array_operators" + WHITESPACE "\n" + COMMENT "-- first array (as a set) contain the second (as a set)?" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "4" + COMMA "," + LITERAL + INT_NUMBER "3" + R_BRACK "]" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "3" + COMMA "," + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "3" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first array (as a set) contained by the second (as a set)?" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "2" + COMMA "," + LITERAL + INT_NUMBER "2" + COMMA "," + LITERAL + INT_NUMBER "7" + R_BRACK "]" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "7" + COMMA "," + LITERAL + INT_NUMBER "4" + COMMA "," + LITERAL + INT_NUMBER "2" + COMMA "," + LITERAL + INT_NUMBER "6" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is there any overlap" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "4" + COMMA "," + LITERAL + INT_NUMBER "3" + R_BRACK "]" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + INT_NUMBER "2" + COMMA "," + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- concat" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + ARRAY_EXPR + ARRAY_KW "ARRAY" + L_BRACK "[" + ARRAY_EXPR + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COMMA "," + LITERAL + INT_NUMBER "2" + R_BRACK "]" + COMMA "," + ARRAY_EXPR + L_BRACK "[" + LITERAL + INT_NUMBER "3" + COMMA "," + LITERAL + INT_NUMBER "4" + R_BRACK "]" + R_BRACK "]" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "ARRAY" + L_BRACK "[" + ARRAY_EXPR + L_BRACK "[" + LITERAL + INT_NUMBER "5" + COMMA "," + LITERAL + INT_NUMBER "6" + R_BRACK "]" + COMMA "," + ARRAY_EXPR + L_BRACK "[" + LITERAL + INT_NUMBER "7" + COMMA "," + LITERAL + INT_NUMBER "8" + R_BRACK "]" + COMMA "," + ARRAY_EXPR + L_BRACK "[" + LITERAL + INT_NUMBER "9" + COMMA "," + LITERAL + INT_NUMBER "0" + R_BRACK "]" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- starts with" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'alphabet'" + WHITESPACE " " + CUSTOM_OP + CARET "^" + AT "@" + WHITESPACE " " + LITERAL + STRING "'alph'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- array_access" + WHITESPACE "\n" + COMMENT "-- first index" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + NAME_REF + IDENT "a" + L_BRACK "[" + LITERAL + INT_NUMBER "0" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- slicing" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + INDEX_EXPR + NAME_REF + IDENT "b" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COLON ":" + LITERAL + INT_NUMBER "2" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COLON ":" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- omitted bounds" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + INDEX_EXPR + NAME_REF + IDENT "c" + L_BRACK "[" + COLON ":" + LITERAL + INT_NUMBER "2" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "2" + COLON ":" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- omitted part 2" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + INDEX_EXPR + NAME_REF + IDENT "schedule" + L_BRACK "[" + COLON ":" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + COLON ":" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- string_operators" + WHITESPACE "\n" + COMMENT "-- concatenate" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'Post'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + STRING "'greSQL'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'Value: '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + LITERAL + INT_NUMBER "42" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- normalization check" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + NFC_KW "nfc" + WHITESPACE " " + NAME + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + NFD_KW "nfd" + WHITESPACE " " + NAME + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + NFKC_KW "nfkc" + WHITESPACE " " + NAME + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + NFKD_KW "nfkd" + WHITESPACE " " + NAME + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BYTE_STRING "U&'\\0061\\0308bc'" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NAME_REF + NFD_KW "nfd" + WHITESPACE " " + NAME + NORMALIZED_KW "normalized" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pattern_matching" + WHITESPACE "\n" + COMMENT "-- like" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'foo'" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'bar'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not like" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'foo'" + WHITESPACE " " + NOT_LIKE + NOT_KW "not" + WHITESPACE " " + LIKE_KW "like" + WHITESPACE " " + LITERAL + STRING "'bar'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ~~" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + TILDE "~" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- !~~" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + BANG "!" + TILDE "~" + TILDE "~" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- similar to" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'abc'" + WHITESPACE " " + SIMILAR_TO + SIMILAR_KW "similar" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + LITERAL + STRING "'abc'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- posix regex" + WHITESPACE "\n" + COMMENT "-- string matches regex case sensitive" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'foo'" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + WHITESPACE " " + LITERAL + STRING "'f.*'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- string matches regex case insensitive" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + STAR "*" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- string does not match regex case sensitive" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + BANG "!" + TILDE "~" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- string does not match regex case insensitive" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'a'" + WHITESPACE " " + CUSTOM_OP + BANG "!" + TILDE "~" + STAR "*" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- compare_operators" + WHITESPACE "\n" + COMMENT "-- less than" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- greater than" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "5" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- less than or equal to" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "8" + WHITESPACE " " + LTEQ "<=" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- greater than or equal to" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "9" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + LITERAL + INT_NUMBER "7" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- equal" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "5" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not equal" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NEQB "<>" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NEQ "!=" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- between (inclusive of the range endpoints)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "bar" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not between (the negation of between)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "foo" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "bar" + ARG_LIST + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- between symmetric (between, after sorting the two endpoint values)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + SYMMETRIC_KW "symmetric" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not between symmetric (not between, after sorting the two endpoint values)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BETWEEN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + BETWEEN_KW "between" + WHITESPACE " " + SYMMETRIC_KW "symmetric" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is distinct from (not equal, treating null as a comparable value)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IS_DISTINCT_FROM + IS_KW "is" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is not distinct from (equal, treating null as a comparable value)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IS_NOT_DISTINCT_FROM + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + DISTINCT_KW "distinct" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- at time zone" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'2024-01-01 12:00:00'" + WHITESPACE " " + AT_TIME_ZONE + AT_KW "at" + WHITESPACE " " + TIME_KW "time" + WHITESPACE " " + ZONE_KW "zone" + WHITESPACE " " + LITERAL + STRING "'UTC'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is null" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + FLOAT_NUMBER "1.5" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is not null" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'null'" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- isnull (non-standard syntax)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + POSTFIX_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + ISNULL_KW "isnull" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- notnull (non-standard syntax)" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + POSTFIX_EXPR + LITERAL + STRING "'foo'" + WHITESPACE " " + ISNULL_KW "isnull" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is true" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is not true" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is false" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is not false" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + FALSE_KW "false" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is unknown" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_KW "is" + WHITESPACE " " + NAME_REF + UNKNOWN_KW "unknown" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- is not unknown" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + TRUE_KW "true" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NAME_REF + UNKNOWN_KW "unknown" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- math_operators" + WHITESPACE "\n" + COMMENT "-- addition" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- unary plus" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + PLUS "+" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "3.5" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subtraction" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- negation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + MINUS "-" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + PREFIX_EXPR + MINUS "-" + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiplication" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- division" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + FLOAT_NUMBER "5.0" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "5" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PAREN_EXPR + L_PAREN "(" + PREFIX_EXPR + MINUS "-" + LITERAL + INT_NUMBER "5" + R_PAREN ")" + WHITESPACE " " + SLASH "/" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- modulo" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "5" + WHITESPACE " " + PERCENT "%" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- exponentiation" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + CARET "^" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + CARET "^" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + LITERAL + INT_NUMBER "3" + WHITESPACE " " + CARET "^" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- square root" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + PIPE "|" + SLASH "/" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "25.0" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cube root" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + PIPE "|" + PIPE "|" + SLASH "/" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "64.0" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- absolute value" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + AT "@" + WHITESPACE " " + PREFIX_EXPR + MINUS "-" + LITERAL + FLOAT_NUMBER "5.0" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise and" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "91" + WHITESPACE " " + CUSTOM_OP + AMP "&" + WHITESPACE " " + LITERAL + INT_NUMBER "15" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise or" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "32" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise exclusive OR" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "17" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise NOT" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + TILDE "~" + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise shift left" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "4" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise shift right" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "8" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitstring_operators" + WHITESPACE "\n" + COMMENT "-- bitwise and" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BIT_STRING "B'10001'" + WHITESPACE " " + CUSTOM_OP + AMP "&" + WHITESPACE " " + LITERAL + BIT_STRING "B'01101'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise or" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BIT_STRING "B'10001'" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + WHITESPACE " " + LITERAL + BIT_STRING "B'01101'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise xor" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BIT_STRING "B'10001'" + WHITESPACE " " + CUSTOM_OP + POUND "#" + WHITESPACE " " + LITERAL + BIT_STRING "B'01101'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitwise not" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + TILDE "~" + WHITESPACE " " + LITERAL + BIT_STRING "B'10001'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitshift left" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BIT_STRING "B'10001'" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- bitshift right" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + BIT_STRING "B'10001'" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- range" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "7" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json_ops" + WHITESPACE "\n" + COMMENT "-- extract" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[{\"a\":\"foo\"},{\"b\":\"bar\"},{\"c\":\"baz\"}]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": {\"b\":\"foo\"}}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + LITERAL + STRING "'a'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract as text" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[1,2,3]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\":1,\"b\":2}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract path as json" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": {\"b\": [\"foo\",\"bar\"]}}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + POUND "#" + R_ANGLE ">" + WHITESPACE " " + LITERAL + STRING "'{a,b,1}'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extract path as text" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": {\"b\": [\"foo\",\"bar\"]}}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + JSON_KW "json" + WHITESPACE " " + CUSTOM_OP + POUND "#" + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + LITERAL + STRING "'{a,b,1}'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- contains" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'\"foo\"'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'\"foo\"'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"b\":2}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'{\"a\":1, \"b\":2}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- existence" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\":1, \"b\":2}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", \"b\", \"c\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- any keys exist" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\":1, \"b\":2, \"c\":3}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + PIPE "|" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'d'" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- all keys exist" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", \"b\", \"c\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + QUESTION "?" + AMP "&" + WHITESPACE " " + ARRAY_EXPR + ARRAY_KW "array" + L_BRACK "[" + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'b'" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- concat" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", \"b\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'[\"a\", \"d\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": \"b\"}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'{\"c\": \"d\"}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[1, 2]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'3'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": \"b\"}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'42'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[1, 2]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "jsonb_build_array" + ARG_LIST + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'[3, 4]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- delete" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": \"b\", \"c\": \"d\"}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + LITERAL + STRING "'a'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", \"b\", \"c\", \"b\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + LITERAL + STRING "'b'" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\": \"b\", \"c\": \"d\"}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'{a,c}'" + COLON2 "::" + ARRAY_TYPE + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + TEXT_KW "text" + L_BRACK "[" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", \"b\"]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- delete at path" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[\"a\", {\"b\":1}]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + POUND "#" + MINUS "-" + WHITESPACE " " + LITERAL + STRING "'{1,b}'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json path find" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"items\": [1, 2, 3]}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + AT "@" + QUESTION "?" + WHITESPACE " " + LITERAL + STRING "'$.items[*] ? (@ > 2)'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- json path predicate check" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'{\"a\":[1,2,3,4,5]}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + WHITESPACE " " + CUSTOM_OP + AT "@" + AT "@" + WHITESPACE " " + LITERAL + STRING "'$.a[*] > 2'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- subscripting" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + NAME_REF + IDENT "foo" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + NAME_REF + IDENT "bar" + L_BRACK "[" + LITERAL + STRING "'a'" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + PAREN_EXPR + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'[1, \"2\", null]'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + PAREN_EXPR + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'{\"a\": 1}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + L_BRACK "[" + LITERAL + STRING "'a'" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + INDEX_EXPR + INDEX_EXPR + PAREN_EXPR + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'{\"a\": {\"b\": {\"c\": 1}}}'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "jsonb" + R_PAREN ")" + L_BRACK "[" + LITERAL + STRING "'a'" + R_BRACK "]" + L_BRACK "[" + LITERAL + STRING "'b'" + R_BRACK "]" + L_BRACK "[" + LITERAL + STRING "'c'" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + FIELD_EXPR + NAME_REF + IDENT "mytable" + DOT "." + NAME_REF + IDENT "arraycolumn" + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + INDEX_EXPR + FIELD_EXPR + NAME_REF + IDENT "mytable" + DOT "." + NAME_REF + IDENT "two_d_column" + L_BRACK "[" + LITERAL + INT_NUMBER "17" + R_BRACK "]" + L_BRACK "[" + LITERAL + INT_NUMBER "34" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + LITERAL + PARAM "$1" + L_BRACK "[" + LITERAL + INT_NUMBER "10" + COLON ":" + LITERAL + INT_NUMBER "42" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + INDEX_EXPR + PAREN_EXPR + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "arrayfunction" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "a" + COMMA "," + NAME_REF + IDENT "b" + R_PAREN ")" + R_PAREN ")" + L_BRACK "[" + LITERAL + INT_NUMBER "42" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_with_collate" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + LITERAL + STRING "'foo'" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"fr_FR\"" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"de_DE\"" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + STRING "'Å'" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + LITERAL + STRING "'A'" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "ignore_accent_case" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"de_DE\"" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + WHITESPACE " " + L_ANGLE "<" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"POSIX\"" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE " " + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"fr_FR\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + BANG "!" + BANG "!" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PREFIX_EXPR + MINUS "-" + NAME_REF + IDENT "a" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PREFIX_EXPR + PLUS "+" + NAME_REF + IDENT "a" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PREFIX_EXPR + MINUS "-" + INDEX_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "a" + L_BRACK "[" + LITERAL + INT_NUMBER "0" + R_BRACK "]" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + PREFIX_EXPR + MINUS "-" + CAST_EXPR + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "b" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"C\"" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- cube_operators" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + TILDE "~" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + POUND "#" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + EQ "=" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- more_ops" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + PLUS "+" + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- prefix operators" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + STAR "*" + STAR "*" + WHITESPACE " " + NAME_REF + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- range_operators" + WHITESPACE "\n" + COMMENT "-- contains" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- contains element" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CAST_EXPR + LITERAL + STRING "'[2011-01-01,2011-03-01)'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "tsrange" + WHITESPACE " " + CUSTOM_OP + AT "@" + R_ANGLE ">" + WHITESPACE " " + CAST_EXPR + LITERAL + STRING "'2011-01-10'" + COLON2 "::" + TIME_TYPE + NAME_REF + TIMESTAMP_KW "timestamp" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first contained by second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "7" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- element contained in range" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "42" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + AT "@" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int4range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "7" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- range overlap" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "7" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + AMP "&" + AMP "&" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "4" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "12" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first range strictly left" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + L_ANGLE "<" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "110" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first range strictly right" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "50" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "60" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "20" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "30" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first range not extend right of second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + AMP "&" + L_ANGLE "<" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "18" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- first range not extend left of second" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "7" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + AMP "&" + R_ANGLE ">" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "10" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- ranges adjacent" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "numrange" + ARG_LIST + L_PAREN "(" + LITERAL + FLOAT_NUMBER "1.1" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "2.2" + R_PAREN ")" + WHITESPACE " " + CUSTOM_OP + MINUS "-" + PIPE "|" + MINUS "-" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "numrange" + ARG_LIST + L_PAREN "(" + LITERAL + FLOAT_NUMBER "2.2" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "3.3" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- union" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "numrange" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "15" + R_PAREN ")" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "numrange" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- intersection" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "15" + R_PAREN ")" + WHITESPACE " " + STAR "*" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- difference" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "15" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + WHITESPACE " " + CALL_EXPR + NAME_REF + IDENT "int8range" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "20" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- OVERLAPS" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + TUPLE_EXPR + L_PAREN "(" + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2001-02-16'" + COMMA "," + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2001-12-21'" + R_PAREN ")" + WHITESPACE " " + OVERLAPS_KW "overlaps" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2001-10-30'" + COMMA "," + WHITESPACE " " + CAST_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + LITERAL + STRING "'2002-10-30'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- postfix operators" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + LITERAL + NULL_KW "null" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + IS_NOT + IS_KW "is" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + NAME_REF + UNKNOWN_KW "unknown" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- single tuple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multi tuple" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- not_in" + WHITESPACE "\n" + COMMENT "-- select" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + BIN_EXPR + LITERAL + INT_NUMBER "1" + WHITESPACE " " + NOT_IN + NOT_KW "not" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- single char operators that are okay in the prefix position" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + PLUS "+" + NAME_REF + IDENT "a" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + MINUS "-" + NAME_REF + IDENT "b" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + TILDE "~" + NAME_REF + IDENT "h" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + BANG "!" + NAME_REF + IDENT "i" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + AT "@" + NAME_REF + IDENT "j" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + POUND "#" + NAME_REF + IDENT "k" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + AMP "&" + NAME_REF + IDENT "n" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + PIPE "|" + NAME_REF + IDENT "o" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + QUESTION "?" + NAME_REF + IDENT "q" + SEMICOLON ";" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + PREFIX_EXPR + CUSTOM_OP + BACKTICK "`" + NAME_REF + IDENT "p" + SEMICOLON ";" + WHITESPACE "\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__set_constraints_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_constraints_ok.snap new file mode 100644 index 00000000..8aa51bf9 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_constraints_ok.snap @@ -0,0 +1,70 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/set_constraints.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + SET_CONSTRAINTS_STMT + SET_KW "set" + WHITESPACE " " + CONSTRAINTS_KW "constraints" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + DEFERRED_KW "deferred" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_CONSTRAINTS_STMT + SET_KW "set" + WHITESPACE " " + CONSTRAINTS_KW "constraints" + WHITESPACE " " + ALL_KW "all" + WHITESPACE " " + IMMEDIATE_KW "immediate" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_CONSTRAINTS_STMT + SET_KW "set" + WHITESPACE " " + CONSTRAINTS_KW "constraints" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + COMMA "," + WHITESPACE " " + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + DOT "." + PATH_SEGMENT + NAME + IDENT "b" + WHITESPACE " " + IMMEDIATE_KW "immediate" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_CONSTRAINTS_STMT + SET_KW "set" + WHITESPACE " " + CONSTRAINTS_KW "constraints" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME + IDENT "bar" + WHITESPACE " " + IMMEDIATE_KW "immediate" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__set_role_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_role_ok.snap new file mode 100644 index 00000000..35937c25 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_role_ok.snap @@ -0,0 +1,50 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/set_role.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + SET_ROLE_STMT + SET_KW "SET" + WHITESPACE " " + ROLE_KW "ROLE" + WHITESPACE " " + LITERAL + STRING "'paul'" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_ROLE_STMT + SET_KW "SET" + WHITESPACE " " + ROLE_KW "ROLE" + WHITESPACE " " + NONE_KW "NONE" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_ROLE_STMT + SET_KW "SET" + WHITESPACE " " + LOCAL_KW "LOCAL" + WHITESPACE " " + ROLE_KW "ROLE" + WHITESPACE " " + NONE_KW "NONE" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_ROLE_STMT + SET_KW "SET" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + ROLE_KW "ROLE" + WHITESPACE " " + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_ROLE_STMT + RESET_KW "RESET" + WHITESPACE " " + ROLE_KW "ROLE" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__set_session_auth_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_session_auth_ok.snap new file mode 100644 index 00000000..6bd47fb4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_session_auth_ok.snap @@ -0,0 +1,50 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/set_session_auth.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + SET_SESSION_AUTH_STMT + SET_KW "SET" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + AUTHORIZATION_KW "AUTHORIZATION" + WHITESPACE " " + DECIMAL_KW "decimal" + SEMICOLON ";" + WHITESPACE "\n" + SET_SESSION_AUTH_STMT + SET_KW "SET" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + AUTHORIZATION_KW "AUTHORIZATION" + WHITESPACE " " + LITERAL + STRING "'foo'" + SEMICOLON ";" + WHITESPACE "\n" + SET_SESSION_AUTH_STMT + SET_KW "SET" + WHITESPACE " " + LOCAL_KW "LOCAL" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + AUTHORIZATION_KW "AUTHORIZATION" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + SEMICOLON ";" + WHITESPACE "\n" + SET_SESSION_AUTH_STMT + RESET_KW "RESET" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + AUTHORIZATION_KW "AUTHORIZATION" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__set_transaction_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_transaction_ok.snap new file mode 100644 index 00000000..4b839617 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__set_transaction_ok.snap @@ -0,0 +1,64 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/set_transaction.sql +--- +SOURCE_FILE + COMMENT "-- docs" + WHITESPACE "\n" + SET_TRANSACTION_STMT + SET_KW "SET" + WHITESPACE " " + TRANSACTION_KW "TRANSACTION" + WHITESPACE " " + SNAPSHOT_KW "SNAPSHOT" + WHITESPACE " " + LITERAL + STRING "'00000003-0000001B-1'" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_TRANSACTION_STMT + SET_KW "SET" + WHITESPACE " " + SESSION_KW "SESSION" + WHITESPACE " " + CHARACTERISTICS_KW "CHARACTERISTICS" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + TRANSACTION_KW "TRANSACTION" + WHITESPACE " " + ISOLATION_KW "ISOLATION" + WHITESPACE " " + LEVEL_KW "LEVEL" + WHITESPACE " " + READ_KW "READ" + WHITESPACE " " + COMMITTED_KW "COMMITTED" + COMMA "," + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" + SEMICOLON ";" + WHITESPACE "\n\n" + SET_TRANSACTION_STMT + SET_KW "SET" + WHITESPACE " " + TRANSACTION_KW "TRANSACTION" + WHITESPACE " " + ISOLATION_KW "ISOLATION" + WHITESPACE " " + LEVEL_KW "LEVEL" + WHITESPACE " " + SERIALIZABLE_KW "SERIALIZABLE" + COMMA "," + WHITESPACE " " + READ_KW "READ" + WHITESPACE " " + WRITE_KW "WRITE" + COMMA "," + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + DEFERRABLE_KW "DEFERRABLE" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__transaction_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__transaction_ok.snap new file mode 100644 index 00000000..6d7d21b3 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__transaction_ok.snap @@ -0,0 +1,447 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/transaction.sql +--- +SOURCE_FILE + COMMENT "-- begin_commit_abort_rollback" + WHITESPACE "\n" + COMMENT "-- https://www.postgresql.org/docs/17/sql-commit.html" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + WHITESPACE " " + WORK_KW "work" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + WHITESPACE " " + TRANSACTION_KW "transaction" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "commit" + WHITESPACE " " + PREPARED_KW "prepared" + WHITESPACE " " + LITERAL + STRING "'bar'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- https://www.postgresql.org/docs/17/sql-begin.html" + WHITESPACE "\n" + BEGIN_STMT + BEGIN_KW "begin" + SEMICOLON ";" + WHITESPACE "\n" + BEGIN_STMT + BEGIN_KW "begin" + WHITESPACE " " + TRANSACTION_KW "transaction" + SEMICOLON ";" + WHITESPACE "\n" + BEGIN_STMT + BEGIN_KW "begin" + WHITESPACE " " + WORK_KW "work" + SEMICOLON ";" + WHITESPACE "\n" + BEGIN_STMT + BEGIN_KW "begin" + WHITESPACE " \n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" + WHITESPACE "\n " + DEFERRABLE_KW "deferrable" + WHITESPACE "\n " + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n\n" + BEGIN_STMT + BEGIN_KW "begin" + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + UNCOMMITTED_KW "uncommitted" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + REPEATABLE_KW "repeatable" + WHITESPACE " " + READ_KW "read" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SERIALIZABLE_KW "serializable" + COMMA "," + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" + COMMA "," + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" + COMMA "," + WHITESPACE "\n " + DEFERRABLE_KW "deferrable" + COMMA "," + WHITESPACE "\n " + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n\n" + BEGIN_STMT + START_KW "start" + WHITESPACE " " + TRANSACTION_KW "transaction" + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" + WHITESPACE "\n " + DEFERRABLE_KW "deferrable" + WHITESPACE "\n " + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n\n" + BEGIN_STMT + START_KW "start" + WHITESPACE " " + TRANSACTION_KW "transaction" + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + UNCOMMITTED_KW "uncommitted" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + REPEATABLE_KW "repeatable" + WHITESPACE " " + READ_KW "read" + COMMA "," + WHITESPACE "\n " + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SERIALIZABLE_KW "serializable" + COMMA "," + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" + COMMA "," + WHITESPACE "\n " + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" + COMMA "," + WHITESPACE "\n " + DEFERRABLE_KW "deferrable" + COMMA "," + WHITESPACE "\n " + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" + SEMICOLON ";" + WHITESPACE "\n\n" + PREPARE_TRANSACTION_STMT + PREPARE_KW "prepare" + WHITESPACE " " + TRANSACTION_KW "transaction" + WHITESPACE " " + LITERAL + STRING "'f'" + SEMICOLON ";" + WHITESPACE "\n\n" + SAVEPOINT_STMT + SAVEPOINT_KW "savepoint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + RELEASE_SAVEPOINT_STMT + RELEASE_KW "release" + WHITESPACE " " + SAVEPOINT_KW "savepoint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + RELEASE_SAVEPOINT_STMT + RELEASE_KW "release" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SAVEPOINT_KW "savepoint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + WORK_KW "work" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SAVEPOINT_KW "savepoint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + TRANSACTION_KW "transaction" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SAVEPOINT_KW "savepoint" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + WORK_KW "work" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + TRANSACTION_KW "transaction" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMIT_STMT + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + END_KW "end" + WHITESPACE " " + WORK_KW "work" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + END_KW "end" + WHITESPACE " " + TRANSACTION_KW "transaction" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + END_KW "end" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + COMMIT_STMT + END_KW "end" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n\n" + ROLLBACK_STMT + ABORT_KW "abort" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ABORT_KW "abort" + WHITESPACE " " + WORK_KW "work" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ABORT_KW "abort" + WHITESPACE " " + TRANSACTION_KW "transaction" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ABORT_KW "abort" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ABORT_KW "abort" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + WORK_KW "work" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + TRANSACTION_KW "transaction" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + CHAIN_KW "chain" + SEMICOLON ";" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "rollback" + WHITESPACE " " + PREPARED_KW "prepared" + WHITESPACE " " + LITERAL + STRING "'foo'" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__truncate_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__truncate_ok.snap new file mode 100644 index 00000000..11d06eb7 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__truncate_ok.snap @@ -0,0 +1,92 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/truncate.sql +--- +SOURCE_FILE + COMMENT "-- pg_grammar" + WHITESPACE "\n" + TRUNCATE_STMT + TRUNCATE_KW "truncate" + WHITESPACE " " + TABLE_KW "table" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE "\n" + RESTART_KW "restart" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE "\n" + CASCADE_KW "cascade" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- multiple_tables" + WHITESPACE "\n" + TRUNCATE_STMT + TRUNCATE_KW "TRUNCATE" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "b" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- rest" + WHITESPACE "\n" + TRUNCATE_STMT + TRUNCATE_KW "truncate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + SEMICOLON ";" + WHITESPACE "\n" + TRUNCATE_STMT + TRUNCATE_KW "truncate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + CONTINUE_KW "continue" + WHITESPACE " " + IDENTITY_KW "identity" + SEMICOLON ";" + WHITESPACE "\n" + TRUNCATE_STMT + TRUNCATE_KW "truncate" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "a" + WHITESPACE " " + CONTINUE_KW "continue" + WHITESPACE " " + IDENTITY_KW "identity" + WHITESPACE " " + RESTRICT_KW "restrict" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__unlisten_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__unlisten_ok.snap new file mode 100644 index 00000000..dce1513f --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__unlisten_ok.snap @@ -0,0 +1,20 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/unlisten.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + UNLISTEN_STMT + UNLISTEN_KW "unlisten" + WHITESPACE " " + NAME + IDENT "virtual" + SEMICOLON ";" + WHITESPACE "\n\n" + UNLISTEN_STMT + UNLISTEN_KW "unlisten" + WHITESPACE " " + STAR "*" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__update_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__update_ok.snap new file mode 100644 index 00000000..85bf43be --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__update_ok.snap @@ -0,0 +1,1232 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/update.sql +--- +SOURCE_FILE + COMMENT "-- update" + WHITESPACE "\n" + COMMENT "-- update where" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "price" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "price" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- no where" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "products" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "price" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "price" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.10" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- set muliple" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "mytable" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "5" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- sub_select" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "z" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- with_stmt" + WHITESPACE "\n" + UPDATE_STMT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t1" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + UPDATE_KW "update" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t2" + WHITESPACE " " + SET_KW "set" + WHITESPACE " \n " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "t1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "t2" + DOT "." + NAME_REF + IDENT "foo_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t1" + DOT "." + NAME_REF + IDENT "foo_id" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- based_on_schema" + WHITESPACE "\n" + COMMENT "-- all options" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "update" + WHITESPACE " " + ONLY_KW "only" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + ALIAS + AS_KW "as" + WHITESPACE " " + NAME + IDENT "t2" + WHITESPACE " \n" + SET_KW "set" + WHITESPACE " \n " + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + NAME_REF + IDENT "a" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ROW_KW "row" + L_PAREN "(" + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + NAME_REF + IDENT "z" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "b" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "t2" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "t" + WHITESPACE "\n" + RETURNING_KW "returning" + WHITESPACE " " + STAR "*" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "foo" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + IDENT "bar" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg_docs" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Dramatic'" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Drama'" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "weather" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "temp_lo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "temp_hi" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "15" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "prcp" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "city" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'San Francisco'" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'2003-07-03'" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "weather" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "temp_lo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "temp_hi" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "15" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "prcp" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "DEFAULT" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "city" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'San Francisco'" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'2003-07-03'" + WHITESPACE "\n " + RETURNING_KW "RETURNING" + WHITESPACE " " + NAME_REF + IDENT "temp_lo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "temp_hi" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "prcp" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "weather" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "temp_lo" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "temp_hi" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "prcp" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "temp_lo" + PLUS "+" + LITERAL + INT_NUMBER "15" + COMMA "," + WHITESPACE " " + DEFAULT_KW "DEFAULT" + R_PAREN ")" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + NAME_REF + IDENT "city" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'San Francisco'" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "date" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'2003-07-03'" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "sales_count" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "sales_count" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "accounts" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "accounts" + DOT "." + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Acme Corporation'" + WHITESPACE "\n " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "employees" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "accounts" + DOT "." + NAME_REF + IDENT "sales_person" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "sales_count" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "sales_count" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE "\n " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "sales_person" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "accounts" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + NAME_KW "name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Acme Corporation'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "accounts" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "contact_first_name" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "contact_last_name" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE "\n " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + NAME_REF + IDENT "first_name" + COMMA "," + WHITESPACE " " + TARGET + NAME_REF + IDENT "last_name" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "employees" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "employees" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "accounts" + DOT "." + NAME_REF + IDENT "sales_person" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "accounts" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "contact_first_name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "first_name" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "contact_last_name" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "last_name" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "employees" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "employees" + DOT "." + NAME_REF + IDENT "id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "accounts" + DOT "." + NAME_REF + IDENT "sales_person" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "summary" + WHITESPACE " " + ALIAS + NAME + IDENT "s" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + L_PAREN "(" + NAME_REF + IDENT "sum_x" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "sum_y" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "avg_x" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "avg_y" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE "\n " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "x" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "sum" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "y" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "x" + R_PAREN ")" + COMMA "," + WHITESPACE " " + TARGET + CALL_EXPR + NAME_REF + IDENT "avg" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "y" + R_PAREN ")" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + DATA_KW "data" + WHITESPACE " " + ALIAS + NAME + IDENT "d" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "d" + DOT "." + NAME_REF + IDENT "group_id" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "group_id" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + BEGIN_STMT + BEGIN_KW "BEGIN" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- other operations" + WHITESPACE "\n" + SAVEPOINT_STMT + SAVEPOINT_KW "SAVEPOINT" + WHITESPACE " " + NAME_REF + IDENT "sp1" + SEMICOLON ";" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wines" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + LITERAL + STRING "'Chateau Lafite 2003'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'24'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- Assume the above fails because of a unique key violation," + WHITESPACE "\n" + COMMENT "-- so now we issue these commands:" + WHITESPACE "\n" + ROLLBACK_STMT + ROLLBACK_KW "ROLLBACK" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + NAME_REF + IDENT "sp1" + SEMICOLON ";" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "wines" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "stock" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "stock" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "24" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "winename" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Chateau Lafite 2003'" + SEMICOLON ";" + WHITESPACE "\n" + COMMENT "-- continue with other operations, and eventually" + WHITESPACE "\n" + COMMIT_STMT + COMMIT_KW "COMMIT" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'Dramatic'" + WHITESPACE " " + WHERE_KW "WHERE" + WHITESPACE " " + CURRENT_KW "CURRENT" + WHITESPACE " " + OF_KW "OF" + WHITESPACE " " + IDENT "c_films" + SEMICOLON ";" + WHITESPACE "\n\n" + UPDATE_STMT + WITH_CLAUSE + WITH_KW "WITH" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "exceeded_max_retries" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "ctid" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "work_item" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "w" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "status" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'active'" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "num_retries" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE "\n " + ORDER_BY_CLAUSE + ORDER_KW "ORDER" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "retry_timestamp" + WHITESPACE "\n " + LOCKING_CLAUSE + FOR_KW "FOR" + WHITESPACE " " + UPDATE_KW "UPDATE" + WHITESPACE "\n " + LIMIT_CLAUSE + LIMIT_KW "LIMIT" + WHITESPACE " " + LITERAL + INT_NUMBER "5000" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE "\n" + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "work_item" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "status" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "'failed'" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "exceeded_max_retries" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "emr" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "work_item" + DOT "." + NAME_REF + IDENT "ctid" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "emr" + DOT "." + NAME_REF + IDENT "ctid" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__vacuum_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__vacuum_ok.snap new file mode 100644 index 00000000..91f074a4 --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__vacuum_ok.snap @@ -0,0 +1,238 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/vacuum.sql +--- +SOURCE_FILE + COMMENT "-- simple" + WHITESPACE "\n" + VACUUM_STMT + VACUUM_KW "vacuum" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pg_docs" + WHITESPACE "\n" + VACUUM_STMT + VACUUM_KW "VACUUM" + WHITESPACE " " + L_PAREN "(" + VERBOSE_KW "VERBOSE" + COMMA "," + WHITESPACE " " + ANALYZE_KW "ANALYZE" + R_PAREN ")" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "onek" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- full" + WHITESPACE "\n" + VACUUM_STMT + VACUUM_KW "VACUUM" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + FULL_KW "full" + COMMA "," + WHITESPACE " \n " + FULL_KW "full" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE " \n " + FULL_KW "full" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE " \n " + ANALYZE_KW "analyze" + COMMA "," + WHITESPACE "\n " + ANALYZE_KW "analyze" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + ANALYZE_KW "analyze" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + IDENT "disable_page_skipping" + COMMA "," + WHITESPACE "\n " + IDENT "disable_page_skipping" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + IDENT "disable_page_skipping" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + IDENT "skip_locked" + COMMA "," + WHITESPACE "\n " + IDENT "skip_locked" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + IDENT "skip_locked" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + IDENT "index_cleanup" + WHITESPACE " " + IDENT "auto" + COMMA "," + WHITESPACE "\n " + IDENT "index_cleanup" + WHITESPACE " " + ON_KW "on" + COMMA "," + WHITESPACE "\n " + IDENT "index_cleanup" + WHITESPACE " " + OFF_KW "off" + COMMA "," + WHITESPACE "\n " + IDENT "process_main" + COMMA "," + WHITESPACE "\n " + IDENT "process_main" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + IDENT "process_main" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + TRUNCATE_KW "truncate" + COMMA "," + WHITESPACE "\n " + TRUNCATE_KW "truncate" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + TRUNCATE_KW "truncate" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + PARALLEL_KW "parallel" + WHITESPACE " " + LITERAL + INT_NUMBER "100" + COMMA "," + WHITESPACE "\n " + IDENT "skip_database_stats" + COMMA "," + WHITESPACE "\n " + IDENT "skip_database_stats" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + IDENT "skip_database_stats" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + IDENT "only_database_stats" + COMMA "," + WHITESPACE "\n " + IDENT "only_database_stats" + WHITESPACE " " + LITERAL + TRUE_KW "true" + COMMA "," + WHITESPACE "\n " + IDENT "only_database_stats" + WHITESPACE " " + LITERAL + FALSE_KW "false" + COMMA "," + WHITESPACE "\n " + IDENT "buffer_usage_limit" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + COMMA "," + WHITESPACE "\n " + IDENT "buffer_usage_limit" + WHITESPACE " " + LITERAL + STRING "'10 TB'" + WHITESPACE "\n" + R_PAREN ")" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t1" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- pre_pg_9_syntax" + WHITESPACE "\n" + VACUUM_STMT + VACUUM_KW "vacuum" + WHITESPACE " " + FULL_KW "full" + WHITESPACE " " + FREEZE_KW "freeze" + WHITESPACE " " + VERBOSE_KW "verbose" + WHITESPACE " " + ANALYZE_KW "analyze" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + R_PAREN ")" + COMMA "," + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "c" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__values_err.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__values_err.snap new file mode 100644 index 00000000..b42ed33b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__values_err.snap @@ -0,0 +1,47 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/err/values.sql +--- +SOURCE_FILE + WHITESPACE "\n" + COMMENT "-- trailing comma and missing comma between value lists" + WHITESPACE "\n" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + ERROR + COMMA "," + R_PAREN ")" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- extra comma, aka missing tuple" + WHITESPACE "\n" + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + ERROR + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" +--- +ERROR@66: unexpected trailing comma +ERROR@68: expected COMMA +ERROR@120: expected L_PAREN diff --git a/crates/squawk_parser/src/snapshots/squawk_parser__test__values_ok.snap b/crates/squawk_parser/src/snapshots/squawk_parser__test__values_ok.snap new file mode 100644 index 00000000..6460184b --- /dev/null +++ b/crates/squawk_parser/src/snapshots/squawk_parser__test__values_ok.snap @@ -0,0 +1,562 @@ +--- +source: crates/squawk_parser/src/test.rs +input_file: crates/squawk_parser/test_data/ok/values.sql +--- +SOURCE_FILE + COMMENT "-- pg_docs" + WHITESPACE "\n" + SELECT + VALUES_KW "VALUES" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'one'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'two'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'three'" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- union_with_select" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "column1" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + STRING "'one'" + WHITESPACE " " + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "column2" + WHITESPACE "\n" + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + STRING "'two'" + WHITESPACE "\n" + UNION_KW "UNION" + WHITESPACE " " + ALL_KW "ALL" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + TARGET + LITERAL + STRING "'three'" + SEMICOLON ";" + WHITESPACE "\n\n\n\n\n" + COMMENT "-- insert_values" + WHITESPACE "\n" + INSERT_STMT + INSERT_KW "INSERT" + WHITESPACE " " + INTO_KW "INTO" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "films" + WHITESPACE " " + SELECT + VALUES_KW "VALUES" + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'UA502'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Bananas'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "105" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Comedy'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'82 minutes'" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + L_PAREN "(" + LITERAL + STRING "'T_601'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Yojimbo'" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "106" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Drama'" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "DEFAULT" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- in_select_from_position" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + STAR "*" + WHITESPACE "\n " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "films" + WHITESPACE " " + ALIAS + NAME + IDENT "f" + COMMA "," + WHITESPACE " " + L_PAREN "(" + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + LITERAL + STRING "'MGM'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Horror'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'UA'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'Sci-Fi'" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "t" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "studio" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "kind" + R_PAREN ")" + WHITESPACE "\n " + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "studio" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "studio" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "f" + DOT "." + NAME_REF + IDENT "kind" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "kind" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- update_from" + WHITESPACE "\n" + UPDATE_STMT + UPDATE_KW "UPDATE" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "employees" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " + NAME_REF + IDENT "salary" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "salary" + WHITESPACE " " + STAR "*" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "v" + DOT "." + NAME_REF + IDENT "increase" + WHITESPACE "\n" + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "200000" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.2" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "400000" + COMMA "," + WHITESPACE " " + LITERAL + FLOAT_NUMBER "1.4" + R_PAREN ")" + R_PAREN ")" + WHITESPACE " " + ALIAS + AS_KW "AS" + WHITESPACE " " + NAME + IDENT "v" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME + IDENT "depno" + COMMA "," + WHITESPACE " " + COLUMN + NAME + TARGET_KW "target" + COMMA "," + WHITESPACE " " + COLUMN + NAME + IDENT "increase" + R_PAREN ")" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "employees" + DOT "." + NAME_REF + IDENT "depno" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "v" + DOT "." + NAME_REF + IDENT "depno" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "employees" + DOT "." + NAME_REF + IDENT "sales" + WHITESPACE " " + GTEQ ">=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "v" + DOT "." + NAME_REF + TARGET_KW "target" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select_from_in" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "FROM" + WHITESPACE " " + NAME_REF + IDENT "machines" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "WHERE" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "ip_address" + WHITESPACE " " + IN_KW "IN" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + VALUES_KW "VALUES" + L_PAREN "(" + CAST_EXPR + LITERAL + STRING "'192.168.0.1'" + COLON2 "::" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "inet" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'192.168.0.10'" + R_PAREN ")" + COMMA "," + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'192.168.1.43'" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- union" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "4" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- union_select_values" + WHITESPACE "\n" + COMPOUND_SELECT + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + COMPOUND_SELECT + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + COMPOUND_SELECT + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + COMPOUND_SELECT + SELECT + VALUES_KW "values" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "2" + R_PAREN ")" + WHITESPACE " " + UNION_KW "union" + WHITESPACE " " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "3" + SEMICOLON ";" + WHITESPACE "\n\n" diff --git a/crates/squawk_parser/src/syntax_kind.rs b/crates/squawk_parser/src/syntax_kind.rs new file mode 100644 index 00000000..e5d84383 --- /dev/null +++ b/crates/squawk_parser/src/syntax_kind.rs @@ -0,0 +1,4678 @@ +// based on https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/syntax_kind/generated.rs +#![allow(bad_style, missing_docs, clippy::upper_case_acronyms)] + +use crate::token_set::TokenSet; +#[doc = r" The kind of syntax node, e.g. `IDENT`, `SELECT_KW`, or `STRUCT`."] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[repr(u16)] +/// Needs to be compatible with [`rowan::SyntaxKind`] +pub enum SyntaxKind { + #[doc(hidden)] + TOMBSTONE, + #[doc(hidden)] + EOF, + + // symbols + /// `;` + SEMICOLON, + /// `,` + COMMA, + /// `(` + L_PAREN, + /// `)` + R_PAREN, + /// `[` + L_BRACK, + /// `]` + R_BRACK, + /// `<` + L_ANGLE, + /// `>` + R_ANGLE, + /// `@` + AT, + /// `#` + POUND, + /// `~` + TILDE, + /// `?` + QUESTION, + /// `&` + AMP, + /// `|` + PIPE, + /// `+` + PLUS, + /// `*` + STAR, + /// `/` + SLASH, + /// `^` + CARET, + /// `%` + PERCENT, + /// `.` + DOT, + /// `:` + COLON, + /// `::` + COLON2, + /// `:=` + COLONEQ, + /// `=` + EQ, + /// `=>` + /// Used for `NAMED_ARG` + FAT_ARROW, + /// ``` + /// ` + /// ``` + BACKTICK, + /// `!` + BANG, + /// `!=` + NEQ, + /// `<>` + NEQB, + /// `-` + MINUS, + /// `<=` + LTEQ, + /// `>=` + GTEQ, + // catch all for custom operators + CUSTOM_OP, + + // keywords -- generated via: cargo xtrask generate-keywords + /// `abort` + ABORT_KW, + /// `absent` + ABSENT_KW, + /// `absolute` + ABSOLUTE_KW, + /// `access` + ACCESS_KW, + /// `action` + ACTION_KW, + /// `add` + ADD_KW, + /// `admin` + ADMIN_KW, + /// `after` + AFTER_KW, + /// `aggregate` + AGGREGATE_KW, + /// `all` + ALL_KW, + /// `also` + ALSO_KW, + /// `alter` + ALTER_KW, + /// `always` + ALWAYS_KW, + /// `analyse` + ANALYSE_KW, + /// `analyze` + ANALYZE_KW, + /// `and` + AND_KW, + /// `any` + ANY_KW, + /// `array` + ARRAY_KW, + /// `as` + AS_KW, + /// `asc` + ASC_KW, + /// `asensitive` + ASENSITIVE_KW, + /// `assertion` + ASSERTION_KW, + /// `assignment` + ASSIGNMENT_KW, + /// `asymmetric` + ASYMMETRIC_KW, + /// `at` + AT_KW, + /// `atomic` + ATOMIC_KW, + /// `attach` + ATTACH_KW, + /// `attribute` + ATTRIBUTE_KW, + /// `authorization` + AUTHORIZATION_KW, + /// `backward` + BACKWARD_KW, + /// `before` + BEFORE_KW, + /// `begin` + BEGIN_KW, + /// `between` + BETWEEN_KW, + /// `bigint` + BIGINT_KW, + /// `binary` + BINARY_KW, + /// `bit` + BIT_KW, + /// `boolean` + BOOLEAN_KW, + /// `both` + BOTH_KW, + /// `breadth` + BREADTH_KW, + /// `by` + BY_KW, + /// `cache` + CACHE_KW, + /// `call` + CALL_KW, + /// `called` + CALLED_KW, + /// `cascade` + CASCADE_KW, + /// `cascaded` + CASCADED_KW, + /// `case` + CASE_KW, + /// `cast` + CAST_KW, + /// `catalog` + CATALOG_KW, + /// `chain` + CHAIN_KW, + /// `char` + CHAR_KW, + /// `character` + CHARACTER_KW, + /// `characteristics` + CHARACTERISTICS_KW, + /// `check` + CHECK_KW, + /// `checkpoint` + CHECKPOINT_KW, + /// `class` + CLASS_KW, + /// `close` + CLOSE_KW, + /// `cluster` + CLUSTER_KW, + /// `coalesce` + COALESCE_KW, + /// `collate` + COLLATE_KW, + /// `collation` + COLLATION_KW, + /// `column` + COLUMN_KW, + /// `columns` + COLUMNS_KW, + /// `comment` + COMMENT_KW, + /// `comments` + COMMENTS_KW, + /// `commit` + COMMIT_KW, + /// `committed` + COMMITTED_KW, + /// `compression` + COMPRESSION_KW, + /// `concurrently` + CONCURRENTLY_KW, + /// `conditional` + CONDITIONAL_KW, + /// `configuration` + CONFIGURATION_KW, + /// `conflict` + CONFLICT_KW, + /// `connection` + CONNECTION_KW, + /// `constraint` + CONSTRAINT_KW, + /// `constraints` + CONSTRAINTS_KW, + /// `content` + CONTENT_KW, + /// `continue` + CONTINUE_KW, + /// `conversion` + CONVERSION_KW, + /// `copy` + COPY_KW, + /// `cost` + COST_KW, + /// `create` + CREATE_KW, + /// `cross` + CROSS_KW, + /// `csv` + CSV_KW, + /// `cube` + CUBE_KW, + /// `current` + CURRENT_KW, + /// `current_catalog` + CURRENT_CATALOG_KW, + /// `current_date` + CURRENT_DATE_KW, + /// `current_role` + CURRENT_ROLE_KW, + /// `current_schema` + CURRENT_SCHEMA_KW, + /// `current_time` + CURRENT_TIME_KW, + /// `current_timestamp` + CURRENT_TIMESTAMP_KW, + /// `current_user` + CURRENT_USER_KW, + /// `cursor` + CURSOR_KW, + /// `cycle` + CYCLE_KW, + /// `data` + DATA_KW, + /// `database` + DATABASE_KW, + /// `day` + DAY_KW, + /// `deallocate` + DEALLOCATE_KW, + /// `dec` + DEC_KW, + /// `decimal` + DECIMAL_KW, + /// `declare` + DECLARE_KW, + /// `default` + DEFAULT_KW, + /// `defaults` + DEFAULTS_KW, + /// `deferrable` + DEFERRABLE_KW, + /// `deferred` + DEFERRED_KW, + /// `definer` + DEFINER_KW, + /// `delete` + DELETE_KW, + /// `delimiter` + DELIMITER_KW, + /// `delimiters` + DELIMITERS_KW, + /// `depends` + DEPENDS_KW, + /// `depth` + DEPTH_KW, + /// `desc` + DESC_KW, + /// `detach` + DETACH_KW, + /// `dictionary` + DICTIONARY_KW, + /// `disable` + DISABLE_KW, + /// `discard` + DISCARD_KW, + /// `distinct` + DISTINCT_KW, + /// `do` + DO_KW, + /// `document` + DOCUMENT_KW, + /// `domain` + DOMAIN_KW, + /// `double` + DOUBLE_KW, + /// `drop` + DROP_KW, + /// `each` + EACH_KW, + /// `else` + ELSE_KW, + /// `empty` + EMPTY_KW, + /// `enable` + ENABLE_KW, + /// `encoding` + ENCODING_KW, + /// `encrypted` + ENCRYPTED_KW, + /// `end` + END_KW, + /// `enum` + ENUM_KW, + /// `error` + ERROR_KW, + /// `escape` + ESCAPE_KW, + /// `event` + EVENT_KW, + /// `except` + EXCEPT_KW, + /// `exclude` + EXCLUDE_KW, + /// `excluding` + EXCLUDING_KW, + /// `exclusive` + EXCLUSIVE_KW, + /// `execute` + EXECUTE_KW, + /// `exists` + EXISTS_KW, + /// `explain` + EXPLAIN_KW, + /// `expression` + EXPRESSION_KW, + /// `extension` + EXTENSION_KW, + /// `external` + EXTERNAL_KW, + /// `extract` + EXTRACT_KW, + /// `false` + FALSE_KW, + /// `family` + FAMILY_KW, + /// `fetch` + FETCH_KW, + /// `filter` + FILTER_KW, + /// `finalize` + FINALIZE_KW, + /// `first` + FIRST_KW, + /// `float` + FLOAT_KW, + /// `following` + FOLLOWING_KW, + /// `for` + FOR_KW, + /// `force` + FORCE_KW, + /// `foreign` + FOREIGN_KW, + /// `format` + FORMAT_KW, + /// `forward` + FORWARD_KW, + /// `freeze` + FREEZE_KW, + /// `from` + FROM_KW, + /// `full` + FULL_KW, + /// `function` + FUNCTION_KW, + /// `functions` + FUNCTIONS_KW, + /// `generated` + GENERATED_KW, + /// `global` + GLOBAL_KW, + /// `grant` + GRANT_KW, + /// `granted` + GRANTED_KW, + /// `greatest` + GREATEST_KW, + /// `group` + GROUP_KW, + /// `grouping` + GROUPING_KW, + /// `groups` + GROUPS_KW, + /// `handler` + HANDLER_KW, + /// `having` + HAVING_KW, + /// `header` + HEADER_KW, + /// `hold` + HOLD_KW, + /// `hour` + HOUR_KW, + /// `identity` + IDENTITY_KW, + /// `if` + IF_KW, + /// `ilike` + ILIKE_KW, + /// `immediate` + IMMEDIATE_KW, + /// `immutable` + IMMUTABLE_KW, + /// `implicit` + IMPLICIT_KW, + /// `import` + IMPORT_KW, + /// `in` + IN_KW, + /// `include` + INCLUDE_KW, + /// `including` + INCLUDING_KW, + /// `increment` + INCREMENT_KW, + /// `indent` + INDENT_KW, + /// `index` + INDEX_KW, + /// `indexes` + INDEXES_KW, + /// `inherit` + INHERIT_KW, + /// `inherits` + INHERITS_KW, + /// `initially` + INITIALLY_KW, + /// `inline` + INLINE_KW, + /// `inner` + INNER_KW, + /// `inout` + INOUT_KW, + /// `input` + INPUT_KW, + /// `insensitive` + INSENSITIVE_KW, + /// `insert` + INSERT_KW, + /// `instead` + INSTEAD_KW, + /// `int` + INT_KW, + /// `integer` + INTEGER_KW, + /// `intersect` + INTERSECT_KW, + /// `interval` + INTERVAL_KW, + /// `into` + INTO_KW, + /// `invoker` + INVOKER_KW, + /// `is` + IS_KW, + /// `isnull` + ISNULL_KW, + /// `isolation` + ISOLATION_KW, + /// `join` + JOIN_KW, + /// `json` + JSON_KW, + /// `json_array` + JSON_ARRAY_KW, + /// `json_arrayagg` + JSON_ARRAYAGG_KW, + /// `json_exists` + JSON_EXISTS_KW, + /// `json_object` + JSON_OBJECT_KW, + /// `json_objectagg` + JSON_OBJECTAGG_KW, + /// `json_query` + JSON_QUERY_KW, + /// `json_scalar` + JSON_SCALAR_KW, + /// `json_serialize` + JSON_SERIALIZE_KW, + /// `json_table` + JSON_TABLE_KW, + /// `json_value` + JSON_VALUE_KW, + /// `keep` + KEEP_KW, + /// `key` + KEY_KW, + /// `keys` + KEYS_KW, + /// `label` + LABEL_KW, + /// `language` + LANGUAGE_KW, + /// `large` + LARGE_KW, + /// `last` + LAST_KW, + /// `lateral` + LATERAL_KW, + /// `leading` + LEADING_KW, + /// `leakproof` + LEAKPROOF_KW, + /// `least` + LEAST_KW, + /// `left` + LEFT_KW, + /// `level` + LEVEL_KW, + /// `like` + LIKE_KW, + /// `limit` + LIMIT_KW, + /// `listen` + LISTEN_KW, + /// `load` + LOAD_KW, + /// `local` + LOCAL_KW, + /// `localtime` + LOCALTIME_KW, + /// `localtimestamp` + LOCALTIMESTAMP_KW, + /// `location` + LOCATION_KW, + /// `lock` + LOCK_KW, + /// `locked` + LOCKED_KW, + /// `logged` + LOGGED_KW, + /// `mapping` + MAPPING_KW, + /// `match` + MATCH_KW, + /// `matched` + MATCHED_KW, + /// `materialized` + MATERIALIZED_KW, + /// `maxvalue` + MAXVALUE_KW, + /// `merge` + MERGE_KW, + /// `merge_action` + MERGE_ACTION_KW, + /// `method` + METHOD_KW, + /// `minute` + MINUTE_KW, + /// `minvalue` + MINVALUE_KW, + /// `mode` + MODE_KW, + /// `month` + MONTH_KW, + /// `move` + MOVE_KW, + /// `name` + NAME_KW, + /// `names` + NAMES_KW, + /// `national` + NATIONAL_KW, + /// `natural` + NATURAL_KW, + /// `nchar` + NCHAR_KW, + /// `nested` + NESTED_KW, + /// `new` + NEW_KW, + /// `next` + NEXT_KW, + /// `nfc` + NFC_KW, + /// `nfd` + NFD_KW, + /// `nfkc` + NFKC_KW, + /// `nfkd` + NFKD_KW, + /// `no` + NO_KW, + /// `none` + NONE_KW, + /// `normalize` + NORMALIZE_KW, + /// `normalized` + NORMALIZED_KW, + /// `not` + NOT_KW, + /// `nothing` + NOTHING_KW, + /// `notify` + NOTIFY_KW, + /// `notnull` + NOTNULL_KW, + /// `nowait` + NOWAIT_KW, + /// `null` + NULL_KW, + /// `nullif` + NULLIF_KW, + /// `nulls` + NULLS_KW, + /// `numeric` + NUMERIC_KW, + /// `object` + OBJECT_KW, + /// `of` + OF_KW, + /// `off` + OFF_KW, + /// `offset` + OFFSET_KW, + /// `oids` + OIDS_KW, + /// `old` + OLD_KW, + /// `omit` + OMIT_KW, + /// `on` + ON_KW, + /// `only` + ONLY_KW, + /// `operator` + OPERATOR_KW, + /// `option` + OPTION_KW, + /// `options` + OPTIONS_KW, + /// `or` + OR_KW, + /// `order` + ORDER_KW, + /// `ordinality` + ORDINALITY_KW, + /// `others` + OTHERS_KW, + /// `out` + OUT_KW, + /// `outer` + OUTER_KW, + /// `over` + OVER_KW, + /// `overlaps` + OVERLAPS_KW, + /// `overlay` + OVERLAY_KW, + /// `overriding` + OVERRIDING_KW, + /// `owned` + OWNED_KW, + /// `owner` + OWNER_KW, + /// `parallel` + PARALLEL_KW, + /// `parameter` + PARAMETER_KW, + /// `parser` + PARSER_KW, + /// `partial` + PARTIAL_KW, + /// `partition` + PARTITION_KW, + /// `passing` + PASSING_KW, + /// `password` + PASSWORD_KW, + /// `path` + PATH_KW, + /// `period` + PERIOD_KW, + /// `placing` + PLACING_KW, + /// `plan` + PLAN_KW, + /// `plans` + PLANS_KW, + /// `policy` + POLICY_KW, + /// `position` + POSITION_KW, + /// `preceding` + PRECEDING_KW, + /// `precision` + PRECISION_KW, + /// `prepare` + PREPARE_KW, + /// `prepared` + PREPARED_KW, + /// `preserve` + PRESERVE_KW, + /// `primary` + PRIMARY_KW, + /// `prior` + PRIOR_KW, + /// `privileges` + PRIVILEGES_KW, + /// `procedural` + PROCEDURAL_KW, + /// `procedure` + PROCEDURE_KW, + /// `procedures` + PROCEDURES_KW, + /// `program` + PROGRAM_KW, + /// `publication` + PUBLICATION_KW, + /// `quote` + QUOTE_KW, + /// `quotes` + QUOTES_KW, + /// `range` + RANGE_KW, + /// `read` + READ_KW, + /// `real` + REAL_KW, + /// `reassign` + REASSIGN_KW, + /// `recursive` + RECURSIVE_KW, + /// `ref` + REF_KW, + /// `references` + REFERENCES_KW, + /// `referencing` + REFERENCING_KW, + /// `refresh` + REFRESH_KW, + /// `reindex` + REINDEX_KW, + /// `relative` + RELATIVE_KW, + /// `release` + RELEASE_KW, + /// `rename` + RENAME_KW, + /// `repeatable` + REPEATABLE_KW, + /// `replace` + REPLACE_KW, + /// `replica` + REPLICA_KW, + /// `reset` + RESET_KW, + /// `restart` + RESTART_KW, + /// `restrict` + RESTRICT_KW, + /// `return` + RETURN_KW, + /// `returning` + RETURNING_KW, + /// `returns` + RETURNS_KW, + /// `revoke` + REVOKE_KW, + /// `right` + RIGHT_KW, + /// `role` + ROLE_KW, + /// `rollback` + ROLLBACK_KW, + /// `rollup` + ROLLUP_KW, + /// `routine` + ROUTINE_KW, + /// `routines` + ROUTINES_KW, + /// `row` + ROW_KW, + /// `rows` + ROWS_KW, + /// `rule` + RULE_KW, + /// `savepoint` + SAVEPOINT_KW, + /// `scalar` + SCALAR_KW, + /// `schema` + SCHEMA_KW, + /// `schemas` + SCHEMAS_KW, + /// `scroll` + SCROLL_KW, + /// `search` + SEARCH_KW, + /// `second` + SECOND_KW, + /// `security` + SECURITY_KW, + /// `select` + SELECT_KW, + /// `sequence` + SEQUENCE_KW, + /// `sequences` + SEQUENCES_KW, + /// `serializable` + SERIALIZABLE_KW, + /// `server` + SERVER_KW, + /// `session` + SESSION_KW, + /// `session_user` + SESSION_USER_KW, + /// `set` + SET_KW, + /// `setof` + SETOF_KW, + /// `sets` + SETS_KW, + /// `share` + SHARE_KW, + /// `show` + SHOW_KW, + /// `similar` + SIMILAR_KW, + /// `simple` + SIMPLE_KW, + /// `skip` + SKIP_KW, + /// `smallint` + SMALLINT_KW, + /// `snapshot` + SNAPSHOT_KW, + /// `some` + SOME_KW, + /// `source` + SOURCE_KW, + /// `sql` + SQL_KW, + /// `stable` + STABLE_KW, + /// `standalone` + STANDALONE_KW, + /// `start` + START_KW, + /// `statement` + STATEMENT_KW, + /// `statistics` + STATISTICS_KW, + /// `stdin` + STDIN_KW, + /// `stdout` + STDOUT_KW, + /// `storage` + STORAGE_KW, + /// `stored` + STORED_KW, + /// `strict` + STRICT_KW, + /// `string` + STRING_KW, + /// `strip` + STRIP_KW, + /// `subscription` + SUBSCRIPTION_KW, + /// `substring` + SUBSTRING_KW, + /// `support` + SUPPORT_KW, + /// `symmetric` + SYMMETRIC_KW, + /// `sysid` + SYSID_KW, + /// `system` + SYSTEM_KW, + /// `system_user` + SYSTEM_USER_KW, + /// `table` + TABLE_KW, + /// `tables` + TABLES_KW, + /// `tablesample` + TABLESAMPLE_KW, + /// `tablespace` + TABLESPACE_KW, + /// `target` + TARGET_KW, + /// `temp` + TEMP_KW, + /// `template` + TEMPLATE_KW, + /// `temporary` + TEMPORARY_KW, + /// `text` + TEXT_KW, + /// `then` + THEN_KW, + /// `ties` + TIES_KW, + /// `time` + TIME_KW, + /// `timestamp` + TIMESTAMP_KW, + /// `to` + TO_KW, + /// `trailing` + TRAILING_KW, + /// `transaction` + TRANSACTION_KW, + /// `transform` + TRANSFORM_KW, + /// `treat` + TREAT_KW, + /// `trigger` + TRIGGER_KW, + /// `trim` + TRIM_KW, + /// `true` + TRUE_KW, + /// `truncate` + TRUNCATE_KW, + /// `trusted` + TRUSTED_KW, + /// `type` + TYPE_KW, + /// `types` + TYPES_KW, + /// `uescape` + UESCAPE_KW, + /// `unbounded` + UNBOUNDED_KW, + /// `uncommitted` + UNCOMMITTED_KW, + /// `unconditional` + UNCONDITIONAL_KW, + /// `unencrypted` + UNENCRYPTED_KW, + /// `union` + UNION_KW, + /// `unique` + UNIQUE_KW, + /// `unknown` + UNKNOWN_KW, + /// `unlisten` + UNLISTEN_KW, + /// `unlogged` + UNLOGGED_KW, + /// `until` + UNTIL_KW, + /// `update` + UPDATE_KW, + /// `user` + USER_KW, + /// `using` + USING_KW, + /// `vacuum` + VACUUM_KW, + /// `valid` + VALID_KW, + /// `validate` + VALIDATE_KW, + /// `validator` + VALIDATOR_KW, + /// `value` + VALUE_KW, + /// `values` + VALUES_KW, + /// `varchar` + VARCHAR_KW, + /// `variadic` + VARIADIC_KW, + /// `varying` + VARYING_KW, + /// `verbose` + VERBOSE_KW, + /// `version` + VERSION_KW, + /// `view` + VIEW_KW, + /// `views` + VIEWS_KW, + /// `volatile` + VOLATILE_KW, + /// `when` + WHEN_KW, + /// `where` + WHERE_KW, + /// `whitespace` + WHITESPACE_KW, + /// `window` + WINDOW_KW, + /// `with` + WITH_KW, + /// `within` + WITHIN_KW, + /// `without` + WITHOUT_KW, + /// `work` + WORK_KW, + /// `wrapper` + WRAPPER_KW, + /// `write` + WRITE_KW, + /// `xml` + XML_KW, + /// `xmlattributes` + XMLATTRIBUTES_KW, + /// `xmlconcat` + XMLCONCAT_KW, + /// `xmlelement` + XMLELEMENT_KW, + /// `xmlexists` + XMLEXISTS_KW, + /// `xmlforest` + XMLFOREST_KW, + /// `xmlnamespaces` + XMLNAMESPACES_KW, + /// `xmlparse` + XMLPARSE_KW, + /// `xmlpi` + XMLPI_KW, + /// `xmlroot` + XMLROOT_KW, + /// `xmlserialize` + XMLSERIALIZE_KW, + /// `xmltable` + XMLTABLE_KW, + /// `year` + YEAR_KW, + /// `yes` + YES_KW, + /// `zone` + ZONE_KW, + + // literals + /// `1.0` + FLOAT_NUMBER, + /// `1` + INT_NUMBER, + /// `'foo'` + STRING, + /// `X'1FF'`, `U&'d\0061t\+000061'` + /// + /// see: + /// see: + BYTE_STRING, + /// `B'1001'` + /// + /// see: + BIT_STRING, + /// `$$Dianne's horse$$` + /// + /// see: + DOLLAR_QUOTED_STRING, + /// `E'foo'` + /// + /// see: + ESC_STRING, + /// `-- foo` + /// or + /// `/* foo */` + /// + /// see: + COMMENT, + IDENT, + PARAM, + ERROR, + WHITESPACE, + + // nodes + /// `100, bar, buzz` + ARG_LIST, + ARG, + PARAM_LIST, + COLLATE, + TARGET_LIST, + TARGET, + ARRAY_EXPR, + IS_NULL, + IS_NOT, + IS_NOT_DISTINCT_FROM, + /// + /// Left assoc in postgres/gram.y + /// Same precedence as operators + OPERATOR_CALL, + /// `at time zone` + AT_TIME_ZONE, + SIMILAR_TO, + IS_DISTINCT_FROM, + NOT_LIKE, + NOT_IN, + BIN_EXPR, + POSTFIX_EXPR, + /// `foo()` + CALL_EXPR, + BETWEEN_EXPR, + /// `foo::bar`, `cast(foo as bar)`, `treat(foo as bar)`, or `numeric '123'` + CAST_EXPR, + CASE_EXPR, + ALIAS, + /// `foo.bar` + FIELD_EXPR, + /// `foo[1]` + INDEX_EXPR, + LITERAL, + NAME, + /// `a := b`, `a => b` + NAMED_ARG, + /// `a: b`, `a value b` + JSON_KEY_VALUE, + PAREN_EXPR, + PATH, + PATH_SEGMENT, + PATH_TYPE, + CHAR_TYPE, + BIT_TYPE, + PERCENT_TYPE, + DOUBLE_TYPE, + TIME_TYPE, + INTERVAL_TYPE, + ARRAY_TYPE, + PERCENT_TYPE_CLAUSE, + WITH_TIMEZONE, + WITHOUT_TIMEZONE, + PREFIX_EXPR, + COLUMN, + SOURCE_FILE, + RET_TYPE, + STMT, + ALTER_AGGREGATE_STMT, + ALTER_COLLATION_STMT, + ALTER_CONVERSION_STMT, + ALTER_DATABASE_STMT, + ALTER_DEFAULT_PRIVILEGES_STMT, + ALTER_DOMAIN_STMT, + ALTER_EVENT_TRIGGER_STMT, + ALTER_EXTENSION_STMT, + ALTER_FOREIGN_DATA_WRAPPER_STMT, + ALTER_FOREIGN_TABLE_STMT, + ALTER_FUNCTION_STMT, + ALTER_GROUP_STMT, + ALTER_INDEX_STMT, + ALTER_LANGUAGE_STMT, + ALTER_LARGE_OBJECT_STMT, + ALTER_MATERIALIZED_VIEW_STMT, + ALTER_OPERATOR_STMT, + ALTER_OPERATOR_CLASS_STMT, + ALTER_OPERATOR_FAMILY_STMT, + ALTER_POLICY_STMT, + ALTER_PROCEDURE_STMT, + ALTER_PUBLICATION_STMT, + ALTER_ROLE_STMT, + ALTER_ROUTINE_STMT, + ALTER_RULE_STMT, + ALTER_SCHEMA_STMT, + ALTER_SEQUENCE_STMT, + ALTER_SERVER_STMT, + ALTER_STATISTICS_STMT, + ALTER_SUBSCRIPTION_STMT, + ALTER_SYSTEM_STMT, + ALTER_TABLESPACE_STMT, + ALTER_TEXT_SEARCH_CONFIGURATION_STMT, + ALTER_TEXT_SEARCH_DICTIONARY_STMT, + ALTER_TEXT_SEARCH_PARSER_STMT, + ALTER_TEXT_SEARCH_TEMPLATE_STMT, + ALTER_TRIGGER_STMT, + ALTER_TYPE_STMT, + ALTER_USER_STMT, + ALTER_USER_MAPPING_STMT, + ALTER_VIEW_STMT, + ANALYZE_STMT, + CLUSTER_STMT, + COMMENT_STMT, + COMMIT_STMT, + CREATE_EXTENSION_STMT, + CREATE_ACCESS_METHOD_STMT, + CREATE_AGGREGATE_STMT, + CREATE_CAST_STMT, + CREATE_COLLATION_STMT, + CREATE_CONVERSION_STMT, + CREATE_DATABASE_STMT, + CREATE_DOMAIN_STMT, + CREATE_EVENT_TRIGGER_STMT, + CREATE_FOREIGN_DATA_WRAPPER_STMT, + CREATE_FOREIGN_TABLE_STMT, + CREATE_GROUP_STMT, + CREATE_LANGUAGE_STMT, + CREATE_MATERIALIZED_VIEW_STMT, + CREATE_OPERATOR_STMT, + CREATE_OPERATOR_CLASS_STMT, + CREATE_OPERATOR_FAMILY_STMT, + CREATE_POLICY_STMT, + CREATE_PROCEDURE_STMT, + CREATE_PUBLICATION_STMT, + CREATE_ROLE_STMT, + CREATE_RULE_STMT, + CREATE_SEQUENCE_STMT, + CREATE_SERVER_STMT, + CREATE_STATISTICS_STMT, + CREATE_SUBSCRIPTION_STMT, + CREATE_TABLE_AS_STMT, + CREATE_TABLESPACE_STMT, + CREATE_TEXT_SEARCH_CONFIGURATION_STMT, + CREATE_TEXT_SEARCH_DICTIONARY_STMT, + CREATE_TEXT_SEARCH_PARSER_STMT, + CREATE_TEXT_SEARCH_TEMPLATE_STMT, + CREATE_TRANSFORM_STMT, + CREATE_INDEX_STMT, + CREATE_TYPE_STMT, + CREATE_TRIGGER_STMT, + CREATE_FUNCTION_STMT, + PARAM_IN, + PARAM_OUT, + PARAM_INOUT, + PARAM_VARIADIC, + BEGIN_FUNC_OPTION, + RETURN_FUNC_OPTION, + AS_FUNC_OPTION, + SET_FUNC_OPTION, + SUPPORT_FUNC_OPTION, + ROWS_FUNC_OPTION, + COST_FUNC_OPTION, + PARALLEL_FUNC_OPTION, + SECURITY_FUNC_OPTION, + STRICT_FUNC_OPTION, + LEAKPROOF_FUNC_OPTION, + RESET_FUNC_OPTION, + VOLATILITY_FUNC_OPTION, + WINDOW_FUNC_OPTION, + TRANSFORM_FUNC_OPTION, + LANGUAGE_FUNC_OPTION, + PARAM_DEFAULT, + FUNC_OPTION_LIST, + IF_EXISTS, + IF_NOT_EXISTS, + OR_REPLACE, + DROP_INDEX_STMT, + DROP_TRIGGER_STMT, + BEGIN_STMT, + SHOW_STMT, + SET_STMT, + PREPARE_TRANSACTION_STMT, + DROP_DATABASE_STMT, + DROP_TYPE_STMT, + CALL_STMT, + TRUNCATE_STMT, + MOVE_STMT, + FETCH_STMT, + DECLARE_STMT, + DO_STMT, + DISCARD_STMT, + RESET_STMT, + LISTEN_STMT, + LOAD_STMT, + DEALLOCATE_STMT, + CHECKPOINT_STMT, + PREPARE_STMT, + UNLISTEN_STMT, + NOTIFY_STMT, + CLOSE_STMT, + VACUUM_STMT, + COPY_STMT, + DELETE_STMT, + MERGE_STMT, + LOCK_STMT, + EXPLAIN_STMT, + DROP_USER_STMT, + DROP_TRANSFORM_STMT, + DROP_TEXT_SEARCH_TEMPLATE_STMT, + DROP_TEXT_SEARCH_PARSER_STMT, + DROP_TEXT_SEARCH_DICT_STMT, + DROP_TEXT_SEARCH_CONFIG_STMT, + DROP_TABLESPACE_STMT, + DROP_SUBSCRIPTION_STMT, + DROP_STATISTICS_STMT, + DROP_SERVER_STMT, + DROP_SEQUENCE_STMT, + DROP_RULE_STMT, + DROP_ROUTINE_STMT, + DROP_ROLE_STMT, + DROP_PUBLICATION_STMT, + DROP_PROCEDURE_STMT, + DROP_POLICY_STMT, + DROP_OWNED_STMT, + DROP_OPERATOR_FAMILY_STMT, + DROP_OPERATOR_CLASS_STMT, + DROP_MATERIALIZED_VIEW_STMT, + DROP_OPERATOR_STMT, + DROP_LANGUAGE_STMT, + DROP_GROUP_STMT, + DROP_FUNCTION_STMT, + DROP_FOREIGN_TABLE_STMT, + DROP_FOREIGN_DATA_WRAPPER_STMT, + DROP_EXTENSION_STMT, + DROP_EVENT_TRIGGER_STMT, + DROP_DOMAIN_STMT, + DROP_CONVERSION_STMT, + DROP_COLLATION_STMT, + DROP_CAST_STMT, + DROP_AGGREGATE_STMT, + DROP_ACCESS_METHOD_STMT, + DROP_USER_MAPPING_STMT, + IMPORT_FOREIGN_SCHEMA, + EXECUTE_STMT, + CREATE_VIEW_STMT, + SAVEPOINT_STMT, + RELEASE_SAVEPOINT_STMT, + DROP_SCHEMA_STMT, + DROP_VIEW_STMT, + REINDEX_STMT, + UPDATE_STMT, + ROLLBACK_STMT, + INSERT_STMT, + CREATE_SCHEMA_STMT, + SELECT, + SELECT_INTO_STMT, + SECURITY_LABEL_STMT, + REVOKE_STMT, + GRANT_STMT, + REFRESH_STMT, + REASSIGN_STMT, + SET_SESSION_AUTH_STMT, + CREATE_USER_MAPPING_STMT, + CREATE_USER_STMT, + SET_ROLE_STMT, + SET_CONSTRAINTS_STMT, + SET_TRANSACTION_STMT, + INTO_CLAUSE, + COMPOUND_SELECT, + DROP_TABLE, + JOIN, + CREATE_TABLE, + ALTER_TABLE, + WINDOW_DEF, + JSON_VALUE_EXPR, + JSON_FORMAT_CLAUSE, + JSON_RETURNING_CLAUSE, + JSON_QUOTES_CLAUSE, + JSON_WRAPPER_BEHAVIOR_CLAUSE, + JSON_BEHAVIOR_CLAUSE, + JSON_PASSING_CLAUSE, + JSON_ON_ERROR_CLAUSE, + JSON_NULL_CLAUSE, + JSON_KEYS_UNIQUE_CLAUSE, + SELECT_CLAUSE, + LIKE_CLAUSE, + REFERENCES_CONSTRAINT, + PRIMARY_KEY_CONSTRAINT, + FOREIGN_KEY_CONSTRAINT, + EXCLUDE_CONSTRAINT, + UNIQUE_CONSTRAINT, + GENERATED_CONSTRAINT, + DEFAULT_CONSTRAINT, + CHECK_CONSTRAINT, + NULL_CONSTRAINT, + NOT_NULL_CONSTRAINT, + INDEX_PARAMS, + CONSTRAINT_INDEX_TABLESPACE, + CONSTRAINT_STORAGE_PARAMS, + CONSTRAINT_INCLUDE_CLAUSE, + CONSTRAINT_WHERE_CLAUSE, + CONSTRAINT_INDEX_METHOD, + CONSTRAINT_EXCLUSIONS, + DEFERRABLE_CONSTRAINT_OPTION, + NOT_DEFERRABLE_CONSTRAINT_OPTION, + INITALLY_DEFERRED_CONSTRAINT_OPTION, + INITIALLY_IMMEDIATE_CONSTRAINT_OPTION, + CONSTRAINT_OPTION_LIST, + SEQUENCE_OPTION_LIST, + USING_INDEX, + // alter table actions + VALIDATE_CONSTRAINT, + REPLICA_IDENTITY, + OF_TYPE, + NOT_OF, + FORCE_RLS, + NO_FORCE_RLS, + INHERIT, + NO_INHERIT, + ENABLE_TRIGGER, + ENABLE_REPLICA_TRIGGER, + ENABLE_REPLICA_RULE, + ENABLE_ALWAYS_TRIGGER, + ENABLE_ALWAYS_RULE, + ENABLE_RULE, + ENABLE_RLS, + DISABLE_TRIGGER, + DISABLE_RLS, + DISABLE_RULE, + DISABLE_CLUSTER, + OWNER_TO, + DETACH_PARTITION, + DROP_CONSTRAINT, + DROP_COLUMN, + ADD_CONSTRAINT, + ADD_COLUMN, + ATTACH_PARTITION, + SET_SCHEMA, + SET_TABLESPACE, + SET_WITHOUT_CLUSTER, + SET_WITHOUT_OIDS, + SET_ACCESS_METHOD, + SET_LOGGED, + SET_UNLOGGED, + SET_STORAGE_PARAMS, + RESET_STORAGE_PARAMS, + RENAME_TABLE, + RENAME_CONSTRAINT, + RENAME_COLUMN, + RENAME_TO, + NOT_VALID, + ALTER_CONSTRAINT, + ALTER_COLUMN, + // alter table actions end + // alter column options + DROP_DEFAULT, + DROP_EXPRESSION, + DROP_IDENTITY, + DROP_NOT_NULL, + RESTART, + ADD_GENERATED, + RESET_OPTIONS, + SET_TYPE, + SET_GENERATED_OPTIONS, + SET_GENERATED, + SET_SEQUENCE_OPTION, + SET_DEFAULT, + SET_EXPRESSION, + SET_STATISTICS, + SET_OPTIONS, + SET_OPTIONS_LIST, + SET_STORAGE, + SET_COMPRESSION, + SET_NOT_NULL, + // alter column options end + TABLE_ARGS, + COLUMN_LIST, + WHEN_CLAUSE, + USING_CLAUSE, + WITHIN_CLAUSE, + FILTER_CLAUSE, + OVER_CLAUSE, + DISTINCT_CLAUSE, + WITH_TABLE, + WITH_CLAUSE, + FROM_CLAUSE, + WHERE_CLAUSE, + GROUP_BY_CLAUSE, + HAVING_CLAUSE, + WINDOW_CLAUSE, + LIMIT_CLAUSE, + OFFSET_CLAUSE, + ORDER_BY_CLAUSE, + LOCKING_CLAUSE, + TUPLE_EXPR, + NAME_REF, + #[doc(hidden)] + __LAST, +} + +impl From for SyntaxKind { + #[inline] + fn from(d: u16) -> SyntaxKind { + assert!(d <= (SyntaxKind::__LAST as u16)); + unsafe { std::mem::transmute::(d) } + } +} + +impl From for u16 { + #[inline] + fn from(k: SyntaxKind) -> u16 { + k as u16 + } +} + +impl SyntaxKind { + #[inline] + pub fn is_trivia(self) -> bool { + matches!(self, SyntaxKind::WHITESPACE | SyntaxKind::COMMENT) + } + + // generated via: cargo xtask generate_keywords + pub(crate) fn from_keyword(ident: &str) -> Option { + let kw = if ident.eq_ignore_ascii_case("abort") { + SyntaxKind::ABORT_KW + } else if ident.eq_ignore_ascii_case("absent") { + SyntaxKind::ABSENT_KW + } else if ident.eq_ignore_ascii_case("absolute") { + SyntaxKind::ABSOLUTE_KW + } else if ident.eq_ignore_ascii_case("access") { + SyntaxKind::ACCESS_KW + } else if ident.eq_ignore_ascii_case("action") { + SyntaxKind::ACTION_KW + } else if ident.eq_ignore_ascii_case("add") { + SyntaxKind::ADD_KW + } else if ident.eq_ignore_ascii_case("admin") { + SyntaxKind::ADMIN_KW + } else if ident.eq_ignore_ascii_case("after") { + SyntaxKind::AFTER_KW + } else if ident.eq_ignore_ascii_case("aggregate") { + SyntaxKind::AGGREGATE_KW + } else if ident.eq_ignore_ascii_case("all") { + SyntaxKind::ALL_KW + } else if ident.eq_ignore_ascii_case("also") { + SyntaxKind::ALSO_KW + } else if ident.eq_ignore_ascii_case("alter") { + SyntaxKind::ALTER_KW + } else if ident.eq_ignore_ascii_case("always") { + SyntaxKind::ALWAYS_KW + } else if ident.eq_ignore_ascii_case("analyse") { + SyntaxKind::ANALYSE_KW + } else if ident.eq_ignore_ascii_case("analyze") { + SyntaxKind::ANALYZE_KW + } else if ident.eq_ignore_ascii_case("and") { + SyntaxKind::AND_KW + } else if ident.eq_ignore_ascii_case("any") { + SyntaxKind::ANY_KW + } else if ident.eq_ignore_ascii_case("array") { + SyntaxKind::ARRAY_KW + } else if ident.eq_ignore_ascii_case("as") { + SyntaxKind::AS_KW + } else if ident.eq_ignore_ascii_case("asc") { + SyntaxKind::ASC_KW + } else if ident.eq_ignore_ascii_case("asensitive") { + SyntaxKind::ASENSITIVE_KW + } else if ident.eq_ignore_ascii_case("assertion") { + SyntaxKind::ASSERTION_KW + } else if ident.eq_ignore_ascii_case("assignment") { + SyntaxKind::ASSIGNMENT_KW + } else if ident.eq_ignore_ascii_case("asymmetric") { + SyntaxKind::ASYMMETRIC_KW + } else if ident.eq_ignore_ascii_case("at") { + SyntaxKind::AT_KW + } else if ident.eq_ignore_ascii_case("atomic") { + SyntaxKind::ATOMIC_KW + } else if ident.eq_ignore_ascii_case("attach") { + SyntaxKind::ATTACH_KW + } else if ident.eq_ignore_ascii_case("attribute") { + SyntaxKind::ATTRIBUTE_KW + } else if ident.eq_ignore_ascii_case("authorization") { + SyntaxKind::AUTHORIZATION_KW + } else if ident.eq_ignore_ascii_case("backward") { + SyntaxKind::BACKWARD_KW + } else if ident.eq_ignore_ascii_case("before") { + SyntaxKind::BEFORE_KW + } else if ident.eq_ignore_ascii_case("begin") { + SyntaxKind::BEGIN_KW + } else if ident.eq_ignore_ascii_case("between") { + SyntaxKind::BETWEEN_KW + } else if ident.eq_ignore_ascii_case("bigint") { + SyntaxKind::BIGINT_KW + } else if ident.eq_ignore_ascii_case("binary") { + SyntaxKind::BINARY_KW + } else if ident.eq_ignore_ascii_case("bit") { + SyntaxKind::BIT_KW + } else if ident.eq_ignore_ascii_case("boolean") { + SyntaxKind::BOOLEAN_KW + } else if ident.eq_ignore_ascii_case("both") { + SyntaxKind::BOTH_KW + } else if ident.eq_ignore_ascii_case("breadth") { + SyntaxKind::BREADTH_KW + } else if ident.eq_ignore_ascii_case("by") { + SyntaxKind::BY_KW + } else if ident.eq_ignore_ascii_case("cache") { + SyntaxKind::CACHE_KW + } else if ident.eq_ignore_ascii_case("call") { + SyntaxKind::CALL_KW + } else if ident.eq_ignore_ascii_case("called") { + SyntaxKind::CALLED_KW + } else if ident.eq_ignore_ascii_case("cascade") { + SyntaxKind::CASCADE_KW + } else if ident.eq_ignore_ascii_case("cascaded") { + SyntaxKind::CASCADED_KW + } else if ident.eq_ignore_ascii_case("case") { + SyntaxKind::CASE_KW + } else if ident.eq_ignore_ascii_case("cast") { + SyntaxKind::CAST_KW + } else if ident.eq_ignore_ascii_case("catalog") { + SyntaxKind::CATALOG_KW + } else if ident.eq_ignore_ascii_case("chain") { + SyntaxKind::CHAIN_KW + } else if ident.eq_ignore_ascii_case("char") { + SyntaxKind::CHAR_KW + } else if ident.eq_ignore_ascii_case("character") { + SyntaxKind::CHARACTER_KW + } else if ident.eq_ignore_ascii_case("characteristics") { + SyntaxKind::CHARACTERISTICS_KW + } else if ident.eq_ignore_ascii_case("check") { + SyntaxKind::CHECK_KW + } else if ident.eq_ignore_ascii_case("checkpoint") { + SyntaxKind::CHECKPOINT_KW + } else if ident.eq_ignore_ascii_case("class") { + SyntaxKind::CLASS_KW + } else if ident.eq_ignore_ascii_case("close") { + SyntaxKind::CLOSE_KW + } else if ident.eq_ignore_ascii_case("cluster") { + SyntaxKind::CLUSTER_KW + } else if ident.eq_ignore_ascii_case("coalesce") { + SyntaxKind::COALESCE_KW + } else if ident.eq_ignore_ascii_case("collate") { + SyntaxKind::COLLATE_KW + } else if ident.eq_ignore_ascii_case("collation") { + SyntaxKind::COLLATION_KW + } else if ident.eq_ignore_ascii_case("column") { + SyntaxKind::COLUMN_KW + } else if ident.eq_ignore_ascii_case("columns") { + SyntaxKind::COLUMNS_KW + } else if ident.eq_ignore_ascii_case("comment") { + SyntaxKind::COMMENT_KW + } else if ident.eq_ignore_ascii_case("comments") { + SyntaxKind::COMMENTS_KW + } else if ident.eq_ignore_ascii_case("commit") { + SyntaxKind::COMMIT_KW + } else if ident.eq_ignore_ascii_case("committed") { + SyntaxKind::COMMITTED_KW + } else if ident.eq_ignore_ascii_case("compression") { + SyntaxKind::COMPRESSION_KW + } else if ident.eq_ignore_ascii_case("concurrently") { + SyntaxKind::CONCURRENTLY_KW + } else if ident.eq_ignore_ascii_case("conditional") { + SyntaxKind::CONDITIONAL_KW + } else if ident.eq_ignore_ascii_case("configuration") { + SyntaxKind::CONFIGURATION_KW + } else if ident.eq_ignore_ascii_case("conflict") { + SyntaxKind::CONFLICT_KW + } else if ident.eq_ignore_ascii_case("connection") { + SyntaxKind::CONNECTION_KW + } else if ident.eq_ignore_ascii_case("constraint") { + SyntaxKind::CONSTRAINT_KW + } else if ident.eq_ignore_ascii_case("constraints") { + SyntaxKind::CONSTRAINTS_KW + } else if ident.eq_ignore_ascii_case("content") { + SyntaxKind::CONTENT_KW + } else if ident.eq_ignore_ascii_case("continue") { + SyntaxKind::CONTINUE_KW + } else if ident.eq_ignore_ascii_case("conversion") { + SyntaxKind::CONVERSION_KW + } else if ident.eq_ignore_ascii_case("copy") { + SyntaxKind::COPY_KW + } else if ident.eq_ignore_ascii_case("cost") { + SyntaxKind::COST_KW + } else if ident.eq_ignore_ascii_case("create") { + SyntaxKind::CREATE_KW + } else if ident.eq_ignore_ascii_case("cross") { + SyntaxKind::CROSS_KW + } else if ident.eq_ignore_ascii_case("csv") { + SyntaxKind::CSV_KW + } else if ident.eq_ignore_ascii_case("cube") { + SyntaxKind::CUBE_KW + } else if ident.eq_ignore_ascii_case("current") { + SyntaxKind::CURRENT_KW + } else if ident.eq_ignore_ascii_case("current_catalog") { + SyntaxKind::CURRENT_CATALOG_KW + } else if ident.eq_ignore_ascii_case("current_date") { + SyntaxKind::CURRENT_DATE_KW + } else if ident.eq_ignore_ascii_case("current_role") { + SyntaxKind::CURRENT_ROLE_KW + } else if ident.eq_ignore_ascii_case("current_schema") { + SyntaxKind::CURRENT_SCHEMA_KW + } else if ident.eq_ignore_ascii_case("current_time") { + SyntaxKind::CURRENT_TIME_KW + } else if ident.eq_ignore_ascii_case("current_timestamp") { + SyntaxKind::CURRENT_TIMESTAMP_KW + } else if ident.eq_ignore_ascii_case("current_user") { + SyntaxKind::CURRENT_USER_KW + } else if ident.eq_ignore_ascii_case("cursor") { + SyntaxKind::CURSOR_KW + } else if ident.eq_ignore_ascii_case("cycle") { + SyntaxKind::CYCLE_KW + } else if ident.eq_ignore_ascii_case("data") { + SyntaxKind::DATA_KW + } else if ident.eq_ignore_ascii_case("database") { + SyntaxKind::DATABASE_KW + } else if ident.eq_ignore_ascii_case("day") { + SyntaxKind::DAY_KW + } else if ident.eq_ignore_ascii_case("deallocate") { + SyntaxKind::DEALLOCATE_KW + } else if ident.eq_ignore_ascii_case("dec") { + SyntaxKind::DEC_KW + } else if ident.eq_ignore_ascii_case("decimal") { + SyntaxKind::DECIMAL_KW + } else if ident.eq_ignore_ascii_case("declare") { + SyntaxKind::DECLARE_KW + } else if ident.eq_ignore_ascii_case("default") { + SyntaxKind::DEFAULT_KW + } else if ident.eq_ignore_ascii_case("defaults") { + SyntaxKind::DEFAULTS_KW + } else if ident.eq_ignore_ascii_case("deferrable") { + SyntaxKind::DEFERRABLE_KW + } else if ident.eq_ignore_ascii_case("deferred") { + SyntaxKind::DEFERRED_KW + } else if ident.eq_ignore_ascii_case("definer") { + SyntaxKind::DEFINER_KW + } else if ident.eq_ignore_ascii_case("delete") { + SyntaxKind::DELETE_KW + } else if ident.eq_ignore_ascii_case("delimiter") { + SyntaxKind::DELIMITER_KW + } else if ident.eq_ignore_ascii_case("delimiters") { + SyntaxKind::DELIMITERS_KW + } else if ident.eq_ignore_ascii_case("depends") { + SyntaxKind::DEPENDS_KW + } else if ident.eq_ignore_ascii_case("depth") { + SyntaxKind::DEPTH_KW + } else if ident.eq_ignore_ascii_case("desc") { + SyntaxKind::DESC_KW + } else if ident.eq_ignore_ascii_case("detach") { + SyntaxKind::DETACH_KW + } else if ident.eq_ignore_ascii_case("dictionary") { + SyntaxKind::DICTIONARY_KW + } else if ident.eq_ignore_ascii_case("disable") { + SyntaxKind::DISABLE_KW + } else if ident.eq_ignore_ascii_case("discard") { + SyntaxKind::DISCARD_KW + } else if ident.eq_ignore_ascii_case("distinct") { + SyntaxKind::DISTINCT_KW + } else if ident.eq_ignore_ascii_case("do") { + SyntaxKind::DO_KW + } else if ident.eq_ignore_ascii_case("document") { + SyntaxKind::DOCUMENT_KW + } else if ident.eq_ignore_ascii_case("domain") { + SyntaxKind::DOMAIN_KW + } else if ident.eq_ignore_ascii_case("double") { + SyntaxKind::DOUBLE_KW + } else if ident.eq_ignore_ascii_case("drop") { + SyntaxKind::DROP_KW + } else if ident.eq_ignore_ascii_case("each") { + SyntaxKind::EACH_KW + } else if ident.eq_ignore_ascii_case("else") { + SyntaxKind::ELSE_KW + } else if ident.eq_ignore_ascii_case("empty") { + SyntaxKind::EMPTY_KW + } else if ident.eq_ignore_ascii_case("enable") { + SyntaxKind::ENABLE_KW + } else if ident.eq_ignore_ascii_case("encoding") { + SyntaxKind::ENCODING_KW + } else if ident.eq_ignore_ascii_case("encrypted") { + SyntaxKind::ENCRYPTED_KW + } else if ident.eq_ignore_ascii_case("end") { + SyntaxKind::END_KW + } else if ident.eq_ignore_ascii_case("enum") { + SyntaxKind::ENUM_KW + } else if ident.eq_ignore_ascii_case("error") { + SyntaxKind::ERROR_KW + } else if ident.eq_ignore_ascii_case("escape") { + SyntaxKind::ESCAPE_KW + } else if ident.eq_ignore_ascii_case("event") { + SyntaxKind::EVENT_KW + } else if ident.eq_ignore_ascii_case("except") { + SyntaxKind::EXCEPT_KW + } else if ident.eq_ignore_ascii_case("exclude") { + SyntaxKind::EXCLUDE_KW + } else if ident.eq_ignore_ascii_case("excluding") { + SyntaxKind::EXCLUDING_KW + } else if ident.eq_ignore_ascii_case("exclusive") { + SyntaxKind::EXCLUSIVE_KW + } else if ident.eq_ignore_ascii_case("execute") { + SyntaxKind::EXECUTE_KW + } else if ident.eq_ignore_ascii_case("exists") { + SyntaxKind::EXISTS_KW + } else if ident.eq_ignore_ascii_case("explain") { + SyntaxKind::EXPLAIN_KW + } else if ident.eq_ignore_ascii_case("expression") { + SyntaxKind::EXPRESSION_KW + } else if ident.eq_ignore_ascii_case("extension") { + SyntaxKind::EXTENSION_KW + } else if ident.eq_ignore_ascii_case("external") { + SyntaxKind::EXTERNAL_KW + } else if ident.eq_ignore_ascii_case("extract") { + SyntaxKind::EXTRACT_KW + } else if ident.eq_ignore_ascii_case("false") { + SyntaxKind::FALSE_KW + } else if ident.eq_ignore_ascii_case("family") { + SyntaxKind::FAMILY_KW + } else if ident.eq_ignore_ascii_case("fetch") { + SyntaxKind::FETCH_KW + } else if ident.eq_ignore_ascii_case("filter") { + SyntaxKind::FILTER_KW + } else if ident.eq_ignore_ascii_case("finalize") { + SyntaxKind::FINALIZE_KW + } else if ident.eq_ignore_ascii_case("first") { + SyntaxKind::FIRST_KW + } else if ident.eq_ignore_ascii_case("float") { + SyntaxKind::FLOAT_KW + } else if ident.eq_ignore_ascii_case("following") { + SyntaxKind::FOLLOWING_KW + } else if ident.eq_ignore_ascii_case("for") { + SyntaxKind::FOR_KW + } else if ident.eq_ignore_ascii_case("force") { + SyntaxKind::FORCE_KW + } else if ident.eq_ignore_ascii_case("foreign") { + SyntaxKind::FOREIGN_KW + } else if ident.eq_ignore_ascii_case("format") { + SyntaxKind::FORMAT_KW + } else if ident.eq_ignore_ascii_case("forward") { + SyntaxKind::FORWARD_KW + } else if ident.eq_ignore_ascii_case("freeze") { + SyntaxKind::FREEZE_KW + } else if ident.eq_ignore_ascii_case("from") { + SyntaxKind::FROM_KW + } else if ident.eq_ignore_ascii_case("full") { + SyntaxKind::FULL_KW + } else if ident.eq_ignore_ascii_case("function") { + SyntaxKind::FUNCTION_KW + } else if ident.eq_ignore_ascii_case("functions") { + SyntaxKind::FUNCTIONS_KW + } else if ident.eq_ignore_ascii_case("generated") { + SyntaxKind::GENERATED_KW + } else if ident.eq_ignore_ascii_case("global") { + SyntaxKind::GLOBAL_KW + } else if ident.eq_ignore_ascii_case("grant") { + SyntaxKind::GRANT_KW + } else if ident.eq_ignore_ascii_case("granted") { + SyntaxKind::GRANTED_KW + } else if ident.eq_ignore_ascii_case("greatest") { + SyntaxKind::GREATEST_KW + } else if ident.eq_ignore_ascii_case("group") { + SyntaxKind::GROUP_KW + } else if ident.eq_ignore_ascii_case("grouping") { + SyntaxKind::GROUPING_KW + } else if ident.eq_ignore_ascii_case("groups") { + SyntaxKind::GROUPS_KW + } else if ident.eq_ignore_ascii_case("handler") { + SyntaxKind::HANDLER_KW + } else if ident.eq_ignore_ascii_case("having") { + SyntaxKind::HAVING_KW + } else if ident.eq_ignore_ascii_case("header") { + SyntaxKind::HEADER_KW + } else if ident.eq_ignore_ascii_case("hold") { + SyntaxKind::HOLD_KW + } else if ident.eq_ignore_ascii_case("hour") { + SyntaxKind::HOUR_KW + } else if ident.eq_ignore_ascii_case("identity") { + SyntaxKind::IDENTITY_KW + } else if ident.eq_ignore_ascii_case("if") { + SyntaxKind::IF_KW + } else if ident.eq_ignore_ascii_case("ilike") { + SyntaxKind::ILIKE_KW + } else if ident.eq_ignore_ascii_case("immediate") { + SyntaxKind::IMMEDIATE_KW + } else if ident.eq_ignore_ascii_case("immutable") { + SyntaxKind::IMMUTABLE_KW + } else if ident.eq_ignore_ascii_case("implicit") { + SyntaxKind::IMPLICIT_KW + } else if ident.eq_ignore_ascii_case("import") { + SyntaxKind::IMPORT_KW + } else if ident.eq_ignore_ascii_case("in") { + SyntaxKind::IN_KW + } else if ident.eq_ignore_ascii_case("include") { + SyntaxKind::INCLUDE_KW + } else if ident.eq_ignore_ascii_case("including") { + SyntaxKind::INCLUDING_KW + } else if ident.eq_ignore_ascii_case("increment") { + SyntaxKind::INCREMENT_KW + } else if ident.eq_ignore_ascii_case("indent") { + SyntaxKind::INDENT_KW + } else if ident.eq_ignore_ascii_case("index") { + SyntaxKind::INDEX_KW + } else if ident.eq_ignore_ascii_case("indexes") { + SyntaxKind::INDEXES_KW + } else if ident.eq_ignore_ascii_case("inherit") { + SyntaxKind::INHERIT_KW + } else if ident.eq_ignore_ascii_case("inherits") { + SyntaxKind::INHERITS_KW + } else if ident.eq_ignore_ascii_case("initially") { + SyntaxKind::INITIALLY_KW + } else if ident.eq_ignore_ascii_case("inline") { + SyntaxKind::INLINE_KW + } else if ident.eq_ignore_ascii_case("inner") { + SyntaxKind::INNER_KW + } else if ident.eq_ignore_ascii_case("inout") { + SyntaxKind::INOUT_KW + } else if ident.eq_ignore_ascii_case("input") { + SyntaxKind::INPUT_KW + } else if ident.eq_ignore_ascii_case("insensitive") { + SyntaxKind::INSENSITIVE_KW + } else if ident.eq_ignore_ascii_case("insert") { + SyntaxKind::INSERT_KW + } else if ident.eq_ignore_ascii_case("instead") { + SyntaxKind::INSTEAD_KW + } else if ident.eq_ignore_ascii_case("int") { + SyntaxKind::INT_KW + } else if ident.eq_ignore_ascii_case("integer") { + SyntaxKind::INTEGER_KW + } else if ident.eq_ignore_ascii_case("intersect") { + SyntaxKind::INTERSECT_KW + } else if ident.eq_ignore_ascii_case("interval") { + SyntaxKind::INTERVAL_KW + } else if ident.eq_ignore_ascii_case("into") { + SyntaxKind::INTO_KW + } else if ident.eq_ignore_ascii_case("invoker") { + SyntaxKind::INVOKER_KW + } else if ident.eq_ignore_ascii_case("is") { + SyntaxKind::IS_KW + } else if ident.eq_ignore_ascii_case("isnull") { + SyntaxKind::ISNULL_KW + } else if ident.eq_ignore_ascii_case("isolation") { + SyntaxKind::ISOLATION_KW + } else if ident.eq_ignore_ascii_case("join") { + SyntaxKind::JOIN_KW + } else if ident.eq_ignore_ascii_case("json") { + SyntaxKind::JSON_KW + } else if ident.eq_ignore_ascii_case("json_array") { + SyntaxKind::JSON_ARRAY_KW + } else if ident.eq_ignore_ascii_case("json_arrayagg") { + SyntaxKind::JSON_ARRAYAGG_KW + } else if ident.eq_ignore_ascii_case("json_exists") { + SyntaxKind::JSON_EXISTS_KW + } else if ident.eq_ignore_ascii_case("json_object") { + SyntaxKind::JSON_OBJECT_KW + } else if ident.eq_ignore_ascii_case("json_objectagg") { + SyntaxKind::JSON_OBJECTAGG_KW + } else if ident.eq_ignore_ascii_case("json_query") { + SyntaxKind::JSON_QUERY_KW + } else if ident.eq_ignore_ascii_case("json_scalar") { + SyntaxKind::JSON_SCALAR_KW + } else if ident.eq_ignore_ascii_case("json_serialize") { + SyntaxKind::JSON_SERIALIZE_KW + } else if ident.eq_ignore_ascii_case("json_table") { + SyntaxKind::JSON_TABLE_KW + } else if ident.eq_ignore_ascii_case("json_value") { + SyntaxKind::JSON_VALUE_KW + } else if ident.eq_ignore_ascii_case("keep") { + SyntaxKind::KEEP_KW + } else if ident.eq_ignore_ascii_case("key") { + SyntaxKind::KEY_KW + } else if ident.eq_ignore_ascii_case("keys") { + SyntaxKind::KEYS_KW + } else if ident.eq_ignore_ascii_case("label") { + SyntaxKind::LABEL_KW + } else if ident.eq_ignore_ascii_case("language") { + SyntaxKind::LANGUAGE_KW + } else if ident.eq_ignore_ascii_case("large") { + SyntaxKind::LARGE_KW + } else if ident.eq_ignore_ascii_case("last") { + SyntaxKind::LAST_KW + } else if ident.eq_ignore_ascii_case("lateral") { + SyntaxKind::LATERAL_KW + } else if ident.eq_ignore_ascii_case("leading") { + SyntaxKind::LEADING_KW + } else if ident.eq_ignore_ascii_case("leakproof") { + SyntaxKind::LEAKPROOF_KW + } else if ident.eq_ignore_ascii_case("least") { + SyntaxKind::LEAST_KW + } else if ident.eq_ignore_ascii_case("left") { + SyntaxKind::LEFT_KW + } else if ident.eq_ignore_ascii_case("level") { + SyntaxKind::LEVEL_KW + } else if ident.eq_ignore_ascii_case("like") { + SyntaxKind::LIKE_KW + } else if ident.eq_ignore_ascii_case("limit") { + SyntaxKind::LIMIT_KW + } else if ident.eq_ignore_ascii_case("listen") { + SyntaxKind::LISTEN_KW + } else if ident.eq_ignore_ascii_case("load") { + SyntaxKind::LOAD_KW + } else if ident.eq_ignore_ascii_case("local") { + SyntaxKind::LOCAL_KW + } else if ident.eq_ignore_ascii_case("localtime") { + SyntaxKind::LOCALTIME_KW + } else if ident.eq_ignore_ascii_case("localtimestamp") { + SyntaxKind::LOCALTIMESTAMP_KW + } else if ident.eq_ignore_ascii_case("location") { + SyntaxKind::LOCATION_KW + } else if ident.eq_ignore_ascii_case("lock") { + SyntaxKind::LOCK_KW + } else if ident.eq_ignore_ascii_case("locked") { + SyntaxKind::LOCKED_KW + } else if ident.eq_ignore_ascii_case("logged") { + SyntaxKind::LOGGED_KW + } else if ident.eq_ignore_ascii_case("mapping") { + SyntaxKind::MAPPING_KW + } else if ident.eq_ignore_ascii_case("match") { + SyntaxKind::MATCH_KW + } else if ident.eq_ignore_ascii_case("matched") { + SyntaxKind::MATCHED_KW + } else if ident.eq_ignore_ascii_case("materialized") { + SyntaxKind::MATERIALIZED_KW + } else if ident.eq_ignore_ascii_case("maxvalue") { + SyntaxKind::MAXVALUE_KW + } else if ident.eq_ignore_ascii_case("merge") { + SyntaxKind::MERGE_KW + } else if ident.eq_ignore_ascii_case("merge_action") { + SyntaxKind::MERGE_ACTION_KW + } else if ident.eq_ignore_ascii_case("method") { + SyntaxKind::METHOD_KW + } else if ident.eq_ignore_ascii_case("minute") { + SyntaxKind::MINUTE_KW + } else if ident.eq_ignore_ascii_case("minvalue") { + SyntaxKind::MINVALUE_KW + } else if ident.eq_ignore_ascii_case("mode") { + SyntaxKind::MODE_KW + } else if ident.eq_ignore_ascii_case("month") { + SyntaxKind::MONTH_KW + } else if ident.eq_ignore_ascii_case("move") { + SyntaxKind::MOVE_KW + } else if ident.eq_ignore_ascii_case("name") { + SyntaxKind::NAME_KW + } else if ident.eq_ignore_ascii_case("names") { + SyntaxKind::NAMES_KW + } else if ident.eq_ignore_ascii_case("national") { + SyntaxKind::NATIONAL_KW + } else if ident.eq_ignore_ascii_case("natural") { + SyntaxKind::NATURAL_KW + } else if ident.eq_ignore_ascii_case("nchar") { + SyntaxKind::NCHAR_KW + } else if ident.eq_ignore_ascii_case("nested") { + SyntaxKind::NESTED_KW + } else if ident.eq_ignore_ascii_case("new") { + SyntaxKind::NEW_KW + } else if ident.eq_ignore_ascii_case("next") { + SyntaxKind::NEXT_KW + } else if ident.eq_ignore_ascii_case("nfc") { + SyntaxKind::NFC_KW + } else if ident.eq_ignore_ascii_case("nfd") { + SyntaxKind::NFD_KW + } else if ident.eq_ignore_ascii_case("nfkc") { + SyntaxKind::NFKC_KW + } else if ident.eq_ignore_ascii_case("nfkd") { + SyntaxKind::NFKD_KW + } else if ident.eq_ignore_ascii_case("no") { + SyntaxKind::NO_KW + } else if ident.eq_ignore_ascii_case("none") { + SyntaxKind::NONE_KW + } else if ident.eq_ignore_ascii_case("normalize") { + SyntaxKind::NORMALIZE_KW + } else if ident.eq_ignore_ascii_case("normalized") { + SyntaxKind::NORMALIZED_KW + } else if ident.eq_ignore_ascii_case("not") { + SyntaxKind::NOT_KW + } else if ident.eq_ignore_ascii_case("nothing") { + SyntaxKind::NOTHING_KW + } else if ident.eq_ignore_ascii_case("notify") { + SyntaxKind::NOTIFY_KW + } else if ident.eq_ignore_ascii_case("notnull") { + SyntaxKind::NOTNULL_KW + } else if ident.eq_ignore_ascii_case("nowait") { + SyntaxKind::NOWAIT_KW + } else if ident.eq_ignore_ascii_case("null") { + SyntaxKind::NULL_KW + } else if ident.eq_ignore_ascii_case("nullif") { + SyntaxKind::NULLIF_KW + } else if ident.eq_ignore_ascii_case("nulls") { + SyntaxKind::NULLS_KW + } else if ident.eq_ignore_ascii_case("numeric") { + SyntaxKind::NUMERIC_KW + } else if ident.eq_ignore_ascii_case("object") { + SyntaxKind::OBJECT_KW + } else if ident.eq_ignore_ascii_case("of") { + SyntaxKind::OF_KW + } else if ident.eq_ignore_ascii_case("off") { + SyntaxKind::OFF_KW + } else if ident.eq_ignore_ascii_case("offset") { + SyntaxKind::OFFSET_KW + } else if ident.eq_ignore_ascii_case("oids") { + SyntaxKind::OIDS_KW + } else if ident.eq_ignore_ascii_case("old") { + SyntaxKind::OLD_KW + } else if ident.eq_ignore_ascii_case("omit") { + SyntaxKind::OMIT_KW + } else if ident.eq_ignore_ascii_case("on") { + SyntaxKind::ON_KW + } else if ident.eq_ignore_ascii_case("only") { + SyntaxKind::ONLY_KW + } else if ident.eq_ignore_ascii_case("operator") { + SyntaxKind::OPERATOR_KW + } else if ident.eq_ignore_ascii_case("option") { + SyntaxKind::OPTION_KW + } else if ident.eq_ignore_ascii_case("options") { + SyntaxKind::OPTIONS_KW + } else if ident.eq_ignore_ascii_case("or") { + SyntaxKind::OR_KW + } else if ident.eq_ignore_ascii_case("order") { + SyntaxKind::ORDER_KW + } else if ident.eq_ignore_ascii_case("ordinality") { + SyntaxKind::ORDINALITY_KW + } else if ident.eq_ignore_ascii_case("others") { + SyntaxKind::OTHERS_KW + } else if ident.eq_ignore_ascii_case("out") { + SyntaxKind::OUT_KW + } else if ident.eq_ignore_ascii_case("outer") { + SyntaxKind::OUTER_KW + } else if ident.eq_ignore_ascii_case("over") { + SyntaxKind::OVER_KW + } else if ident.eq_ignore_ascii_case("overlaps") { + SyntaxKind::OVERLAPS_KW + } else if ident.eq_ignore_ascii_case("overlay") { + SyntaxKind::OVERLAY_KW + } else if ident.eq_ignore_ascii_case("overriding") { + SyntaxKind::OVERRIDING_KW + } else if ident.eq_ignore_ascii_case("owned") { + SyntaxKind::OWNED_KW + } else if ident.eq_ignore_ascii_case("owner") { + SyntaxKind::OWNER_KW + } else if ident.eq_ignore_ascii_case("parallel") { + SyntaxKind::PARALLEL_KW + } else if ident.eq_ignore_ascii_case("parameter") { + SyntaxKind::PARAMETER_KW + } else if ident.eq_ignore_ascii_case("parser") { + SyntaxKind::PARSER_KW + } else if ident.eq_ignore_ascii_case("partial") { + SyntaxKind::PARTIAL_KW + } else if ident.eq_ignore_ascii_case("partition") { + SyntaxKind::PARTITION_KW + } else if ident.eq_ignore_ascii_case("passing") { + SyntaxKind::PASSING_KW + } else if ident.eq_ignore_ascii_case("password") { + SyntaxKind::PASSWORD_KW + } else if ident.eq_ignore_ascii_case("path") { + SyntaxKind::PATH_KW + } else if ident.eq_ignore_ascii_case("period") { + SyntaxKind::PERIOD_KW + } else if ident.eq_ignore_ascii_case("placing") { + SyntaxKind::PLACING_KW + } else if ident.eq_ignore_ascii_case("plan") { + SyntaxKind::PLAN_KW + } else if ident.eq_ignore_ascii_case("plans") { + SyntaxKind::PLANS_KW + } else if ident.eq_ignore_ascii_case("policy") { + SyntaxKind::POLICY_KW + } else if ident.eq_ignore_ascii_case("position") { + SyntaxKind::POSITION_KW + } else if ident.eq_ignore_ascii_case("preceding") { + SyntaxKind::PRECEDING_KW + } else if ident.eq_ignore_ascii_case("precision") { + SyntaxKind::PRECISION_KW + } else if ident.eq_ignore_ascii_case("prepare") { + SyntaxKind::PREPARE_KW + } else if ident.eq_ignore_ascii_case("prepared") { + SyntaxKind::PREPARED_KW + } else if ident.eq_ignore_ascii_case("preserve") { + SyntaxKind::PRESERVE_KW + } else if ident.eq_ignore_ascii_case("primary") { + SyntaxKind::PRIMARY_KW + } else if ident.eq_ignore_ascii_case("prior") { + SyntaxKind::PRIOR_KW + } else if ident.eq_ignore_ascii_case("privileges") { + SyntaxKind::PRIVILEGES_KW + } else if ident.eq_ignore_ascii_case("procedural") { + SyntaxKind::PROCEDURAL_KW + } else if ident.eq_ignore_ascii_case("procedure") { + SyntaxKind::PROCEDURE_KW + } else if ident.eq_ignore_ascii_case("procedures") { + SyntaxKind::PROCEDURES_KW + } else if ident.eq_ignore_ascii_case("program") { + SyntaxKind::PROGRAM_KW + } else if ident.eq_ignore_ascii_case("publication") { + SyntaxKind::PUBLICATION_KW + } else if ident.eq_ignore_ascii_case("quote") { + SyntaxKind::QUOTE_KW + } else if ident.eq_ignore_ascii_case("quotes") { + SyntaxKind::QUOTES_KW + } else if ident.eq_ignore_ascii_case("range") { + SyntaxKind::RANGE_KW + } else if ident.eq_ignore_ascii_case("read") { + SyntaxKind::READ_KW + } else if ident.eq_ignore_ascii_case("real") { + SyntaxKind::REAL_KW + } else if ident.eq_ignore_ascii_case("reassign") { + SyntaxKind::REASSIGN_KW + } else if ident.eq_ignore_ascii_case("recursive") { + SyntaxKind::RECURSIVE_KW + } else if ident.eq_ignore_ascii_case("ref") { + SyntaxKind::REF_KW + } else if ident.eq_ignore_ascii_case("references") { + SyntaxKind::REFERENCES_KW + } else if ident.eq_ignore_ascii_case("referencing") { + SyntaxKind::REFERENCING_KW + } else if ident.eq_ignore_ascii_case("refresh") { + SyntaxKind::REFRESH_KW + } else if ident.eq_ignore_ascii_case("reindex") { + SyntaxKind::REINDEX_KW + } else if ident.eq_ignore_ascii_case("relative") { + SyntaxKind::RELATIVE_KW + } else if ident.eq_ignore_ascii_case("release") { + SyntaxKind::RELEASE_KW + } else if ident.eq_ignore_ascii_case("rename") { + SyntaxKind::RENAME_KW + } else if ident.eq_ignore_ascii_case("repeatable") { + SyntaxKind::REPEATABLE_KW + } else if ident.eq_ignore_ascii_case("replace") { + SyntaxKind::REPLACE_KW + } else if ident.eq_ignore_ascii_case("replica") { + SyntaxKind::REPLICA_KW + } else if ident.eq_ignore_ascii_case("reset") { + SyntaxKind::RESET_KW + } else if ident.eq_ignore_ascii_case("restart") { + SyntaxKind::RESTART_KW + } else if ident.eq_ignore_ascii_case("restrict") { + SyntaxKind::RESTRICT_KW + } else if ident.eq_ignore_ascii_case("return") { + SyntaxKind::RETURN_KW + } else if ident.eq_ignore_ascii_case("returning") { + SyntaxKind::RETURNING_KW + } else if ident.eq_ignore_ascii_case("returns") { + SyntaxKind::RETURNS_KW + } else if ident.eq_ignore_ascii_case("revoke") { + SyntaxKind::REVOKE_KW + } else if ident.eq_ignore_ascii_case("right") { + SyntaxKind::RIGHT_KW + } else if ident.eq_ignore_ascii_case("role") { + SyntaxKind::ROLE_KW + } else if ident.eq_ignore_ascii_case("rollback") { + SyntaxKind::ROLLBACK_KW + } else if ident.eq_ignore_ascii_case("rollup") { + SyntaxKind::ROLLUP_KW + } else if ident.eq_ignore_ascii_case("routine") { + SyntaxKind::ROUTINE_KW + } else if ident.eq_ignore_ascii_case("routines") { + SyntaxKind::ROUTINES_KW + } else if ident.eq_ignore_ascii_case("row") { + SyntaxKind::ROW_KW + } else if ident.eq_ignore_ascii_case("rows") { + SyntaxKind::ROWS_KW + } else if ident.eq_ignore_ascii_case("rule") { + SyntaxKind::RULE_KW + } else if ident.eq_ignore_ascii_case("savepoint") { + SyntaxKind::SAVEPOINT_KW + } else if ident.eq_ignore_ascii_case("scalar") { + SyntaxKind::SCALAR_KW + } else if ident.eq_ignore_ascii_case("schema") { + SyntaxKind::SCHEMA_KW + } else if ident.eq_ignore_ascii_case("schemas") { + SyntaxKind::SCHEMAS_KW + } else if ident.eq_ignore_ascii_case("scroll") { + SyntaxKind::SCROLL_KW + } else if ident.eq_ignore_ascii_case("search") { + SyntaxKind::SEARCH_KW + } else if ident.eq_ignore_ascii_case("second") { + SyntaxKind::SECOND_KW + } else if ident.eq_ignore_ascii_case("security") { + SyntaxKind::SECURITY_KW + } else if ident.eq_ignore_ascii_case("select") { + SyntaxKind::SELECT_KW + } else if ident.eq_ignore_ascii_case("sequence") { + SyntaxKind::SEQUENCE_KW + } else if ident.eq_ignore_ascii_case("sequences") { + SyntaxKind::SEQUENCES_KW + } else if ident.eq_ignore_ascii_case("serializable") { + SyntaxKind::SERIALIZABLE_KW + } else if ident.eq_ignore_ascii_case("server") { + SyntaxKind::SERVER_KW + } else if ident.eq_ignore_ascii_case("session") { + SyntaxKind::SESSION_KW + } else if ident.eq_ignore_ascii_case("session_user") { + SyntaxKind::SESSION_USER_KW + } else if ident.eq_ignore_ascii_case("set") { + SyntaxKind::SET_KW + } else if ident.eq_ignore_ascii_case("setof") { + SyntaxKind::SETOF_KW + } else if ident.eq_ignore_ascii_case("sets") { + SyntaxKind::SETS_KW + } else if ident.eq_ignore_ascii_case("share") { + SyntaxKind::SHARE_KW + } else if ident.eq_ignore_ascii_case("show") { + SyntaxKind::SHOW_KW + } else if ident.eq_ignore_ascii_case("similar") { + SyntaxKind::SIMILAR_KW + } else if ident.eq_ignore_ascii_case("simple") { + SyntaxKind::SIMPLE_KW + } else if ident.eq_ignore_ascii_case("skip") { + SyntaxKind::SKIP_KW + } else if ident.eq_ignore_ascii_case("smallint") { + SyntaxKind::SMALLINT_KW + } else if ident.eq_ignore_ascii_case("snapshot") { + SyntaxKind::SNAPSHOT_KW + } else if ident.eq_ignore_ascii_case("some") { + SyntaxKind::SOME_KW + } else if ident.eq_ignore_ascii_case("source") { + SyntaxKind::SOURCE_KW + } else if ident.eq_ignore_ascii_case("sql") { + SyntaxKind::SQL_KW + } else if ident.eq_ignore_ascii_case("stable") { + SyntaxKind::STABLE_KW + } else if ident.eq_ignore_ascii_case("standalone") { + SyntaxKind::STANDALONE_KW + } else if ident.eq_ignore_ascii_case("start") { + SyntaxKind::START_KW + } else if ident.eq_ignore_ascii_case("statement") { + SyntaxKind::STATEMENT_KW + } else if ident.eq_ignore_ascii_case("statistics") { + SyntaxKind::STATISTICS_KW + } else if ident.eq_ignore_ascii_case("stdin") { + SyntaxKind::STDIN_KW + } else if ident.eq_ignore_ascii_case("stdout") { + SyntaxKind::STDOUT_KW + } else if ident.eq_ignore_ascii_case("storage") { + SyntaxKind::STORAGE_KW + } else if ident.eq_ignore_ascii_case("stored") { + SyntaxKind::STORED_KW + } else if ident.eq_ignore_ascii_case("strict") { + SyntaxKind::STRICT_KW + } else if ident.eq_ignore_ascii_case("string") { + SyntaxKind::STRING_KW + } else if ident.eq_ignore_ascii_case("strip") { + SyntaxKind::STRIP_KW + } else if ident.eq_ignore_ascii_case("subscription") { + SyntaxKind::SUBSCRIPTION_KW + } else if ident.eq_ignore_ascii_case("substring") { + SyntaxKind::SUBSTRING_KW + } else if ident.eq_ignore_ascii_case("support") { + SyntaxKind::SUPPORT_KW + } else if ident.eq_ignore_ascii_case("symmetric") { + SyntaxKind::SYMMETRIC_KW + } else if ident.eq_ignore_ascii_case("sysid") { + SyntaxKind::SYSID_KW + } else if ident.eq_ignore_ascii_case("system") { + SyntaxKind::SYSTEM_KW + } else if ident.eq_ignore_ascii_case("system_user") { + SyntaxKind::SYSTEM_USER_KW + } else if ident.eq_ignore_ascii_case("table") { + SyntaxKind::TABLE_KW + } else if ident.eq_ignore_ascii_case("tables") { + SyntaxKind::TABLES_KW + } else if ident.eq_ignore_ascii_case("tablesample") { + SyntaxKind::TABLESAMPLE_KW + } else if ident.eq_ignore_ascii_case("tablespace") { + SyntaxKind::TABLESPACE_KW + } else if ident.eq_ignore_ascii_case("target") { + SyntaxKind::TARGET_KW + } else if ident.eq_ignore_ascii_case("temp") { + SyntaxKind::TEMP_KW + } else if ident.eq_ignore_ascii_case("template") { + SyntaxKind::TEMPLATE_KW + } else if ident.eq_ignore_ascii_case("temporary") { + SyntaxKind::TEMPORARY_KW + } else if ident.eq_ignore_ascii_case("text") { + SyntaxKind::TEXT_KW + } else if ident.eq_ignore_ascii_case("then") { + SyntaxKind::THEN_KW + } else if ident.eq_ignore_ascii_case("ties") { + SyntaxKind::TIES_KW + } else if ident.eq_ignore_ascii_case("time") { + SyntaxKind::TIME_KW + } else if ident.eq_ignore_ascii_case("timestamp") { + SyntaxKind::TIMESTAMP_KW + } else if ident.eq_ignore_ascii_case("to") { + SyntaxKind::TO_KW + } else if ident.eq_ignore_ascii_case("trailing") { + SyntaxKind::TRAILING_KW + } else if ident.eq_ignore_ascii_case("transaction") { + SyntaxKind::TRANSACTION_KW + } else if ident.eq_ignore_ascii_case("transform") { + SyntaxKind::TRANSFORM_KW + } else if ident.eq_ignore_ascii_case("treat") { + SyntaxKind::TREAT_KW + } else if ident.eq_ignore_ascii_case("trigger") { + SyntaxKind::TRIGGER_KW + } else if ident.eq_ignore_ascii_case("trim") { + SyntaxKind::TRIM_KW + } else if ident.eq_ignore_ascii_case("true") { + SyntaxKind::TRUE_KW + } else if ident.eq_ignore_ascii_case("truncate") { + SyntaxKind::TRUNCATE_KW + } else if ident.eq_ignore_ascii_case("trusted") { + SyntaxKind::TRUSTED_KW + } else if ident.eq_ignore_ascii_case("type") { + SyntaxKind::TYPE_KW + } else if ident.eq_ignore_ascii_case("types") { + SyntaxKind::TYPES_KW + } else if ident.eq_ignore_ascii_case("uescape") { + SyntaxKind::UESCAPE_KW + } else if ident.eq_ignore_ascii_case("unbounded") { + SyntaxKind::UNBOUNDED_KW + } else if ident.eq_ignore_ascii_case("uncommitted") { + SyntaxKind::UNCOMMITTED_KW + } else if ident.eq_ignore_ascii_case("unconditional") { + SyntaxKind::UNCONDITIONAL_KW + } else if ident.eq_ignore_ascii_case("unencrypted") { + SyntaxKind::UNENCRYPTED_KW + } else if ident.eq_ignore_ascii_case("union") { + SyntaxKind::UNION_KW + } else if ident.eq_ignore_ascii_case("unique") { + SyntaxKind::UNIQUE_KW + } else if ident.eq_ignore_ascii_case("unknown") { + SyntaxKind::UNKNOWN_KW + } else if ident.eq_ignore_ascii_case("unlisten") { + SyntaxKind::UNLISTEN_KW + } else if ident.eq_ignore_ascii_case("unlogged") { + SyntaxKind::UNLOGGED_KW + } else if ident.eq_ignore_ascii_case("until") { + SyntaxKind::UNTIL_KW + } else if ident.eq_ignore_ascii_case("update") { + SyntaxKind::UPDATE_KW + } else if ident.eq_ignore_ascii_case("user") { + SyntaxKind::USER_KW + } else if ident.eq_ignore_ascii_case("using") { + SyntaxKind::USING_KW + } else if ident.eq_ignore_ascii_case("vacuum") { + SyntaxKind::VACUUM_KW + } else if ident.eq_ignore_ascii_case("valid") { + SyntaxKind::VALID_KW + } else if ident.eq_ignore_ascii_case("validate") { + SyntaxKind::VALIDATE_KW + } else if ident.eq_ignore_ascii_case("validator") { + SyntaxKind::VALIDATOR_KW + } else if ident.eq_ignore_ascii_case("value") { + SyntaxKind::VALUE_KW + } else if ident.eq_ignore_ascii_case("values") { + SyntaxKind::VALUES_KW + } else if ident.eq_ignore_ascii_case("varchar") { + SyntaxKind::VARCHAR_KW + } else if ident.eq_ignore_ascii_case("variadic") { + SyntaxKind::VARIADIC_KW + } else if ident.eq_ignore_ascii_case("varying") { + SyntaxKind::VARYING_KW + } else if ident.eq_ignore_ascii_case("verbose") { + SyntaxKind::VERBOSE_KW + } else if ident.eq_ignore_ascii_case("version") { + SyntaxKind::VERSION_KW + } else if ident.eq_ignore_ascii_case("view") { + SyntaxKind::VIEW_KW + } else if ident.eq_ignore_ascii_case("views") { + SyntaxKind::VIEWS_KW + } else if ident.eq_ignore_ascii_case("volatile") { + SyntaxKind::VOLATILE_KW + } else if ident.eq_ignore_ascii_case("when") { + SyntaxKind::WHEN_KW + } else if ident.eq_ignore_ascii_case("where") { + SyntaxKind::WHERE_KW + } else if ident.eq_ignore_ascii_case("whitespace") { + SyntaxKind::WHITESPACE_KW + } else if ident.eq_ignore_ascii_case("window") { + SyntaxKind::WINDOW_KW + } else if ident.eq_ignore_ascii_case("with") { + SyntaxKind::WITH_KW + } else if ident.eq_ignore_ascii_case("within") { + SyntaxKind::WITHIN_KW + } else if ident.eq_ignore_ascii_case("without") { + SyntaxKind::WITHOUT_KW + } else if ident.eq_ignore_ascii_case("work") { + SyntaxKind::WORK_KW + } else if ident.eq_ignore_ascii_case("wrapper") { + SyntaxKind::WRAPPER_KW + } else if ident.eq_ignore_ascii_case("write") { + SyntaxKind::WRITE_KW + } else if ident.eq_ignore_ascii_case("xml") { + SyntaxKind::XML_KW + } else if ident.eq_ignore_ascii_case("xmlattributes") { + SyntaxKind::XMLATTRIBUTES_KW + } else if ident.eq_ignore_ascii_case("xmlconcat") { + SyntaxKind::XMLCONCAT_KW + } else if ident.eq_ignore_ascii_case("xmlelement") { + SyntaxKind::XMLELEMENT_KW + } else if ident.eq_ignore_ascii_case("xmlexists") { + SyntaxKind::XMLEXISTS_KW + } else if ident.eq_ignore_ascii_case("xmlforest") { + SyntaxKind::XMLFOREST_KW + } else if ident.eq_ignore_ascii_case("xmlnamespaces") { + SyntaxKind::XMLNAMESPACES_KW + } else if ident.eq_ignore_ascii_case("xmlparse") { + SyntaxKind::XMLPARSE_KW + } else if ident.eq_ignore_ascii_case("xmlpi") { + SyntaxKind::XMLPI_KW + } else if ident.eq_ignore_ascii_case("xmlroot") { + SyntaxKind::XMLROOT_KW + } else if ident.eq_ignore_ascii_case("xmlserialize") { + SyntaxKind::XMLSERIALIZE_KW + } else if ident.eq_ignore_ascii_case("xmltable") { + SyntaxKind::XMLTABLE_KW + } else if ident.eq_ignore_ascii_case("year") { + SyntaxKind::YEAR_KW + } else if ident.eq_ignore_ascii_case("yes") { + SyntaxKind::YES_KW + } else if ident.eq_ignore_ascii_case("zone") { + SyntaxKind::ZONE_KW + } else { + return None; + }; + Some(kw) + } +} + +// Generated TokenSet start +pub(crate) const COLUMN_OR_TABLE_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ABORT_KW, + SyntaxKind::ABSENT_KW, + SyntaxKind::ABSOLUTE_KW, + SyntaxKind::ACCESS_KW, + SyntaxKind::ACTION_KW, + SyntaxKind::ADD_KW, + SyntaxKind::ADMIN_KW, + SyntaxKind::AFTER_KW, + SyntaxKind::AGGREGATE_KW, + SyntaxKind::ALSO_KW, + SyntaxKind::ALTER_KW, + SyntaxKind::ALWAYS_KW, + SyntaxKind::ASENSITIVE_KW, + SyntaxKind::ASSERTION_KW, + SyntaxKind::ASSIGNMENT_KW, + SyntaxKind::AT_KW, + SyntaxKind::ATOMIC_KW, + SyntaxKind::ATTACH_KW, + SyntaxKind::ATTRIBUTE_KW, + SyntaxKind::BACKWARD_KW, + SyntaxKind::BEFORE_KW, + SyntaxKind::BEGIN_KW, + SyntaxKind::BETWEEN_KW, + SyntaxKind::BIGINT_KW, + SyntaxKind::BIT_KW, + SyntaxKind::BOOLEAN_KW, + SyntaxKind::BREADTH_KW, + SyntaxKind::BY_KW, + SyntaxKind::CACHE_KW, + SyntaxKind::CALL_KW, + SyntaxKind::CALLED_KW, + SyntaxKind::CASCADE_KW, + SyntaxKind::CASCADED_KW, + SyntaxKind::CATALOG_KW, + SyntaxKind::CHAIN_KW, + SyntaxKind::CHAR_KW, + SyntaxKind::CHARACTER_KW, + SyntaxKind::CHARACTERISTICS_KW, + SyntaxKind::CHECKPOINT_KW, + SyntaxKind::CLASS_KW, + SyntaxKind::CLOSE_KW, + SyntaxKind::CLUSTER_KW, + SyntaxKind::COALESCE_KW, + SyntaxKind::COLUMNS_KW, + SyntaxKind::COMMENT_KW, + SyntaxKind::COMMENTS_KW, + SyntaxKind::COMMIT_KW, + SyntaxKind::COMMITTED_KW, + SyntaxKind::COMPRESSION_KW, + SyntaxKind::CONDITIONAL_KW, + SyntaxKind::CONFIGURATION_KW, + SyntaxKind::CONFLICT_KW, + SyntaxKind::CONNECTION_KW, + SyntaxKind::CONSTRAINTS_KW, + SyntaxKind::CONTENT_KW, + SyntaxKind::CONTINUE_KW, + SyntaxKind::CONVERSION_KW, + SyntaxKind::COPY_KW, + SyntaxKind::COST_KW, + SyntaxKind::CSV_KW, + SyntaxKind::CUBE_KW, + SyntaxKind::CURRENT_KW, + SyntaxKind::CURSOR_KW, + SyntaxKind::CYCLE_KW, + SyntaxKind::DATA_KW, + SyntaxKind::DATABASE_KW, + SyntaxKind::DAY_KW, + SyntaxKind::DEALLOCATE_KW, + SyntaxKind::DEC_KW, + SyntaxKind::DECIMAL_KW, + SyntaxKind::DECLARE_KW, + SyntaxKind::DEFAULTS_KW, + SyntaxKind::DEFERRED_KW, + SyntaxKind::DEFINER_KW, + SyntaxKind::DELETE_KW, + SyntaxKind::DELIMITER_KW, + SyntaxKind::DELIMITERS_KW, + SyntaxKind::DEPENDS_KW, + SyntaxKind::DEPTH_KW, + SyntaxKind::DETACH_KW, + SyntaxKind::DICTIONARY_KW, + SyntaxKind::DISABLE_KW, + SyntaxKind::DISCARD_KW, + SyntaxKind::DOCUMENT_KW, + SyntaxKind::DOMAIN_KW, + SyntaxKind::DOUBLE_KW, + SyntaxKind::DROP_KW, + SyntaxKind::EACH_KW, + SyntaxKind::EMPTY_KW, + SyntaxKind::ENABLE_KW, + SyntaxKind::ENCODING_KW, + SyntaxKind::ENCRYPTED_KW, + SyntaxKind::ENUM_KW, + SyntaxKind::ERROR_KW, + SyntaxKind::ESCAPE_KW, + SyntaxKind::EVENT_KW, + SyntaxKind::EXCLUDE_KW, + SyntaxKind::EXCLUDING_KW, + SyntaxKind::EXCLUSIVE_KW, + SyntaxKind::EXECUTE_KW, + SyntaxKind::EXISTS_KW, + SyntaxKind::EXPLAIN_KW, + SyntaxKind::EXPRESSION_KW, + SyntaxKind::EXTENSION_KW, + SyntaxKind::EXTERNAL_KW, + SyntaxKind::EXTRACT_KW, + SyntaxKind::FAMILY_KW, + SyntaxKind::FILTER_KW, + SyntaxKind::FINALIZE_KW, + SyntaxKind::FIRST_KW, + SyntaxKind::FLOAT_KW, + SyntaxKind::FOLLOWING_KW, + SyntaxKind::FORCE_KW, + SyntaxKind::FORMAT_KW, + SyntaxKind::FORWARD_KW, + SyntaxKind::FUNCTION_KW, + SyntaxKind::FUNCTIONS_KW, + SyntaxKind::GENERATED_KW, + SyntaxKind::GLOBAL_KW, + SyntaxKind::GRANTED_KW, + SyntaxKind::GREATEST_KW, + SyntaxKind::GROUPING_KW, + SyntaxKind::GROUPS_KW, + SyntaxKind::HANDLER_KW, + SyntaxKind::HEADER_KW, + SyntaxKind::HOLD_KW, + SyntaxKind::HOUR_KW, + SyntaxKind::IDENTITY_KW, + SyntaxKind::IF_KW, + SyntaxKind::IMMEDIATE_KW, + SyntaxKind::IMMUTABLE_KW, + SyntaxKind::IMPLICIT_KW, + SyntaxKind::IMPORT_KW, + SyntaxKind::INCLUDE_KW, + SyntaxKind::INCLUDING_KW, + SyntaxKind::INCREMENT_KW, + SyntaxKind::INDENT_KW, + SyntaxKind::INDEX_KW, + SyntaxKind::INDEXES_KW, + SyntaxKind::INHERIT_KW, + SyntaxKind::INHERITS_KW, + SyntaxKind::INLINE_KW, + SyntaxKind::INOUT_KW, + SyntaxKind::INPUT_KW, + SyntaxKind::INSENSITIVE_KW, + SyntaxKind::INSERT_KW, + SyntaxKind::INSTEAD_KW, + SyntaxKind::INT_KW, + SyntaxKind::INTEGER_KW, + SyntaxKind::INTERVAL_KW, + SyntaxKind::INVOKER_KW, + SyntaxKind::ISOLATION_KW, + SyntaxKind::JSON_KW, + SyntaxKind::JSON_ARRAY_KW, + SyntaxKind::JSON_ARRAYAGG_KW, + SyntaxKind::JSON_EXISTS_KW, + SyntaxKind::JSON_OBJECT_KW, + SyntaxKind::JSON_OBJECTAGG_KW, + SyntaxKind::JSON_QUERY_KW, + SyntaxKind::JSON_SCALAR_KW, + SyntaxKind::JSON_SERIALIZE_KW, + SyntaxKind::JSON_TABLE_KW, + SyntaxKind::JSON_VALUE_KW, + SyntaxKind::KEEP_KW, + SyntaxKind::KEY_KW, + SyntaxKind::KEYS_KW, + SyntaxKind::LABEL_KW, + SyntaxKind::LANGUAGE_KW, + SyntaxKind::LARGE_KW, + SyntaxKind::LAST_KW, + SyntaxKind::LEAKPROOF_KW, + SyntaxKind::LEAST_KW, + SyntaxKind::LEVEL_KW, + SyntaxKind::LISTEN_KW, + SyntaxKind::LOAD_KW, + SyntaxKind::LOCAL_KW, + SyntaxKind::LOCATION_KW, + SyntaxKind::LOCK_KW, + SyntaxKind::LOCKED_KW, + SyntaxKind::LOGGED_KW, + SyntaxKind::MAPPING_KW, + SyntaxKind::MATCH_KW, + SyntaxKind::MATCHED_KW, + SyntaxKind::MATERIALIZED_KW, + SyntaxKind::MAXVALUE_KW, + SyntaxKind::MERGE_KW, + SyntaxKind::MERGE_ACTION_KW, + SyntaxKind::METHOD_KW, + SyntaxKind::MINUTE_KW, + SyntaxKind::MINVALUE_KW, + SyntaxKind::MODE_KW, + SyntaxKind::MONTH_KW, + SyntaxKind::MOVE_KW, + SyntaxKind::NAME_KW, + SyntaxKind::NAMES_KW, + SyntaxKind::NATIONAL_KW, + SyntaxKind::NCHAR_KW, + SyntaxKind::NESTED_KW, + SyntaxKind::NEW_KW, + SyntaxKind::NEXT_KW, + SyntaxKind::NFC_KW, + SyntaxKind::NFD_KW, + SyntaxKind::NFKC_KW, + SyntaxKind::NFKD_KW, + SyntaxKind::NO_KW, + SyntaxKind::NONE_KW, + SyntaxKind::NORMALIZE_KW, + SyntaxKind::NORMALIZED_KW, + SyntaxKind::NOTHING_KW, + SyntaxKind::NOTIFY_KW, + SyntaxKind::NOWAIT_KW, + SyntaxKind::NULLIF_KW, + SyntaxKind::NULLS_KW, + SyntaxKind::NUMERIC_KW, + SyntaxKind::OBJECT_KW, + SyntaxKind::OF_KW, + SyntaxKind::OFF_KW, + SyntaxKind::OIDS_KW, + SyntaxKind::OLD_KW, + SyntaxKind::OMIT_KW, + SyntaxKind::OPERATOR_KW, + SyntaxKind::OPTION_KW, + SyntaxKind::OPTIONS_KW, + SyntaxKind::ORDINALITY_KW, + SyntaxKind::OTHERS_KW, + SyntaxKind::OUT_KW, + SyntaxKind::OVER_KW, + SyntaxKind::OVERLAY_KW, + SyntaxKind::OVERRIDING_KW, + SyntaxKind::OWNED_KW, + SyntaxKind::OWNER_KW, + SyntaxKind::PARALLEL_KW, + SyntaxKind::PARAMETER_KW, + SyntaxKind::PARSER_KW, + SyntaxKind::PARTIAL_KW, + SyntaxKind::PARTITION_KW, + SyntaxKind::PASSING_KW, + SyntaxKind::PASSWORD_KW, + SyntaxKind::PATH_KW, + SyntaxKind::PERIOD_KW, + SyntaxKind::PLAN_KW, + SyntaxKind::PLANS_KW, + SyntaxKind::POLICY_KW, + SyntaxKind::POSITION_KW, + SyntaxKind::PRECEDING_KW, + SyntaxKind::PRECISION_KW, + SyntaxKind::PREPARE_KW, + SyntaxKind::PREPARED_KW, + SyntaxKind::PRESERVE_KW, + SyntaxKind::PRIOR_KW, + SyntaxKind::PRIVILEGES_KW, + SyntaxKind::PROCEDURAL_KW, + SyntaxKind::PROCEDURE_KW, + SyntaxKind::PROCEDURES_KW, + SyntaxKind::PROGRAM_KW, + SyntaxKind::PUBLICATION_KW, + SyntaxKind::QUOTE_KW, + SyntaxKind::QUOTES_KW, + SyntaxKind::RANGE_KW, + SyntaxKind::READ_KW, + SyntaxKind::REAL_KW, + SyntaxKind::REASSIGN_KW, + SyntaxKind::RECURSIVE_KW, + SyntaxKind::REF_KW, + SyntaxKind::REFERENCING_KW, + SyntaxKind::REFRESH_KW, + SyntaxKind::REINDEX_KW, + SyntaxKind::RELATIVE_KW, + SyntaxKind::RELEASE_KW, + SyntaxKind::RENAME_KW, + SyntaxKind::REPEATABLE_KW, + SyntaxKind::REPLACE_KW, + SyntaxKind::REPLICA_KW, + SyntaxKind::RESET_KW, + SyntaxKind::RESTART_KW, + SyntaxKind::RESTRICT_KW, + SyntaxKind::RETURN_KW, + SyntaxKind::RETURNS_KW, + SyntaxKind::REVOKE_KW, + SyntaxKind::ROLE_KW, + SyntaxKind::ROLLBACK_KW, + SyntaxKind::ROLLUP_KW, + SyntaxKind::ROUTINE_KW, + SyntaxKind::ROUTINES_KW, + SyntaxKind::ROW_KW, + SyntaxKind::ROWS_KW, + SyntaxKind::RULE_KW, + SyntaxKind::SAVEPOINT_KW, + SyntaxKind::SCALAR_KW, + SyntaxKind::SCHEMA_KW, + SyntaxKind::SCHEMAS_KW, + SyntaxKind::SCROLL_KW, + SyntaxKind::SEARCH_KW, + SyntaxKind::SECOND_KW, + SyntaxKind::SECURITY_KW, + SyntaxKind::SEQUENCE_KW, + SyntaxKind::SEQUENCES_KW, + SyntaxKind::SERIALIZABLE_KW, + SyntaxKind::SERVER_KW, + SyntaxKind::SESSION_KW, + SyntaxKind::SET_KW, + SyntaxKind::SETOF_KW, + SyntaxKind::SETS_KW, + SyntaxKind::SHARE_KW, + SyntaxKind::SHOW_KW, + SyntaxKind::SIMPLE_KW, + SyntaxKind::SKIP_KW, + SyntaxKind::SMALLINT_KW, + SyntaxKind::SNAPSHOT_KW, + SyntaxKind::SOURCE_KW, + SyntaxKind::SQL_KW, + SyntaxKind::STABLE_KW, + SyntaxKind::STANDALONE_KW, + SyntaxKind::START_KW, + SyntaxKind::STATEMENT_KW, + SyntaxKind::STATISTICS_KW, + SyntaxKind::STDIN_KW, + SyntaxKind::STDOUT_KW, + SyntaxKind::STORAGE_KW, + SyntaxKind::STORED_KW, + SyntaxKind::STRICT_KW, + SyntaxKind::STRING_KW, + SyntaxKind::STRIP_KW, + SyntaxKind::SUBSCRIPTION_KW, + SyntaxKind::SUBSTRING_KW, + SyntaxKind::SUPPORT_KW, + SyntaxKind::SYSID_KW, + SyntaxKind::SYSTEM_KW, + SyntaxKind::TABLES_KW, + SyntaxKind::TABLESPACE_KW, + SyntaxKind::TARGET_KW, + SyntaxKind::TEMP_KW, + SyntaxKind::TEMPLATE_KW, + SyntaxKind::TEMPORARY_KW, + SyntaxKind::TEXT_KW, + SyntaxKind::TIES_KW, + SyntaxKind::TIME_KW, + SyntaxKind::TIMESTAMP_KW, + SyntaxKind::TRANSACTION_KW, + SyntaxKind::TRANSFORM_KW, + SyntaxKind::TREAT_KW, + SyntaxKind::TRIGGER_KW, + SyntaxKind::TRIM_KW, + SyntaxKind::TRUNCATE_KW, + SyntaxKind::TRUSTED_KW, + SyntaxKind::TYPE_KW, + SyntaxKind::TYPES_KW, + SyntaxKind::UESCAPE_KW, + SyntaxKind::UNBOUNDED_KW, + SyntaxKind::UNCOMMITTED_KW, + SyntaxKind::UNCONDITIONAL_KW, + SyntaxKind::UNENCRYPTED_KW, + SyntaxKind::UNKNOWN_KW, + SyntaxKind::UNLISTEN_KW, + SyntaxKind::UNLOGGED_KW, + SyntaxKind::UNTIL_KW, + SyntaxKind::UPDATE_KW, + SyntaxKind::VACUUM_KW, + SyntaxKind::VALID_KW, + SyntaxKind::VALIDATE_KW, + SyntaxKind::VALIDATOR_KW, + SyntaxKind::VALUE_KW, + SyntaxKind::VALUES_KW, + SyntaxKind::VARCHAR_KW, + SyntaxKind::VARYING_KW, + SyntaxKind::VERSION_KW, + SyntaxKind::VIEW_KW, + SyntaxKind::VIEWS_KW, + SyntaxKind::VOLATILE_KW, + SyntaxKind::WHITESPACE_KW, + SyntaxKind::WITHIN_KW, + SyntaxKind::WITHOUT_KW, + SyntaxKind::WORK_KW, + SyntaxKind::WRAPPER_KW, + SyntaxKind::WRITE_KW, + SyntaxKind::XML_KW, + SyntaxKind::XMLATTRIBUTES_KW, + SyntaxKind::XMLCONCAT_KW, + SyntaxKind::XMLELEMENT_KW, + SyntaxKind::XMLEXISTS_KW, + SyntaxKind::XMLFOREST_KW, + SyntaxKind::XMLNAMESPACES_KW, + SyntaxKind::XMLPARSE_KW, + SyntaxKind::XMLPI_KW, + SyntaxKind::XMLROOT_KW, + SyntaxKind::XMLSERIALIZE_KW, + SyntaxKind::XMLTABLE_KW, + SyntaxKind::YEAR_KW, + SyntaxKind::YES_KW, + SyntaxKind::ZONE_KW, +]); + +pub(crate) const TYPE_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ABORT_KW, + SyntaxKind::ABSENT_KW, + SyntaxKind::ABSOLUTE_KW, + SyntaxKind::ACCESS_KW, + SyntaxKind::ACTION_KW, + SyntaxKind::ADD_KW, + SyntaxKind::ADMIN_KW, + SyntaxKind::AFTER_KW, + SyntaxKind::AGGREGATE_KW, + SyntaxKind::ALSO_KW, + SyntaxKind::ALTER_KW, + SyntaxKind::ALWAYS_KW, + SyntaxKind::ASENSITIVE_KW, + SyntaxKind::ASSERTION_KW, + SyntaxKind::ASSIGNMENT_KW, + SyntaxKind::AT_KW, + SyntaxKind::ATOMIC_KW, + SyntaxKind::ATTACH_KW, + SyntaxKind::ATTRIBUTE_KW, + SyntaxKind::AUTHORIZATION_KW, + SyntaxKind::BACKWARD_KW, + SyntaxKind::BEFORE_KW, + SyntaxKind::BEGIN_KW, + SyntaxKind::BETWEEN_KW, + SyntaxKind::BIGINT_KW, + SyntaxKind::BINARY_KW, + SyntaxKind::BIT_KW, + SyntaxKind::BOOLEAN_KW, + SyntaxKind::BREADTH_KW, + SyntaxKind::BY_KW, + SyntaxKind::CACHE_KW, + SyntaxKind::CALL_KW, + SyntaxKind::CALLED_KW, + SyntaxKind::CASCADE_KW, + SyntaxKind::CASCADED_KW, + SyntaxKind::CATALOG_KW, + SyntaxKind::CHAIN_KW, + SyntaxKind::CHAR_KW, + SyntaxKind::CHARACTER_KW, + SyntaxKind::CHARACTERISTICS_KW, + SyntaxKind::CHECKPOINT_KW, + SyntaxKind::CLASS_KW, + SyntaxKind::CLOSE_KW, + SyntaxKind::CLUSTER_KW, + SyntaxKind::COALESCE_KW, + SyntaxKind::COLLATION_KW, + SyntaxKind::COLUMNS_KW, + SyntaxKind::COMMENT_KW, + SyntaxKind::COMMENTS_KW, + SyntaxKind::COMMIT_KW, + SyntaxKind::COMMITTED_KW, + SyntaxKind::COMPRESSION_KW, + SyntaxKind::CONCURRENTLY_KW, + SyntaxKind::CONDITIONAL_KW, + SyntaxKind::CONFIGURATION_KW, + SyntaxKind::CONFLICT_KW, + SyntaxKind::CONNECTION_KW, + SyntaxKind::CONSTRAINTS_KW, + SyntaxKind::CONTENT_KW, + SyntaxKind::CONTINUE_KW, + SyntaxKind::CONVERSION_KW, + SyntaxKind::COPY_KW, + SyntaxKind::COST_KW, + SyntaxKind::CROSS_KW, + SyntaxKind::CSV_KW, + SyntaxKind::CUBE_KW, + SyntaxKind::CURRENT_KW, + SyntaxKind::CURRENT_SCHEMA_KW, + SyntaxKind::CURSOR_KW, + SyntaxKind::CYCLE_KW, + SyntaxKind::DATA_KW, + SyntaxKind::DATABASE_KW, + SyntaxKind::DAY_KW, + SyntaxKind::DEALLOCATE_KW, + SyntaxKind::DEC_KW, + SyntaxKind::DECIMAL_KW, + SyntaxKind::DECLARE_KW, + SyntaxKind::DEFAULTS_KW, + SyntaxKind::DEFERRED_KW, + SyntaxKind::DEFINER_KW, + SyntaxKind::DELETE_KW, + SyntaxKind::DELIMITER_KW, + SyntaxKind::DELIMITERS_KW, + SyntaxKind::DEPENDS_KW, + SyntaxKind::DEPTH_KW, + SyntaxKind::DETACH_KW, + SyntaxKind::DICTIONARY_KW, + SyntaxKind::DISABLE_KW, + SyntaxKind::DISCARD_KW, + SyntaxKind::DOCUMENT_KW, + SyntaxKind::DOMAIN_KW, + SyntaxKind::DOUBLE_KW, + SyntaxKind::DROP_KW, + SyntaxKind::EACH_KW, + SyntaxKind::EMPTY_KW, + SyntaxKind::ENABLE_KW, + SyntaxKind::ENCODING_KW, + SyntaxKind::ENCRYPTED_KW, + SyntaxKind::ENUM_KW, + SyntaxKind::ERROR_KW, + SyntaxKind::ESCAPE_KW, + SyntaxKind::EVENT_KW, + SyntaxKind::EXCLUDE_KW, + SyntaxKind::EXCLUDING_KW, + SyntaxKind::EXCLUSIVE_KW, + SyntaxKind::EXECUTE_KW, + SyntaxKind::EXISTS_KW, + SyntaxKind::EXPLAIN_KW, + SyntaxKind::EXPRESSION_KW, + SyntaxKind::EXTENSION_KW, + SyntaxKind::EXTERNAL_KW, + SyntaxKind::EXTRACT_KW, + SyntaxKind::FAMILY_KW, + SyntaxKind::FILTER_KW, + SyntaxKind::FINALIZE_KW, + SyntaxKind::FIRST_KW, + SyntaxKind::FLOAT_KW, + SyntaxKind::FOLLOWING_KW, + SyntaxKind::FORCE_KW, + SyntaxKind::FORMAT_KW, + SyntaxKind::FORWARD_KW, + SyntaxKind::FREEZE_KW, + SyntaxKind::FULL_KW, + SyntaxKind::FUNCTION_KW, + SyntaxKind::FUNCTIONS_KW, + SyntaxKind::GENERATED_KW, + SyntaxKind::GLOBAL_KW, + SyntaxKind::GRANTED_KW, + SyntaxKind::GREATEST_KW, + SyntaxKind::GROUPING_KW, + SyntaxKind::GROUPS_KW, + SyntaxKind::HANDLER_KW, + SyntaxKind::HEADER_KW, + SyntaxKind::HOLD_KW, + SyntaxKind::HOUR_KW, + SyntaxKind::IDENTITY_KW, + SyntaxKind::IF_KW, + SyntaxKind::ILIKE_KW, + SyntaxKind::IMMEDIATE_KW, + SyntaxKind::IMMUTABLE_KW, + SyntaxKind::IMPLICIT_KW, + SyntaxKind::IMPORT_KW, + SyntaxKind::INCLUDE_KW, + SyntaxKind::INCLUDING_KW, + SyntaxKind::INCREMENT_KW, + SyntaxKind::INDENT_KW, + SyntaxKind::INDEX_KW, + SyntaxKind::INDEXES_KW, + SyntaxKind::INHERIT_KW, + SyntaxKind::INHERITS_KW, + SyntaxKind::INLINE_KW, + SyntaxKind::INNER_KW, + SyntaxKind::INOUT_KW, + SyntaxKind::INPUT_KW, + SyntaxKind::INSENSITIVE_KW, + SyntaxKind::INSERT_KW, + SyntaxKind::INSTEAD_KW, + SyntaxKind::INT_KW, + SyntaxKind::INTEGER_KW, + SyntaxKind::INTERVAL_KW, + SyntaxKind::INVOKER_KW, + SyntaxKind::IS_KW, + SyntaxKind::ISNULL_KW, + SyntaxKind::ISOLATION_KW, + SyntaxKind::JOIN_KW, + SyntaxKind::JSON_KW, + SyntaxKind::JSON_ARRAY_KW, + SyntaxKind::JSON_ARRAYAGG_KW, + SyntaxKind::JSON_EXISTS_KW, + SyntaxKind::JSON_OBJECT_KW, + SyntaxKind::JSON_OBJECTAGG_KW, + SyntaxKind::JSON_QUERY_KW, + SyntaxKind::JSON_SCALAR_KW, + SyntaxKind::JSON_SERIALIZE_KW, + SyntaxKind::JSON_TABLE_KW, + SyntaxKind::JSON_VALUE_KW, + SyntaxKind::KEEP_KW, + SyntaxKind::KEY_KW, + SyntaxKind::KEYS_KW, + SyntaxKind::LABEL_KW, + SyntaxKind::LANGUAGE_KW, + SyntaxKind::LARGE_KW, + SyntaxKind::LAST_KW, + SyntaxKind::LEAKPROOF_KW, + SyntaxKind::LEAST_KW, + SyntaxKind::LEFT_KW, + SyntaxKind::LEVEL_KW, + SyntaxKind::LIKE_KW, + SyntaxKind::LISTEN_KW, + SyntaxKind::LOAD_KW, + SyntaxKind::LOCAL_KW, + SyntaxKind::LOCATION_KW, + SyntaxKind::LOCK_KW, + SyntaxKind::LOCKED_KW, + SyntaxKind::LOGGED_KW, + SyntaxKind::MAPPING_KW, + SyntaxKind::MATCH_KW, + SyntaxKind::MATCHED_KW, + SyntaxKind::MATERIALIZED_KW, + SyntaxKind::MAXVALUE_KW, + SyntaxKind::MERGE_KW, + SyntaxKind::MERGE_ACTION_KW, + SyntaxKind::METHOD_KW, + SyntaxKind::MINUTE_KW, + SyntaxKind::MINVALUE_KW, + SyntaxKind::MODE_KW, + SyntaxKind::MONTH_KW, + SyntaxKind::MOVE_KW, + SyntaxKind::NAME_KW, + SyntaxKind::NAMES_KW, + SyntaxKind::NATIONAL_KW, + SyntaxKind::NATURAL_KW, + SyntaxKind::NCHAR_KW, + SyntaxKind::NESTED_KW, + SyntaxKind::NEW_KW, + SyntaxKind::NEXT_KW, + SyntaxKind::NFC_KW, + SyntaxKind::NFD_KW, + SyntaxKind::NFKC_KW, + SyntaxKind::NFKD_KW, + SyntaxKind::NO_KW, + SyntaxKind::NONE_KW, + SyntaxKind::NORMALIZE_KW, + SyntaxKind::NORMALIZED_KW, + SyntaxKind::NOTHING_KW, + SyntaxKind::NOTIFY_KW, + SyntaxKind::NOTNULL_KW, + SyntaxKind::NOWAIT_KW, + SyntaxKind::NULLIF_KW, + SyntaxKind::NULLS_KW, + SyntaxKind::NUMERIC_KW, + SyntaxKind::OBJECT_KW, + SyntaxKind::OF_KW, + SyntaxKind::OFF_KW, + SyntaxKind::OIDS_KW, + SyntaxKind::OLD_KW, + SyntaxKind::OMIT_KW, + SyntaxKind::OPERATOR_KW, + SyntaxKind::OPTION_KW, + SyntaxKind::OPTIONS_KW, + SyntaxKind::ORDINALITY_KW, + SyntaxKind::OTHERS_KW, + SyntaxKind::OUT_KW, + SyntaxKind::OUTER_KW, + SyntaxKind::OVER_KW, + SyntaxKind::OVERLAPS_KW, + SyntaxKind::OVERLAY_KW, + SyntaxKind::OVERRIDING_KW, + SyntaxKind::OWNED_KW, + SyntaxKind::OWNER_KW, + SyntaxKind::PARALLEL_KW, + SyntaxKind::PARAMETER_KW, + SyntaxKind::PARSER_KW, + SyntaxKind::PARTIAL_KW, + SyntaxKind::PARTITION_KW, + SyntaxKind::PASSING_KW, + SyntaxKind::PASSWORD_KW, + SyntaxKind::PATH_KW, + SyntaxKind::PERIOD_KW, + SyntaxKind::PLAN_KW, + SyntaxKind::PLANS_KW, + SyntaxKind::POLICY_KW, + SyntaxKind::POSITION_KW, + SyntaxKind::PRECEDING_KW, + SyntaxKind::PRECISION_KW, + SyntaxKind::PREPARE_KW, + SyntaxKind::PREPARED_KW, + SyntaxKind::PRESERVE_KW, + SyntaxKind::PRIOR_KW, + SyntaxKind::PRIVILEGES_KW, + SyntaxKind::PROCEDURAL_KW, + SyntaxKind::PROCEDURE_KW, + SyntaxKind::PROCEDURES_KW, + SyntaxKind::PROGRAM_KW, + SyntaxKind::PUBLICATION_KW, + SyntaxKind::QUOTE_KW, + SyntaxKind::QUOTES_KW, + SyntaxKind::RANGE_KW, + SyntaxKind::READ_KW, + SyntaxKind::REAL_KW, + SyntaxKind::REASSIGN_KW, + SyntaxKind::RECURSIVE_KW, + SyntaxKind::REF_KW, + SyntaxKind::REFERENCING_KW, + SyntaxKind::REFRESH_KW, + SyntaxKind::REINDEX_KW, + SyntaxKind::RELATIVE_KW, + SyntaxKind::RELEASE_KW, + SyntaxKind::RENAME_KW, + SyntaxKind::REPEATABLE_KW, + SyntaxKind::REPLACE_KW, + SyntaxKind::REPLICA_KW, + SyntaxKind::RESET_KW, + SyntaxKind::RESTART_KW, + SyntaxKind::RESTRICT_KW, + SyntaxKind::RETURN_KW, + SyntaxKind::RETURNS_KW, + SyntaxKind::REVOKE_KW, + SyntaxKind::RIGHT_KW, + SyntaxKind::ROLE_KW, + SyntaxKind::ROLLBACK_KW, + SyntaxKind::ROLLUP_KW, + SyntaxKind::ROUTINE_KW, + SyntaxKind::ROUTINES_KW, + SyntaxKind::ROW_KW, + SyntaxKind::ROWS_KW, + SyntaxKind::RULE_KW, + SyntaxKind::SAVEPOINT_KW, + SyntaxKind::SCALAR_KW, + SyntaxKind::SCHEMA_KW, + SyntaxKind::SCHEMAS_KW, + SyntaxKind::SCROLL_KW, + SyntaxKind::SEARCH_KW, + SyntaxKind::SECOND_KW, + SyntaxKind::SECURITY_KW, + SyntaxKind::SEQUENCE_KW, + SyntaxKind::SEQUENCES_KW, + SyntaxKind::SERIALIZABLE_KW, + SyntaxKind::SERVER_KW, + SyntaxKind::SESSION_KW, + SyntaxKind::SET_KW, + SyntaxKind::SETOF_KW, + SyntaxKind::SETS_KW, + SyntaxKind::SHARE_KW, + SyntaxKind::SHOW_KW, + SyntaxKind::SIMILAR_KW, + SyntaxKind::SIMPLE_KW, + SyntaxKind::SKIP_KW, + SyntaxKind::SMALLINT_KW, + SyntaxKind::SNAPSHOT_KW, + SyntaxKind::SOURCE_KW, + SyntaxKind::SQL_KW, + SyntaxKind::STABLE_KW, + SyntaxKind::STANDALONE_KW, + SyntaxKind::START_KW, + SyntaxKind::STATEMENT_KW, + SyntaxKind::STATISTICS_KW, + SyntaxKind::STDIN_KW, + SyntaxKind::STDOUT_KW, + SyntaxKind::STORAGE_KW, + SyntaxKind::STORED_KW, + SyntaxKind::STRICT_KW, + SyntaxKind::STRING_KW, + SyntaxKind::STRIP_KW, + SyntaxKind::SUBSCRIPTION_KW, + SyntaxKind::SUBSTRING_KW, + SyntaxKind::SUPPORT_KW, + SyntaxKind::SYSID_KW, + SyntaxKind::SYSTEM_KW, + SyntaxKind::TABLES_KW, + SyntaxKind::TABLESAMPLE_KW, + SyntaxKind::TABLESPACE_KW, + SyntaxKind::TARGET_KW, + SyntaxKind::TEMP_KW, + SyntaxKind::TEMPLATE_KW, + SyntaxKind::TEMPORARY_KW, + SyntaxKind::TEXT_KW, + SyntaxKind::TIES_KW, + SyntaxKind::TIME_KW, + SyntaxKind::TIMESTAMP_KW, + SyntaxKind::TRANSACTION_KW, + SyntaxKind::TRANSFORM_KW, + SyntaxKind::TREAT_KW, + SyntaxKind::TRIGGER_KW, + SyntaxKind::TRIM_KW, + SyntaxKind::TRUNCATE_KW, + SyntaxKind::TRUSTED_KW, + SyntaxKind::TYPE_KW, + SyntaxKind::TYPES_KW, + SyntaxKind::UESCAPE_KW, + SyntaxKind::UNBOUNDED_KW, + SyntaxKind::UNCOMMITTED_KW, + SyntaxKind::UNCONDITIONAL_KW, + SyntaxKind::UNENCRYPTED_KW, + SyntaxKind::UNKNOWN_KW, + SyntaxKind::UNLISTEN_KW, + SyntaxKind::UNLOGGED_KW, + SyntaxKind::UNTIL_KW, + SyntaxKind::UPDATE_KW, + SyntaxKind::VACUUM_KW, + SyntaxKind::VALID_KW, + SyntaxKind::VALIDATE_KW, + SyntaxKind::VALIDATOR_KW, + SyntaxKind::VALUE_KW, + SyntaxKind::VALUES_KW, + SyntaxKind::VARCHAR_KW, + SyntaxKind::VARYING_KW, + SyntaxKind::VERBOSE_KW, + SyntaxKind::VERSION_KW, + SyntaxKind::VIEW_KW, + SyntaxKind::VIEWS_KW, + SyntaxKind::VOLATILE_KW, + SyntaxKind::WHITESPACE_KW, + SyntaxKind::WITHIN_KW, + SyntaxKind::WITHOUT_KW, + SyntaxKind::WORK_KW, + SyntaxKind::WRAPPER_KW, + SyntaxKind::WRITE_KW, + SyntaxKind::XML_KW, + SyntaxKind::XMLATTRIBUTES_KW, + SyntaxKind::XMLCONCAT_KW, + SyntaxKind::XMLELEMENT_KW, + SyntaxKind::XMLEXISTS_KW, + SyntaxKind::XMLFOREST_KW, + SyntaxKind::XMLNAMESPACES_KW, + SyntaxKind::XMLPARSE_KW, + SyntaxKind::XMLPI_KW, + SyntaxKind::XMLROOT_KW, + SyntaxKind::XMLSERIALIZE_KW, + SyntaxKind::XMLTABLE_KW, + SyntaxKind::YEAR_KW, + SyntaxKind::YES_KW, + SyntaxKind::ZONE_KW, +]); + +pub(crate) const ALL_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ABORT_KW, + SyntaxKind::ABSENT_KW, + SyntaxKind::ABSOLUTE_KW, + SyntaxKind::ACCESS_KW, + SyntaxKind::ACTION_KW, + SyntaxKind::ADD_KW, + SyntaxKind::ADMIN_KW, + SyntaxKind::AFTER_KW, + SyntaxKind::AGGREGATE_KW, + SyntaxKind::ALL_KW, + SyntaxKind::ALSO_KW, + SyntaxKind::ALTER_KW, + SyntaxKind::ALWAYS_KW, + SyntaxKind::ANALYSE_KW, + SyntaxKind::ANALYZE_KW, + SyntaxKind::AND_KW, + SyntaxKind::ANY_KW, + SyntaxKind::ARRAY_KW, + SyntaxKind::AS_KW, + SyntaxKind::ASC_KW, + SyntaxKind::ASENSITIVE_KW, + SyntaxKind::ASSERTION_KW, + SyntaxKind::ASSIGNMENT_KW, + SyntaxKind::ASYMMETRIC_KW, + SyntaxKind::AT_KW, + SyntaxKind::ATOMIC_KW, + SyntaxKind::ATTACH_KW, + SyntaxKind::ATTRIBUTE_KW, + SyntaxKind::AUTHORIZATION_KW, + SyntaxKind::BACKWARD_KW, + SyntaxKind::BEFORE_KW, + SyntaxKind::BEGIN_KW, + SyntaxKind::BETWEEN_KW, + SyntaxKind::BIGINT_KW, + SyntaxKind::BINARY_KW, + SyntaxKind::BIT_KW, + SyntaxKind::BOOLEAN_KW, + SyntaxKind::BOTH_KW, + SyntaxKind::BREADTH_KW, + SyntaxKind::BY_KW, + SyntaxKind::CACHE_KW, + SyntaxKind::CALL_KW, + SyntaxKind::CALLED_KW, + SyntaxKind::CASCADE_KW, + SyntaxKind::CASCADED_KW, + SyntaxKind::CASE_KW, + SyntaxKind::CAST_KW, + SyntaxKind::CATALOG_KW, + SyntaxKind::CHAIN_KW, + SyntaxKind::CHAR_KW, + SyntaxKind::CHARACTER_KW, + SyntaxKind::CHARACTERISTICS_KW, + SyntaxKind::CHECK_KW, + SyntaxKind::CHECKPOINT_KW, + SyntaxKind::CLASS_KW, + SyntaxKind::CLOSE_KW, + SyntaxKind::CLUSTER_KW, + SyntaxKind::COALESCE_KW, + SyntaxKind::COLLATE_KW, + SyntaxKind::COLLATION_KW, + SyntaxKind::COLUMN_KW, + SyntaxKind::COLUMNS_KW, + SyntaxKind::COMMENT_KW, + SyntaxKind::COMMENTS_KW, + SyntaxKind::COMMIT_KW, + SyntaxKind::COMMITTED_KW, + SyntaxKind::COMPRESSION_KW, + SyntaxKind::CONCURRENTLY_KW, + SyntaxKind::CONDITIONAL_KW, + SyntaxKind::CONFIGURATION_KW, + SyntaxKind::CONFLICT_KW, + SyntaxKind::CONNECTION_KW, + SyntaxKind::CONSTRAINT_KW, + SyntaxKind::CONSTRAINTS_KW, + SyntaxKind::CONTENT_KW, + SyntaxKind::CONTINUE_KW, + SyntaxKind::CONVERSION_KW, + SyntaxKind::COPY_KW, + SyntaxKind::COST_KW, + SyntaxKind::CREATE_KW, + SyntaxKind::CROSS_KW, + SyntaxKind::CSV_KW, + SyntaxKind::CUBE_KW, + SyntaxKind::CURRENT_KW, + SyntaxKind::CURRENT_CATALOG_KW, + SyntaxKind::CURRENT_DATE_KW, + SyntaxKind::CURRENT_ROLE_KW, + SyntaxKind::CURRENT_SCHEMA_KW, + SyntaxKind::CURRENT_TIME_KW, + SyntaxKind::CURRENT_TIMESTAMP_KW, + SyntaxKind::CURRENT_USER_KW, + SyntaxKind::CURSOR_KW, + SyntaxKind::CYCLE_KW, + SyntaxKind::DATA_KW, + SyntaxKind::DATABASE_KW, + SyntaxKind::DAY_KW, + SyntaxKind::DEALLOCATE_KW, + SyntaxKind::DEC_KW, + SyntaxKind::DECIMAL_KW, + SyntaxKind::DECLARE_KW, + SyntaxKind::DEFAULT_KW, + SyntaxKind::DEFAULTS_KW, + SyntaxKind::DEFERRABLE_KW, + SyntaxKind::DEFERRED_KW, + SyntaxKind::DEFINER_KW, + SyntaxKind::DELETE_KW, + SyntaxKind::DELIMITER_KW, + SyntaxKind::DELIMITERS_KW, + SyntaxKind::DEPENDS_KW, + SyntaxKind::DEPTH_KW, + SyntaxKind::DESC_KW, + SyntaxKind::DETACH_KW, + SyntaxKind::DICTIONARY_KW, + SyntaxKind::DISABLE_KW, + SyntaxKind::DISCARD_KW, + SyntaxKind::DISTINCT_KW, + SyntaxKind::DO_KW, + SyntaxKind::DOCUMENT_KW, + SyntaxKind::DOMAIN_KW, + SyntaxKind::DOUBLE_KW, + SyntaxKind::DROP_KW, + SyntaxKind::EACH_KW, + SyntaxKind::ELSE_KW, + SyntaxKind::EMPTY_KW, + SyntaxKind::ENABLE_KW, + SyntaxKind::ENCODING_KW, + SyntaxKind::ENCRYPTED_KW, + SyntaxKind::END_KW, + SyntaxKind::ENUM_KW, + SyntaxKind::ERROR_KW, + SyntaxKind::ESCAPE_KW, + SyntaxKind::EVENT_KW, + SyntaxKind::EXCEPT_KW, + SyntaxKind::EXCLUDE_KW, + SyntaxKind::EXCLUDING_KW, + SyntaxKind::EXCLUSIVE_KW, + SyntaxKind::EXECUTE_KW, + SyntaxKind::EXISTS_KW, + SyntaxKind::EXPLAIN_KW, + SyntaxKind::EXPRESSION_KW, + SyntaxKind::EXTENSION_KW, + SyntaxKind::EXTERNAL_KW, + SyntaxKind::EXTRACT_KW, + SyntaxKind::FALSE_KW, + SyntaxKind::FAMILY_KW, + SyntaxKind::FETCH_KW, + SyntaxKind::FILTER_KW, + SyntaxKind::FINALIZE_KW, + SyntaxKind::FIRST_KW, + SyntaxKind::FLOAT_KW, + SyntaxKind::FOLLOWING_KW, + SyntaxKind::FOR_KW, + SyntaxKind::FORCE_KW, + SyntaxKind::FOREIGN_KW, + SyntaxKind::FORMAT_KW, + SyntaxKind::FORWARD_KW, + SyntaxKind::FREEZE_KW, + SyntaxKind::FROM_KW, + SyntaxKind::FULL_KW, + SyntaxKind::FUNCTION_KW, + SyntaxKind::FUNCTIONS_KW, + SyntaxKind::GENERATED_KW, + SyntaxKind::GLOBAL_KW, + SyntaxKind::GRANT_KW, + SyntaxKind::GRANTED_KW, + SyntaxKind::GREATEST_KW, + SyntaxKind::GROUP_KW, + SyntaxKind::GROUPING_KW, + SyntaxKind::GROUPS_KW, + SyntaxKind::HANDLER_KW, + SyntaxKind::HAVING_KW, + SyntaxKind::HEADER_KW, + SyntaxKind::HOLD_KW, + SyntaxKind::HOUR_KW, + SyntaxKind::IDENTITY_KW, + SyntaxKind::IF_KW, + SyntaxKind::ILIKE_KW, + SyntaxKind::IMMEDIATE_KW, + SyntaxKind::IMMUTABLE_KW, + SyntaxKind::IMPLICIT_KW, + SyntaxKind::IMPORT_KW, + SyntaxKind::IN_KW, + SyntaxKind::INCLUDE_KW, + SyntaxKind::INCLUDING_KW, + SyntaxKind::INCREMENT_KW, + SyntaxKind::INDENT_KW, + SyntaxKind::INDEX_KW, + SyntaxKind::INDEXES_KW, + SyntaxKind::INHERIT_KW, + SyntaxKind::INHERITS_KW, + SyntaxKind::INITIALLY_KW, + SyntaxKind::INLINE_KW, + SyntaxKind::INNER_KW, + SyntaxKind::INOUT_KW, + SyntaxKind::INPUT_KW, + SyntaxKind::INSENSITIVE_KW, + SyntaxKind::INSERT_KW, + SyntaxKind::INSTEAD_KW, + SyntaxKind::INT_KW, + SyntaxKind::INTEGER_KW, + SyntaxKind::INTERSECT_KW, + SyntaxKind::INTERVAL_KW, + SyntaxKind::INTO_KW, + SyntaxKind::INVOKER_KW, + SyntaxKind::IS_KW, + SyntaxKind::ISNULL_KW, + SyntaxKind::ISOLATION_KW, + SyntaxKind::JOIN_KW, + SyntaxKind::JSON_KW, + SyntaxKind::JSON_ARRAY_KW, + SyntaxKind::JSON_ARRAYAGG_KW, + SyntaxKind::JSON_EXISTS_KW, + SyntaxKind::JSON_OBJECT_KW, + SyntaxKind::JSON_OBJECTAGG_KW, + SyntaxKind::JSON_QUERY_KW, + SyntaxKind::JSON_SCALAR_KW, + SyntaxKind::JSON_SERIALIZE_KW, + SyntaxKind::JSON_TABLE_KW, + SyntaxKind::JSON_VALUE_KW, + SyntaxKind::KEEP_KW, + SyntaxKind::KEY_KW, + SyntaxKind::KEYS_KW, + SyntaxKind::LABEL_KW, + SyntaxKind::LANGUAGE_KW, + SyntaxKind::LARGE_KW, + SyntaxKind::LAST_KW, + SyntaxKind::LATERAL_KW, + SyntaxKind::LEADING_KW, + SyntaxKind::LEAKPROOF_KW, + SyntaxKind::LEAST_KW, + SyntaxKind::LEFT_KW, + SyntaxKind::LEVEL_KW, + SyntaxKind::LIKE_KW, + SyntaxKind::LIMIT_KW, + SyntaxKind::LISTEN_KW, + SyntaxKind::LOAD_KW, + SyntaxKind::LOCAL_KW, + SyntaxKind::LOCALTIME_KW, + SyntaxKind::LOCALTIMESTAMP_KW, + SyntaxKind::LOCATION_KW, + SyntaxKind::LOCK_KW, + SyntaxKind::LOCKED_KW, + SyntaxKind::LOGGED_KW, + SyntaxKind::MAPPING_KW, + SyntaxKind::MATCH_KW, + SyntaxKind::MATCHED_KW, + SyntaxKind::MATERIALIZED_KW, + SyntaxKind::MAXVALUE_KW, + SyntaxKind::MERGE_KW, + SyntaxKind::MERGE_ACTION_KW, + SyntaxKind::METHOD_KW, + SyntaxKind::MINUTE_KW, + SyntaxKind::MINVALUE_KW, + SyntaxKind::MODE_KW, + SyntaxKind::MONTH_KW, + SyntaxKind::MOVE_KW, + SyntaxKind::NAME_KW, + SyntaxKind::NAMES_KW, + SyntaxKind::NATIONAL_KW, + SyntaxKind::NATURAL_KW, + SyntaxKind::NCHAR_KW, + SyntaxKind::NESTED_KW, + SyntaxKind::NEW_KW, + SyntaxKind::NEXT_KW, + SyntaxKind::NFC_KW, + SyntaxKind::NFD_KW, + SyntaxKind::NFKC_KW, + SyntaxKind::NFKD_KW, + SyntaxKind::NO_KW, + SyntaxKind::NONE_KW, + SyntaxKind::NORMALIZE_KW, + SyntaxKind::NORMALIZED_KW, + SyntaxKind::NOT_KW, + SyntaxKind::NOTHING_KW, + SyntaxKind::NOTIFY_KW, + SyntaxKind::NOTNULL_KW, + SyntaxKind::NOWAIT_KW, + SyntaxKind::NULL_KW, + SyntaxKind::NULLIF_KW, + SyntaxKind::NULLS_KW, + SyntaxKind::NUMERIC_KW, + SyntaxKind::OBJECT_KW, + SyntaxKind::OF_KW, + SyntaxKind::OFF_KW, + SyntaxKind::OFFSET_KW, + SyntaxKind::OIDS_KW, + SyntaxKind::OLD_KW, + SyntaxKind::OMIT_KW, + SyntaxKind::ON_KW, + SyntaxKind::ONLY_KW, + SyntaxKind::OPERATOR_KW, + SyntaxKind::OPTION_KW, + SyntaxKind::OPTIONS_KW, + SyntaxKind::OR_KW, + SyntaxKind::ORDER_KW, + SyntaxKind::ORDINALITY_KW, + SyntaxKind::OTHERS_KW, + SyntaxKind::OUT_KW, + SyntaxKind::OUTER_KW, + SyntaxKind::OVER_KW, + SyntaxKind::OVERLAPS_KW, + SyntaxKind::OVERLAY_KW, + SyntaxKind::OVERRIDING_KW, + SyntaxKind::OWNED_KW, + SyntaxKind::OWNER_KW, + SyntaxKind::PARALLEL_KW, + SyntaxKind::PARAMETER_KW, + SyntaxKind::PARSER_KW, + SyntaxKind::PARTIAL_KW, + SyntaxKind::PARTITION_KW, + SyntaxKind::PASSING_KW, + SyntaxKind::PASSWORD_KW, + SyntaxKind::PATH_KW, + SyntaxKind::PERIOD_KW, + SyntaxKind::PLACING_KW, + SyntaxKind::PLAN_KW, + SyntaxKind::PLANS_KW, + SyntaxKind::POLICY_KW, + SyntaxKind::POSITION_KW, + SyntaxKind::PRECEDING_KW, + SyntaxKind::PRECISION_KW, + SyntaxKind::PREPARE_KW, + SyntaxKind::PREPARED_KW, + SyntaxKind::PRESERVE_KW, + SyntaxKind::PRIMARY_KW, + SyntaxKind::PRIOR_KW, + SyntaxKind::PRIVILEGES_KW, + SyntaxKind::PROCEDURAL_KW, + SyntaxKind::PROCEDURE_KW, + SyntaxKind::PROCEDURES_KW, + SyntaxKind::PROGRAM_KW, + SyntaxKind::PUBLICATION_KW, + SyntaxKind::QUOTE_KW, + SyntaxKind::QUOTES_KW, + SyntaxKind::RANGE_KW, + SyntaxKind::READ_KW, + SyntaxKind::REAL_KW, + SyntaxKind::REASSIGN_KW, + SyntaxKind::RECURSIVE_KW, + SyntaxKind::REF_KW, + SyntaxKind::REFERENCES_KW, + SyntaxKind::REFERENCING_KW, + SyntaxKind::REFRESH_KW, + SyntaxKind::REINDEX_KW, + SyntaxKind::RELATIVE_KW, + SyntaxKind::RELEASE_KW, + SyntaxKind::RENAME_KW, + SyntaxKind::REPEATABLE_KW, + SyntaxKind::REPLACE_KW, + SyntaxKind::REPLICA_KW, + SyntaxKind::RESET_KW, + SyntaxKind::RESTART_KW, + SyntaxKind::RESTRICT_KW, + SyntaxKind::RETURN_KW, + SyntaxKind::RETURNING_KW, + SyntaxKind::RETURNS_KW, + SyntaxKind::REVOKE_KW, + SyntaxKind::RIGHT_KW, + SyntaxKind::ROLE_KW, + SyntaxKind::ROLLBACK_KW, + SyntaxKind::ROLLUP_KW, + SyntaxKind::ROUTINE_KW, + SyntaxKind::ROUTINES_KW, + SyntaxKind::ROW_KW, + SyntaxKind::ROWS_KW, + SyntaxKind::RULE_KW, + SyntaxKind::SAVEPOINT_KW, + SyntaxKind::SCALAR_KW, + SyntaxKind::SCHEMA_KW, + SyntaxKind::SCHEMAS_KW, + SyntaxKind::SCROLL_KW, + SyntaxKind::SEARCH_KW, + SyntaxKind::SECOND_KW, + SyntaxKind::SECURITY_KW, + SyntaxKind::SELECT_KW, + SyntaxKind::SEQUENCE_KW, + SyntaxKind::SEQUENCES_KW, + SyntaxKind::SERIALIZABLE_KW, + SyntaxKind::SERVER_KW, + SyntaxKind::SESSION_KW, + SyntaxKind::SESSION_USER_KW, + SyntaxKind::SET_KW, + SyntaxKind::SETOF_KW, + SyntaxKind::SETS_KW, + SyntaxKind::SHARE_KW, + SyntaxKind::SHOW_KW, + SyntaxKind::SIMILAR_KW, + SyntaxKind::SIMPLE_KW, + SyntaxKind::SKIP_KW, + SyntaxKind::SMALLINT_KW, + SyntaxKind::SNAPSHOT_KW, + SyntaxKind::SOME_KW, + SyntaxKind::SOURCE_KW, + SyntaxKind::SQL_KW, + SyntaxKind::STABLE_KW, + SyntaxKind::STANDALONE_KW, + SyntaxKind::START_KW, + SyntaxKind::STATEMENT_KW, + SyntaxKind::STATISTICS_KW, + SyntaxKind::STDIN_KW, + SyntaxKind::STDOUT_KW, + SyntaxKind::STORAGE_KW, + SyntaxKind::STORED_KW, + SyntaxKind::STRICT_KW, + SyntaxKind::STRING_KW, + SyntaxKind::STRIP_KW, + SyntaxKind::SUBSCRIPTION_KW, + SyntaxKind::SUBSTRING_KW, + SyntaxKind::SUPPORT_KW, + SyntaxKind::SYMMETRIC_KW, + SyntaxKind::SYSID_KW, + SyntaxKind::SYSTEM_KW, + SyntaxKind::SYSTEM_USER_KW, + SyntaxKind::TABLE_KW, + SyntaxKind::TABLES_KW, + SyntaxKind::TABLESAMPLE_KW, + SyntaxKind::TABLESPACE_KW, + SyntaxKind::TARGET_KW, + SyntaxKind::TEMP_KW, + SyntaxKind::TEMPLATE_KW, + SyntaxKind::TEMPORARY_KW, + SyntaxKind::TEXT_KW, + SyntaxKind::THEN_KW, + SyntaxKind::TIES_KW, + SyntaxKind::TIME_KW, + SyntaxKind::TIMESTAMP_KW, + SyntaxKind::TO_KW, + SyntaxKind::TRAILING_KW, + SyntaxKind::TRANSACTION_KW, + SyntaxKind::TRANSFORM_KW, + SyntaxKind::TREAT_KW, + SyntaxKind::TRIGGER_KW, + SyntaxKind::TRIM_KW, + SyntaxKind::TRUE_KW, + SyntaxKind::TRUNCATE_KW, + SyntaxKind::TRUSTED_KW, + SyntaxKind::TYPE_KW, + SyntaxKind::TYPES_KW, + SyntaxKind::UESCAPE_KW, + SyntaxKind::UNBOUNDED_KW, + SyntaxKind::UNCOMMITTED_KW, + SyntaxKind::UNCONDITIONAL_KW, + SyntaxKind::UNENCRYPTED_KW, + SyntaxKind::UNION_KW, + SyntaxKind::UNIQUE_KW, + SyntaxKind::UNKNOWN_KW, + SyntaxKind::UNLISTEN_KW, + SyntaxKind::UNLOGGED_KW, + SyntaxKind::UNTIL_KW, + SyntaxKind::UPDATE_KW, + SyntaxKind::USER_KW, + SyntaxKind::USING_KW, + SyntaxKind::VACUUM_KW, + SyntaxKind::VALID_KW, + SyntaxKind::VALIDATE_KW, + SyntaxKind::VALIDATOR_KW, + SyntaxKind::VALUE_KW, + SyntaxKind::VALUES_KW, + SyntaxKind::VARCHAR_KW, + SyntaxKind::VARIADIC_KW, + SyntaxKind::VARYING_KW, + SyntaxKind::VERBOSE_KW, + SyntaxKind::VERSION_KW, + SyntaxKind::VIEW_KW, + SyntaxKind::VIEWS_KW, + SyntaxKind::VOLATILE_KW, + SyntaxKind::WHEN_KW, + SyntaxKind::WHERE_KW, + SyntaxKind::WHITESPACE_KW, + SyntaxKind::WINDOW_KW, + SyntaxKind::WITH_KW, + SyntaxKind::WITHIN_KW, + SyntaxKind::WITHOUT_KW, + SyntaxKind::WORK_KW, + SyntaxKind::WRAPPER_KW, + SyntaxKind::WRITE_KW, + SyntaxKind::XML_KW, + SyntaxKind::XMLATTRIBUTES_KW, + SyntaxKind::XMLCONCAT_KW, + SyntaxKind::XMLELEMENT_KW, + SyntaxKind::XMLEXISTS_KW, + SyntaxKind::XMLFOREST_KW, + SyntaxKind::XMLNAMESPACES_KW, + SyntaxKind::XMLPARSE_KW, + SyntaxKind::XMLPI_KW, + SyntaxKind::XMLROOT_KW, + SyntaxKind::XMLSERIALIZE_KW, + SyntaxKind::XMLTABLE_KW, + SyntaxKind::YEAR_KW, + SyntaxKind::YES_KW, + SyntaxKind::ZONE_KW, +]); + +pub(crate) const BARE_LABEL_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ABORT_KW, + SyntaxKind::ABSENT_KW, + SyntaxKind::ABSOLUTE_KW, + SyntaxKind::ACCESS_KW, + SyntaxKind::ACTION_KW, + SyntaxKind::ADD_KW, + SyntaxKind::ADMIN_KW, + SyntaxKind::AFTER_KW, + SyntaxKind::AGGREGATE_KW, + SyntaxKind::ALL_KW, + SyntaxKind::ALSO_KW, + SyntaxKind::ALTER_KW, + SyntaxKind::ALWAYS_KW, + SyntaxKind::ANALYSE_KW, + SyntaxKind::ANALYZE_KW, + SyntaxKind::AND_KW, + SyntaxKind::ANY_KW, + SyntaxKind::ASC_KW, + SyntaxKind::ASENSITIVE_KW, + SyntaxKind::ASSERTION_KW, + SyntaxKind::ASSIGNMENT_KW, + SyntaxKind::ASYMMETRIC_KW, + SyntaxKind::AT_KW, + SyntaxKind::ATOMIC_KW, + SyntaxKind::ATTACH_KW, + SyntaxKind::ATTRIBUTE_KW, + SyntaxKind::AUTHORIZATION_KW, + SyntaxKind::BACKWARD_KW, + SyntaxKind::BEFORE_KW, + SyntaxKind::BEGIN_KW, + SyntaxKind::BETWEEN_KW, + SyntaxKind::BIGINT_KW, + SyntaxKind::BINARY_KW, + SyntaxKind::BIT_KW, + SyntaxKind::BOOLEAN_KW, + SyntaxKind::BOTH_KW, + SyntaxKind::BREADTH_KW, + SyntaxKind::BY_KW, + SyntaxKind::CACHE_KW, + SyntaxKind::CALL_KW, + SyntaxKind::CALLED_KW, + SyntaxKind::CASCADE_KW, + SyntaxKind::CASCADED_KW, + SyntaxKind::CASE_KW, + SyntaxKind::CAST_KW, + SyntaxKind::CATALOG_KW, + SyntaxKind::CHAIN_KW, + SyntaxKind::CHARACTERISTICS_KW, + SyntaxKind::CHECK_KW, + SyntaxKind::CHECKPOINT_KW, + SyntaxKind::CLASS_KW, + SyntaxKind::CLOSE_KW, + SyntaxKind::CLUSTER_KW, + SyntaxKind::COALESCE_KW, + SyntaxKind::COLLATE_KW, + SyntaxKind::COLLATION_KW, + SyntaxKind::COLUMN_KW, + SyntaxKind::COLUMNS_KW, + SyntaxKind::COMMENT_KW, + SyntaxKind::COMMENTS_KW, + SyntaxKind::COMMIT_KW, + SyntaxKind::COMMITTED_KW, + SyntaxKind::COMPRESSION_KW, + SyntaxKind::CONCURRENTLY_KW, + SyntaxKind::CONDITIONAL_KW, + SyntaxKind::CONFIGURATION_KW, + SyntaxKind::CONFLICT_KW, + SyntaxKind::CONNECTION_KW, + SyntaxKind::CONSTRAINT_KW, + SyntaxKind::CONSTRAINTS_KW, + SyntaxKind::CONTENT_KW, + SyntaxKind::CONTINUE_KW, + SyntaxKind::CONVERSION_KW, + SyntaxKind::COPY_KW, + SyntaxKind::COST_KW, + SyntaxKind::CROSS_KW, + SyntaxKind::CSV_KW, + SyntaxKind::CUBE_KW, + SyntaxKind::CURRENT_KW, + SyntaxKind::CURRENT_CATALOG_KW, + SyntaxKind::CURRENT_DATE_KW, + SyntaxKind::CURRENT_ROLE_KW, + SyntaxKind::CURRENT_SCHEMA_KW, + SyntaxKind::CURRENT_TIME_KW, + SyntaxKind::CURRENT_TIMESTAMP_KW, + SyntaxKind::CURRENT_USER_KW, + SyntaxKind::CURSOR_KW, + SyntaxKind::CYCLE_KW, + SyntaxKind::DATA_KW, + SyntaxKind::DATABASE_KW, + SyntaxKind::DEALLOCATE_KW, + SyntaxKind::DEC_KW, + SyntaxKind::DECIMAL_KW, + SyntaxKind::DECLARE_KW, + SyntaxKind::DEFAULT_KW, + SyntaxKind::DEFAULTS_KW, + SyntaxKind::DEFERRABLE_KW, + SyntaxKind::DEFERRED_KW, + SyntaxKind::DEFINER_KW, + SyntaxKind::DELETE_KW, + SyntaxKind::DELIMITER_KW, + SyntaxKind::DELIMITERS_KW, + SyntaxKind::DEPENDS_KW, + SyntaxKind::DEPTH_KW, + SyntaxKind::DESC_KW, + SyntaxKind::DETACH_KW, + SyntaxKind::DICTIONARY_KW, + SyntaxKind::DISABLE_KW, + SyntaxKind::DISCARD_KW, + SyntaxKind::DISTINCT_KW, + SyntaxKind::DO_KW, + SyntaxKind::DOCUMENT_KW, + SyntaxKind::DOMAIN_KW, + SyntaxKind::DOUBLE_KW, + SyntaxKind::DROP_KW, + SyntaxKind::EACH_KW, + SyntaxKind::ELSE_KW, + SyntaxKind::EMPTY_KW, + SyntaxKind::ENABLE_KW, + SyntaxKind::ENCODING_KW, + SyntaxKind::ENCRYPTED_KW, + SyntaxKind::END_KW, + SyntaxKind::ENUM_KW, + SyntaxKind::ERROR_KW, + SyntaxKind::ESCAPE_KW, + SyntaxKind::EVENT_KW, + SyntaxKind::EXCLUDE_KW, + SyntaxKind::EXCLUDING_KW, + SyntaxKind::EXCLUSIVE_KW, + SyntaxKind::EXECUTE_KW, + SyntaxKind::EXISTS_KW, + SyntaxKind::EXPLAIN_KW, + SyntaxKind::EXPRESSION_KW, + SyntaxKind::EXTENSION_KW, + SyntaxKind::EXTERNAL_KW, + SyntaxKind::EXTRACT_KW, + SyntaxKind::FALSE_KW, + SyntaxKind::FAMILY_KW, + SyntaxKind::FINALIZE_KW, + SyntaxKind::FIRST_KW, + SyntaxKind::FLOAT_KW, + SyntaxKind::FOLLOWING_KW, + SyntaxKind::FORCE_KW, + SyntaxKind::FOREIGN_KW, + SyntaxKind::FORMAT_KW, + SyntaxKind::FORWARD_KW, + SyntaxKind::FREEZE_KW, + SyntaxKind::FULL_KW, + SyntaxKind::FUNCTION_KW, + SyntaxKind::FUNCTIONS_KW, + SyntaxKind::GENERATED_KW, + SyntaxKind::GLOBAL_KW, + SyntaxKind::GRANTED_KW, + SyntaxKind::GREATEST_KW, + SyntaxKind::GROUPING_KW, + SyntaxKind::GROUPS_KW, + SyntaxKind::HANDLER_KW, + SyntaxKind::HEADER_KW, + SyntaxKind::HOLD_KW, + SyntaxKind::IDENTITY_KW, + SyntaxKind::IF_KW, + SyntaxKind::ILIKE_KW, + SyntaxKind::IMMEDIATE_KW, + SyntaxKind::IMMUTABLE_KW, + SyntaxKind::IMPLICIT_KW, + SyntaxKind::IMPORT_KW, + SyntaxKind::IN_KW, + SyntaxKind::INCLUDE_KW, + SyntaxKind::INCLUDING_KW, + SyntaxKind::INCREMENT_KW, + SyntaxKind::INDENT_KW, + SyntaxKind::INDEX_KW, + SyntaxKind::INDEXES_KW, + SyntaxKind::INHERIT_KW, + SyntaxKind::INHERITS_KW, + SyntaxKind::INITIALLY_KW, + SyntaxKind::INLINE_KW, + SyntaxKind::INNER_KW, + SyntaxKind::INOUT_KW, + SyntaxKind::INPUT_KW, + SyntaxKind::INSENSITIVE_KW, + SyntaxKind::INSERT_KW, + SyntaxKind::INSTEAD_KW, + SyntaxKind::INT_KW, + SyntaxKind::INTEGER_KW, + SyntaxKind::INTERVAL_KW, + SyntaxKind::INVOKER_KW, + SyntaxKind::IS_KW, + SyntaxKind::ISOLATION_KW, + SyntaxKind::JOIN_KW, + SyntaxKind::JSON_KW, + SyntaxKind::JSON_ARRAY_KW, + SyntaxKind::JSON_ARRAYAGG_KW, + SyntaxKind::JSON_EXISTS_KW, + SyntaxKind::JSON_OBJECT_KW, + SyntaxKind::JSON_OBJECTAGG_KW, + SyntaxKind::JSON_QUERY_KW, + SyntaxKind::JSON_SCALAR_KW, + SyntaxKind::JSON_SERIALIZE_KW, + SyntaxKind::JSON_TABLE_KW, + SyntaxKind::JSON_VALUE_KW, + SyntaxKind::KEEP_KW, + SyntaxKind::KEY_KW, + SyntaxKind::KEYS_KW, + SyntaxKind::LABEL_KW, + SyntaxKind::LANGUAGE_KW, + SyntaxKind::LARGE_KW, + SyntaxKind::LAST_KW, + SyntaxKind::LATERAL_KW, + SyntaxKind::LEADING_KW, + SyntaxKind::LEAKPROOF_KW, + SyntaxKind::LEAST_KW, + SyntaxKind::LEFT_KW, + SyntaxKind::LEVEL_KW, + SyntaxKind::LIKE_KW, + SyntaxKind::LISTEN_KW, + SyntaxKind::LOAD_KW, + SyntaxKind::LOCAL_KW, + SyntaxKind::LOCALTIME_KW, + SyntaxKind::LOCALTIMESTAMP_KW, + SyntaxKind::LOCATION_KW, + SyntaxKind::LOCK_KW, + SyntaxKind::LOCKED_KW, + SyntaxKind::LOGGED_KW, + SyntaxKind::MAPPING_KW, + SyntaxKind::MATCH_KW, + SyntaxKind::MATCHED_KW, + SyntaxKind::MATERIALIZED_KW, + SyntaxKind::MAXVALUE_KW, + SyntaxKind::MERGE_KW, + SyntaxKind::MERGE_ACTION_KW, + SyntaxKind::METHOD_KW, + SyntaxKind::MINVALUE_KW, + SyntaxKind::MODE_KW, + SyntaxKind::MOVE_KW, + SyntaxKind::NAME_KW, + SyntaxKind::NAMES_KW, + SyntaxKind::NATIONAL_KW, + SyntaxKind::NATURAL_KW, + SyntaxKind::NCHAR_KW, + SyntaxKind::NESTED_KW, + SyntaxKind::NEW_KW, + SyntaxKind::NEXT_KW, + SyntaxKind::NFC_KW, + SyntaxKind::NFD_KW, + SyntaxKind::NFKC_KW, + SyntaxKind::NFKD_KW, + SyntaxKind::NO_KW, + SyntaxKind::NONE_KW, + SyntaxKind::NORMALIZE_KW, + SyntaxKind::NORMALIZED_KW, + SyntaxKind::NOT_KW, + SyntaxKind::NOTHING_KW, + SyntaxKind::NOTIFY_KW, + SyntaxKind::NOWAIT_KW, + SyntaxKind::NULL_KW, + SyntaxKind::NULLIF_KW, + SyntaxKind::NULLS_KW, + SyntaxKind::NUMERIC_KW, + SyntaxKind::OBJECT_KW, + SyntaxKind::OF_KW, + SyntaxKind::OFF_KW, + SyntaxKind::OIDS_KW, + SyntaxKind::OLD_KW, + SyntaxKind::OMIT_KW, + SyntaxKind::ONLY_KW, + SyntaxKind::OPERATOR_KW, + SyntaxKind::OPTION_KW, + SyntaxKind::OPTIONS_KW, + SyntaxKind::OR_KW, + SyntaxKind::ORDINALITY_KW, + SyntaxKind::OTHERS_KW, + SyntaxKind::OUT_KW, + SyntaxKind::OUTER_KW, + SyntaxKind::OVERLAY_KW, + SyntaxKind::OVERRIDING_KW, + SyntaxKind::OWNED_KW, + SyntaxKind::OWNER_KW, + SyntaxKind::PARALLEL_KW, + SyntaxKind::PARAMETER_KW, + SyntaxKind::PARSER_KW, + SyntaxKind::PARTIAL_KW, + SyntaxKind::PARTITION_KW, + SyntaxKind::PASSING_KW, + SyntaxKind::PASSWORD_KW, + SyntaxKind::PATH_KW, + SyntaxKind::PERIOD_KW, + SyntaxKind::PLACING_KW, + SyntaxKind::PLAN_KW, + SyntaxKind::PLANS_KW, + SyntaxKind::POLICY_KW, + SyntaxKind::POSITION_KW, + SyntaxKind::PRECEDING_KW, + SyntaxKind::PREPARE_KW, + SyntaxKind::PREPARED_KW, + SyntaxKind::PRESERVE_KW, + SyntaxKind::PRIMARY_KW, + SyntaxKind::PRIOR_KW, + SyntaxKind::PRIVILEGES_KW, + SyntaxKind::PROCEDURAL_KW, + SyntaxKind::PROCEDURE_KW, + SyntaxKind::PROCEDURES_KW, + SyntaxKind::PROGRAM_KW, + SyntaxKind::PUBLICATION_KW, + SyntaxKind::QUOTE_KW, + SyntaxKind::QUOTES_KW, + SyntaxKind::RANGE_KW, + SyntaxKind::READ_KW, + SyntaxKind::REAL_KW, + SyntaxKind::REASSIGN_KW, + SyntaxKind::RECURSIVE_KW, + SyntaxKind::REF_KW, + SyntaxKind::REFERENCES_KW, + SyntaxKind::REFERENCING_KW, + SyntaxKind::REFRESH_KW, + SyntaxKind::REINDEX_KW, + SyntaxKind::RELATIVE_KW, + SyntaxKind::RELEASE_KW, + SyntaxKind::RENAME_KW, + SyntaxKind::REPEATABLE_KW, + SyntaxKind::REPLACE_KW, + SyntaxKind::REPLICA_KW, + SyntaxKind::RESET_KW, + SyntaxKind::RESTART_KW, + SyntaxKind::RESTRICT_KW, + SyntaxKind::RETURN_KW, + SyntaxKind::RETURNS_KW, + SyntaxKind::REVOKE_KW, + SyntaxKind::RIGHT_KW, + SyntaxKind::ROLE_KW, + SyntaxKind::ROLLBACK_KW, + SyntaxKind::ROLLUP_KW, + SyntaxKind::ROUTINE_KW, + SyntaxKind::ROUTINES_KW, + SyntaxKind::ROW_KW, + SyntaxKind::ROWS_KW, + SyntaxKind::RULE_KW, + SyntaxKind::SAVEPOINT_KW, + SyntaxKind::SCALAR_KW, + SyntaxKind::SCHEMA_KW, + SyntaxKind::SCHEMAS_KW, + SyntaxKind::SCROLL_KW, + SyntaxKind::SEARCH_KW, + SyntaxKind::SECURITY_KW, + SyntaxKind::SELECT_KW, + SyntaxKind::SEQUENCE_KW, + SyntaxKind::SEQUENCES_KW, + SyntaxKind::SERIALIZABLE_KW, + SyntaxKind::SERVER_KW, + SyntaxKind::SESSION_KW, + SyntaxKind::SESSION_USER_KW, + SyntaxKind::SET_KW, + SyntaxKind::SETOF_KW, + SyntaxKind::SETS_KW, + SyntaxKind::SHARE_KW, + SyntaxKind::SHOW_KW, + SyntaxKind::SIMILAR_KW, + SyntaxKind::SIMPLE_KW, + SyntaxKind::SKIP_KW, + SyntaxKind::SMALLINT_KW, + SyntaxKind::SNAPSHOT_KW, + SyntaxKind::SOME_KW, + SyntaxKind::SOURCE_KW, + SyntaxKind::SQL_KW, + SyntaxKind::STABLE_KW, + SyntaxKind::STANDALONE_KW, + SyntaxKind::START_KW, + SyntaxKind::STATEMENT_KW, + SyntaxKind::STATISTICS_KW, + SyntaxKind::STDIN_KW, + SyntaxKind::STDOUT_KW, + SyntaxKind::STORAGE_KW, + SyntaxKind::STORED_KW, + SyntaxKind::STRICT_KW, + SyntaxKind::STRING_KW, + SyntaxKind::STRIP_KW, + SyntaxKind::SUBSCRIPTION_KW, + SyntaxKind::SUBSTRING_KW, + SyntaxKind::SUPPORT_KW, + SyntaxKind::SYMMETRIC_KW, + SyntaxKind::SYSID_KW, + SyntaxKind::SYSTEM_KW, + SyntaxKind::SYSTEM_USER_KW, + SyntaxKind::TABLE_KW, + SyntaxKind::TABLES_KW, + SyntaxKind::TABLESAMPLE_KW, + SyntaxKind::TABLESPACE_KW, + SyntaxKind::TARGET_KW, + SyntaxKind::TEMP_KW, + SyntaxKind::TEMPLATE_KW, + SyntaxKind::TEMPORARY_KW, + SyntaxKind::TEXT_KW, + SyntaxKind::THEN_KW, + SyntaxKind::TIES_KW, + SyntaxKind::TIME_KW, + SyntaxKind::TIMESTAMP_KW, + SyntaxKind::TRAILING_KW, + SyntaxKind::TRANSACTION_KW, + SyntaxKind::TRANSFORM_KW, + SyntaxKind::TREAT_KW, + SyntaxKind::TRIGGER_KW, + SyntaxKind::TRIM_KW, + SyntaxKind::TRUE_KW, + SyntaxKind::TRUNCATE_KW, + SyntaxKind::TRUSTED_KW, + SyntaxKind::TYPE_KW, + SyntaxKind::TYPES_KW, + SyntaxKind::UESCAPE_KW, + SyntaxKind::UNBOUNDED_KW, + SyntaxKind::UNCOMMITTED_KW, + SyntaxKind::UNCONDITIONAL_KW, + SyntaxKind::UNENCRYPTED_KW, + SyntaxKind::UNIQUE_KW, + SyntaxKind::UNKNOWN_KW, + SyntaxKind::UNLISTEN_KW, + SyntaxKind::UNLOGGED_KW, + SyntaxKind::UNTIL_KW, + SyntaxKind::UPDATE_KW, + SyntaxKind::USER_KW, + SyntaxKind::USING_KW, + SyntaxKind::VACUUM_KW, + SyntaxKind::VALID_KW, + SyntaxKind::VALIDATE_KW, + SyntaxKind::VALIDATOR_KW, + SyntaxKind::VALUE_KW, + SyntaxKind::VALUES_KW, + SyntaxKind::VARCHAR_KW, + SyntaxKind::VARIADIC_KW, + SyntaxKind::VERBOSE_KW, + SyntaxKind::VERSION_KW, + SyntaxKind::VIEW_KW, + SyntaxKind::VIEWS_KW, + SyntaxKind::VOLATILE_KW, + SyntaxKind::WHEN_KW, + SyntaxKind::WHITESPACE_KW, + SyntaxKind::WORK_KW, + SyntaxKind::WRAPPER_KW, + SyntaxKind::WRITE_KW, + SyntaxKind::XML_KW, + SyntaxKind::XMLATTRIBUTES_KW, + SyntaxKind::XMLCONCAT_KW, + SyntaxKind::XMLELEMENT_KW, + SyntaxKind::XMLEXISTS_KW, + SyntaxKind::XMLFOREST_KW, + SyntaxKind::XMLNAMESPACES_KW, + SyntaxKind::XMLPARSE_KW, + SyntaxKind::XMLPI_KW, + SyntaxKind::XMLROOT_KW, + SyntaxKind::XMLSERIALIZE_KW, + SyntaxKind::XMLTABLE_KW, + SyntaxKind::YES_KW, + SyntaxKind::ZONE_KW, +]); + +pub(crate) const UNRESERVED_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ABORT_KW, + SyntaxKind::ABSENT_KW, + SyntaxKind::ABSOLUTE_KW, + SyntaxKind::ACCESS_KW, + SyntaxKind::ACTION_KW, + SyntaxKind::ADD_KW, + SyntaxKind::ADMIN_KW, + SyntaxKind::AFTER_KW, + SyntaxKind::AGGREGATE_KW, + SyntaxKind::ALSO_KW, + SyntaxKind::ALTER_KW, + SyntaxKind::ALWAYS_KW, + SyntaxKind::ASENSITIVE_KW, + SyntaxKind::ASSERTION_KW, + SyntaxKind::ASSIGNMENT_KW, + SyntaxKind::AT_KW, + SyntaxKind::ATOMIC_KW, + SyntaxKind::ATTACH_KW, + SyntaxKind::ATTRIBUTE_KW, + SyntaxKind::BACKWARD_KW, + SyntaxKind::BEFORE_KW, + SyntaxKind::BEGIN_KW, + SyntaxKind::BREADTH_KW, + SyntaxKind::BY_KW, + SyntaxKind::CACHE_KW, + SyntaxKind::CALL_KW, + SyntaxKind::CALLED_KW, + SyntaxKind::CASCADE_KW, + SyntaxKind::CASCADED_KW, + SyntaxKind::CATALOG_KW, + SyntaxKind::CHAIN_KW, + SyntaxKind::CHARACTERISTICS_KW, + SyntaxKind::CHECKPOINT_KW, + SyntaxKind::CLASS_KW, + SyntaxKind::CLOSE_KW, + SyntaxKind::CLUSTER_KW, + SyntaxKind::COLUMNS_KW, + SyntaxKind::COMMENT_KW, + SyntaxKind::COMMENTS_KW, + SyntaxKind::COMMIT_KW, + SyntaxKind::COMMITTED_KW, + SyntaxKind::COMPRESSION_KW, + SyntaxKind::CONDITIONAL_KW, + SyntaxKind::CONFIGURATION_KW, + SyntaxKind::CONFLICT_KW, + SyntaxKind::CONNECTION_KW, + SyntaxKind::CONSTRAINTS_KW, + SyntaxKind::CONTENT_KW, + SyntaxKind::CONTINUE_KW, + SyntaxKind::CONVERSION_KW, + SyntaxKind::COPY_KW, + SyntaxKind::COST_KW, + SyntaxKind::CSV_KW, + SyntaxKind::CUBE_KW, + SyntaxKind::CURRENT_KW, + SyntaxKind::CURSOR_KW, + SyntaxKind::CYCLE_KW, + SyntaxKind::DATA_KW, + SyntaxKind::DATABASE_KW, + SyntaxKind::DAY_KW, + SyntaxKind::DEALLOCATE_KW, + SyntaxKind::DECLARE_KW, + SyntaxKind::DEFAULTS_KW, + SyntaxKind::DEFERRED_KW, + SyntaxKind::DEFINER_KW, + SyntaxKind::DELETE_KW, + SyntaxKind::DELIMITER_KW, + SyntaxKind::DELIMITERS_KW, + SyntaxKind::DEPENDS_KW, + SyntaxKind::DEPTH_KW, + SyntaxKind::DETACH_KW, + SyntaxKind::DICTIONARY_KW, + SyntaxKind::DISABLE_KW, + SyntaxKind::DISCARD_KW, + SyntaxKind::DOCUMENT_KW, + SyntaxKind::DOMAIN_KW, + SyntaxKind::DOUBLE_KW, + SyntaxKind::DROP_KW, + SyntaxKind::EACH_KW, + SyntaxKind::EMPTY_KW, + SyntaxKind::ENABLE_KW, + SyntaxKind::ENCODING_KW, + SyntaxKind::ENCRYPTED_KW, + SyntaxKind::ENUM_KW, + SyntaxKind::ERROR_KW, + SyntaxKind::ESCAPE_KW, + SyntaxKind::EVENT_KW, + SyntaxKind::EXCLUDE_KW, + SyntaxKind::EXCLUDING_KW, + SyntaxKind::EXCLUSIVE_KW, + SyntaxKind::EXECUTE_KW, + SyntaxKind::EXPLAIN_KW, + SyntaxKind::EXPRESSION_KW, + SyntaxKind::EXTENSION_KW, + SyntaxKind::EXTERNAL_KW, + SyntaxKind::FAMILY_KW, + SyntaxKind::FILTER_KW, + SyntaxKind::FINALIZE_KW, + SyntaxKind::FIRST_KW, + SyntaxKind::FOLLOWING_KW, + SyntaxKind::FORCE_KW, + SyntaxKind::FORMAT_KW, + SyntaxKind::FORWARD_KW, + SyntaxKind::FUNCTION_KW, + SyntaxKind::FUNCTIONS_KW, + SyntaxKind::GENERATED_KW, + SyntaxKind::GLOBAL_KW, + SyntaxKind::GRANTED_KW, + SyntaxKind::GROUPS_KW, + SyntaxKind::HANDLER_KW, + SyntaxKind::HEADER_KW, + SyntaxKind::HOLD_KW, + SyntaxKind::HOUR_KW, + SyntaxKind::IDENTITY_KW, + SyntaxKind::IF_KW, + SyntaxKind::IMMEDIATE_KW, + SyntaxKind::IMMUTABLE_KW, + SyntaxKind::IMPLICIT_KW, + SyntaxKind::IMPORT_KW, + SyntaxKind::INCLUDE_KW, + SyntaxKind::INCLUDING_KW, + SyntaxKind::INCREMENT_KW, + SyntaxKind::INDENT_KW, + SyntaxKind::INDEX_KW, + SyntaxKind::INDEXES_KW, + SyntaxKind::INHERIT_KW, + SyntaxKind::INHERITS_KW, + SyntaxKind::INLINE_KW, + SyntaxKind::INPUT_KW, + SyntaxKind::INSENSITIVE_KW, + SyntaxKind::INSERT_KW, + SyntaxKind::INSTEAD_KW, + SyntaxKind::INVOKER_KW, + SyntaxKind::ISOLATION_KW, + SyntaxKind::KEEP_KW, + SyntaxKind::KEY_KW, + SyntaxKind::KEYS_KW, + SyntaxKind::LABEL_KW, + SyntaxKind::LANGUAGE_KW, + SyntaxKind::LARGE_KW, + SyntaxKind::LAST_KW, + SyntaxKind::LEAKPROOF_KW, + SyntaxKind::LEVEL_KW, + SyntaxKind::LISTEN_KW, + SyntaxKind::LOAD_KW, + SyntaxKind::LOCAL_KW, + SyntaxKind::LOCATION_KW, + SyntaxKind::LOCK_KW, + SyntaxKind::LOCKED_KW, + SyntaxKind::LOGGED_KW, + SyntaxKind::MAPPING_KW, + SyntaxKind::MATCH_KW, + SyntaxKind::MATCHED_KW, + SyntaxKind::MATERIALIZED_KW, + SyntaxKind::MAXVALUE_KW, + SyntaxKind::MERGE_KW, + SyntaxKind::METHOD_KW, + SyntaxKind::MINUTE_KW, + SyntaxKind::MINVALUE_KW, + SyntaxKind::MODE_KW, + SyntaxKind::MONTH_KW, + SyntaxKind::MOVE_KW, + SyntaxKind::NAME_KW, + SyntaxKind::NAMES_KW, + SyntaxKind::NESTED_KW, + SyntaxKind::NEW_KW, + SyntaxKind::NEXT_KW, + SyntaxKind::NFC_KW, + SyntaxKind::NFD_KW, + SyntaxKind::NFKC_KW, + SyntaxKind::NFKD_KW, + SyntaxKind::NO_KW, + SyntaxKind::NORMALIZED_KW, + SyntaxKind::NOTHING_KW, + SyntaxKind::NOTIFY_KW, + SyntaxKind::NOWAIT_KW, + SyntaxKind::NULLS_KW, + SyntaxKind::OBJECT_KW, + SyntaxKind::OF_KW, + SyntaxKind::OFF_KW, + SyntaxKind::OIDS_KW, + SyntaxKind::OLD_KW, + SyntaxKind::OMIT_KW, + SyntaxKind::OPERATOR_KW, + SyntaxKind::OPTION_KW, + SyntaxKind::OPTIONS_KW, + SyntaxKind::ORDINALITY_KW, + SyntaxKind::OTHERS_KW, + SyntaxKind::OVER_KW, + SyntaxKind::OVERRIDING_KW, + SyntaxKind::OWNED_KW, + SyntaxKind::OWNER_KW, + SyntaxKind::PARALLEL_KW, + SyntaxKind::PARAMETER_KW, + SyntaxKind::PARSER_KW, + SyntaxKind::PARTIAL_KW, + SyntaxKind::PARTITION_KW, + SyntaxKind::PASSING_KW, + SyntaxKind::PASSWORD_KW, + SyntaxKind::PATH_KW, + SyntaxKind::PERIOD_KW, + SyntaxKind::PLAN_KW, + SyntaxKind::PLANS_KW, + SyntaxKind::POLICY_KW, + SyntaxKind::PRECEDING_KW, + SyntaxKind::PREPARE_KW, + SyntaxKind::PREPARED_KW, + SyntaxKind::PRESERVE_KW, + SyntaxKind::PRIOR_KW, + SyntaxKind::PRIVILEGES_KW, + SyntaxKind::PROCEDURAL_KW, + SyntaxKind::PROCEDURE_KW, + SyntaxKind::PROCEDURES_KW, + SyntaxKind::PROGRAM_KW, + SyntaxKind::PUBLICATION_KW, + SyntaxKind::QUOTE_KW, + SyntaxKind::QUOTES_KW, + SyntaxKind::RANGE_KW, + SyntaxKind::READ_KW, + SyntaxKind::REASSIGN_KW, + SyntaxKind::RECURSIVE_KW, + SyntaxKind::REF_KW, + SyntaxKind::REFERENCING_KW, + SyntaxKind::REFRESH_KW, + SyntaxKind::REINDEX_KW, + SyntaxKind::RELATIVE_KW, + SyntaxKind::RELEASE_KW, + SyntaxKind::RENAME_KW, + SyntaxKind::REPEATABLE_KW, + SyntaxKind::REPLACE_KW, + SyntaxKind::REPLICA_KW, + SyntaxKind::RESET_KW, + SyntaxKind::RESTART_KW, + SyntaxKind::RESTRICT_KW, + SyntaxKind::RETURN_KW, + SyntaxKind::RETURNS_KW, + SyntaxKind::REVOKE_KW, + SyntaxKind::ROLE_KW, + SyntaxKind::ROLLBACK_KW, + SyntaxKind::ROLLUP_KW, + SyntaxKind::ROUTINE_KW, + SyntaxKind::ROUTINES_KW, + SyntaxKind::ROWS_KW, + SyntaxKind::RULE_KW, + SyntaxKind::SAVEPOINT_KW, + SyntaxKind::SCALAR_KW, + SyntaxKind::SCHEMA_KW, + SyntaxKind::SCHEMAS_KW, + SyntaxKind::SCROLL_KW, + SyntaxKind::SEARCH_KW, + SyntaxKind::SECOND_KW, + SyntaxKind::SECURITY_KW, + SyntaxKind::SEQUENCE_KW, + SyntaxKind::SEQUENCES_KW, + SyntaxKind::SERIALIZABLE_KW, + SyntaxKind::SERVER_KW, + SyntaxKind::SESSION_KW, + SyntaxKind::SET_KW, + SyntaxKind::SETS_KW, + SyntaxKind::SHARE_KW, + SyntaxKind::SHOW_KW, + SyntaxKind::SIMPLE_KW, + SyntaxKind::SKIP_KW, + SyntaxKind::SNAPSHOT_KW, + SyntaxKind::SOURCE_KW, + SyntaxKind::SQL_KW, + SyntaxKind::STABLE_KW, + SyntaxKind::STANDALONE_KW, + SyntaxKind::START_KW, + SyntaxKind::STATEMENT_KW, + SyntaxKind::STATISTICS_KW, + SyntaxKind::STDIN_KW, + SyntaxKind::STDOUT_KW, + SyntaxKind::STORAGE_KW, + SyntaxKind::STORED_KW, + SyntaxKind::STRICT_KW, + SyntaxKind::STRING_KW, + SyntaxKind::STRIP_KW, + SyntaxKind::SUBSCRIPTION_KW, + SyntaxKind::SUPPORT_KW, + SyntaxKind::SYSID_KW, + SyntaxKind::SYSTEM_KW, + SyntaxKind::TABLES_KW, + SyntaxKind::TABLESPACE_KW, + SyntaxKind::TARGET_KW, + SyntaxKind::TEMP_KW, + SyntaxKind::TEMPLATE_KW, + SyntaxKind::TEMPORARY_KW, + SyntaxKind::TEXT_KW, + SyntaxKind::TIES_KW, + SyntaxKind::TRANSACTION_KW, + SyntaxKind::TRANSFORM_KW, + SyntaxKind::TRIGGER_KW, + SyntaxKind::TRUNCATE_KW, + SyntaxKind::TRUSTED_KW, + SyntaxKind::TYPE_KW, + SyntaxKind::TYPES_KW, + SyntaxKind::UESCAPE_KW, + SyntaxKind::UNBOUNDED_KW, + SyntaxKind::UNCOMMITTED_KW, + SyntaxKind::UNCONDITIONAL_KW, + SyntaxKind::UNENCRYPTED_KW, + SyntaxKind::UNKNOWN_KW, + SyntaxKind::UNLISTEN_KW, + SyntaxKind::UNLOGGED_KW, + SyntaxKind::UNTIL_KW, + SyntaxKind::UPDATE_KW, + SyntaxKind::VACUUM_KW, + SyntaxKind::VALID_KW, + SyntaxKind::VALIDATE_KW, + SyntaxKind::VALIDATOR_KW, + SyntaxKind::VALUE_KW, + SyntaxKind::VARYING_KW, + SyntaxKind::VERSION_KW, + SyntaxKind::VIEW_KW, + SyntaxKind::VIEWS_KW, + SyntaxKind::VOLATILE_KW, + SyntaxKind::WHITESPACE_KW, + SyntaxKind::WITHIN_KW, + SyntaxKind::WITHOUT_KW, + SyntaxKind::WORK_KW, + SyntaxKind::WRAPPER_KW, + SyntaxKind::WRITE_KW, + SyntaxKind::XML_KW, + SyntaxKind::YEAR_KW, + SyntaxKind::YES_KW, + SyntaxKind::ZONE_KW, +]); + +pub(crate) const RESERVED_KEYWORDS: TokenSet = TokenSet::new(&[ + SyntaxKind::ALL_KW, + SyntaxKind::ANALYSE_KW, + SyntaxKind::ANALYZE_KW, + SyntaxKind::AND_KW, + SyntaxKind::ANY_KW, + SyntaxKind::ARRAY_KW, + SyntaxKind::AS_KW, + SyntaxKind::ASC_KW, + SyntaxKind::ASYMMETRIC_KW, + SyntaxKind::BOTH_KW, + SyntaxKind::CASE_KW, + SyntaxKind::CAST_KW, + SyntaxKind::CHECK_KW, + SyntaxKind::COLLATE_KW, + SyntaxKind::COLUMN_KW, + SyntaxKind::CONSTRAINT_KW, + SyntaxKind::CREATE_KW, + SyntaxKind::CURRENT_CATALOG_KW, + SyntaxKind::CURRENT_DATE_KW, + SyntaxKind::CURRENT_ROLE_KW, + SyntaxKind::CURRENT_TIME_KW, + SyntaxKind::CURRENT_TIMESTAMP_KW, + SyntaxKind::CURRENT_USER_KW, + SyntaxKind::DEFAULT_KW, + SyntaxKind::DEFERRABLE_KW, + SyntaxKind::DESC_KW, + SyntaxKind::DISTINCT_KW, + SyntaxKind::DO_KW, + SyntaxKind::ELSE_KW, + SyntaxKind::END_KW, + SyntaxKind::EXCEPT_KW, + SyntaxKind::FALSE_KW, + SyntaxKind::FETCH_KW, + SyntaxKind::FOR_KW, + SyntaxKind::FOREIGN_KW, + SyntaxKind::FROM_KW, + SyntaxKind::GRANT_KW, + SyntaxKind::GROUP_KW, + SyntaxKind::HAVING_KW, + SyntaxKind::IN_KW, + SyntaxKind::INITIALLY_KW, + SyntaxKind::INTERSECT_KW, + SyntaxKind::INTO_KW, + SyntaxKind::LATERAL_KW, + SyntaxKind::LEADING_KW, + SyntaxKind::LIMIT_KW, + SyntaxKind::LOCALTIME_KW, + SyntaxKind::LOCALTIMESTAMP_KW, + SyntaxKind::NOT_KW, + SyntaxKind::NULL_KW, + SyntaxKind::OFFSET_KW, + SyntaxKind::ON_KW, + SyntaxKind::ONLY_KW, + SyntaxKind::OR_KW, + SyntaxKind::ORDER_KW, + SyntaxKind::PLACING_KW, + SyntaxKind::PRIMARY_KW, + SyntaxKind::REFERENCES_KW, + SyntaxKind::RETURNING_KW, + SyntaxKind::SELECT_KW, + SyntaxKind::SESSION_USER_KW, + SyntaxKind::SOME_KW, + SyntaxKind::SYMMETRIC_KW, + SyntaxKind::SYSTEM_USER_KW, + SyntaxKind::TABLE_KW, + SyntaxKind::THEN_KW, + SyntaxKind::TO_KW, + SyntaxKind::TRAILING_KW, + SyntaxKind::TRUE_KW, + SyntaxKind::UNION_KW, + SyntaxKind::UNIQUE_KW, + SyntaxKind::USER_KW, + SyntaxKind::USING_KW, + SyntaxKind::VARIADIC_KW, + SyntaxKind::WHEN_KW, + SyntaxKind::WHERE_KW, + SyntaxKind::WINDOW_KW, + SyntaxKind::WITH_KW, +]); + +// Generated TokenSet end diff --git a/crates/squawk_parser/src/test.rs b/crates/squawk_parser/src/test.rs new file mode 100644 index 00000000..918e9968 --- /dev/null +++ b/crates/squawk_parser/src/test.rs @@ -0,0 +1,116 @@ +// based on https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/tests.rs +use camino::Utf8Path; +use dir_test::{dir_test, Fixture}; +use insta::{assert_snapshot, with_settings}; +use std::fmt::Write; + +use crate::{parse, LexedStr}; + +fn parse_text(text: &str) -> (String, bool) { + let lexed = LexedStr::new(text); + let input = lexed.to_input(); + let output = parse(&input); + + let mut buf = String::new(); + let mut errors = Vec::new(); + let mut indent = String::new(); + let mut depth = 0; + let mut len = 0; + lexed.intersperse_trivia(&output, &mut |step| match step { + crate::StrStep::Token { kind, text } => { + assert!(depth > 0); + len += text.len(); + writeln!(buf, "{indent}{kind:?} {text:?}").unwrap(); + } + crate::StrStep::Enter { kind } => { + assert!(depth > 0 || len == 0); + depth += 1; + writeln!(buf, "{indent}{kind:?}").unwrap(); + indent.push_str(" "); + } + crate::StrStep::Exit => { + assert!(depth > 0); + depth -= 1; + indent.pop(); + indent.pop(); + } + crate::StrStep::Error { msg, pos } => { + assert!(depth > 0); + let err = "ERROR"; + errors.push(format!("{err}@{pos}: {msg}\n")); + } + }); + assert_eq!( + len, + text.len(), + "didn't parse all text.\nParsed:\n{}\n\nAll:\n{}\n", + &text[..len], + text + ); + + for (token, msg) in lexed.errors() { + let pos = lexed.text_start(token); + let err = "ERROR"; + errors.push(format!("{err}@{pos}: {msg}\n")); + } + + let has_errors = !errors.is_empty(); + if has_errors { + buf.push_str("---\n"); + for e in errors { + buf.push_str(&e); + } + } + (buf, has_errors) +} + +#[dir_test( + dir: "$CARGO_MANIFEST_DIR/test_data", + glob: "**/*.sql", +)] +fn sqltest(fixture: Fixture<&str>) { + let content = fixture.content(); + let absolute_fixture_path = Utf8Path::new(fixture.path()); + let input_file = absolute_fixture_path; + let test_name = absolute_fixture_path + .file_name() + .and_then(|x| x.strip_suffix(".sql")) + .unwrap(); + + let parent_dir = input_file.parent().and_then(|x| x.file_name()).unwrap(); + + let (parsed, has_errors) = parse_text(&content); + + with_settings!({ + omit_expression => true, + input_file => input_file, + }, { + assert_snapshot!(format!("{}_{}", test_name, parent_dir), parsed); + }); + + if parent_dir == "ok" { + // We check that all of our tests in `ok` also pass the Postgres parser, + // if they don't, they should be moved to the `err` directory. + assert!( + !has_errors, + "tests defined in the `ok` can't have parser errors." + ); + // skipping pg17 specific stuff since our parser isn't using the latest parser + if !test_name.ends_with("pg17") { + let pg_result = pg_query::parse(&content); + if let Err(e) = &pg_result { + assert!( + &pg_result.is_ok(), + "tests defined in the `ok` can't have Postgres parser errors. Found {}", + e.to_string() + ); + } + } + } else { + assert_eq!(parent_dir, "err"); + assert!( + has_errors, + "tests defined in the `err` directory must have parser errors." + ); + } +} diff --git a/crates/squawk_parser/src/token_set.rs b/crates/squawk_parser/src/token_set.rs new file mode 100644 index 00000000..1708211a --- /dev/null +++ b/crates/squawk_parser/src/token_set.rs @@ -0,0 +1,93 @@ +// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/token_set.rs +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//! A bit-set of `SyntaxKind`s. + +use crate::SyntaxKind; + +/// A bit-set of `SyntaxKind`s +#[derive(Clone, Copy)] +pub(crate) struct TokenSet([u64; 10]); + +/// `TokenSet`s should only include token `SyntaxKind`s, so the discriminant of any passed/included +/// `SyntaxKind` must *not* be greater than that of the last token `SyntaxKind`. +/// See . +const LAST_TOKEN_KIND_DISCRIMINANT: usize = SyntaxKind::WHITESPACE as usize; + +impl TokenSet { + pub(crate) const EMPTY: TokenSet = TokenSet([0; 10]); + + pub(crate) const fn new(kinds: &[SyntaxKind]) -> TokenSet { + let mut res = [0; 10]; + let mut i = 0; + while i < kinds.len() { + let discriminant = kinds[i] as usize; + debug_assert!( + discriminant <= LAST_TOKEN_KIND_DISCRIMINANT, + "Expected a token `SyntaxKind`" + ); + let idx = discriminant / 64; + res[idx] |= 1 << (discriminant % 64); + i += 1; + } + TokenSet(res) + } + + pub(crate) const fn union(self, other: TokenSet) -> TokenSet { + TokenSet([ + self.0[0] | other.0[0], + self.0[1] | other.0[1], + self.0[2] | other.0[2], + self.0[3] | other.0[3], + self.0[4] | other.0[4], + self.0[5] | other.0[5], + self.0[6] | other.0[6], + self.0[7] | other.0[7], + self.0[8] | other.0[8], + self.0[9] | other.0[9], + ]) + } + + pub(crate) const fn contains(&self, kind: SyntaxKind) -> bool { + let discriminant = kind as usize; + debug_assert!( + discriminant <= LAST_TOKEN_KIND_DISCRIMINANT, + "Expected a token `SyntaxKind`" + ); + let idx = discriminant / 64; + let mask = 1 << (discriminant % 64); + self.0[idx] & mask != 0 + } +} + +#[test] +fn token_set_works_for_tokens() { + use crate::SyntaxKind::*; + let ts = TokenSet::new(&[EOF, WHITESPACE]); + assert!(ts.contains(EOF)); + assert!(ts.contains(WHITESPACE)); + assert!(!ts.contains(PLUS)); +} diff --git a/crates/squawk_parser/test_data/err/alter_foreign_data_wrapper.sql b/crates/squawk_parser/test_data/err/alter_foreign_data_wrapper.sql new file mode 100644 index 00000000..07e1f5ad --- /dev/null +++ b/crates/squawk_parser/test_data/err/alter_foreign_data_wrapper.sql @@ -0,0 +1,2 @@ +-- missing option +alter foreign data wrapper w; diff --git a/crates/squawk_parser/test_data/err/alter_sequence.sql b/crates/squawk_parser/test_data/err/alter_sequence.sql new file mode 100644 index 00000000..12b0b799 --- /dev/null +++ b/crates/squawk_parser/test_data/err/alter_sequence.sql @@ -0,0 +1,2 @@ +-- missing option +alter sequence s; diff --git a/crates/squawk_parser/test_data/err/alter_server.sql b/crates/squawk_parser/test_data/err/alter_server.sql new file mode 100644 index 00000000..47fb2081 --- /dev/null +++ b/crates/squawk_parser/test_data/err/alter_server.sql @@ -0,0 +1,2 @@ +-- missing option +alter server s; diff --git a/crates/squawk_parser/test_data/err/alter_table.sql b/crates/squawk_parser/test_data/err/alter_table.sql new file mode 100644 index 00000000..57f76934 --- /dev/null +++ b/crates/squawk_parser/test_data/err/alter_table.sql @@ -0,0 +1,8 @@ +-- missing alter_table +add column foo boolean; + +-- mismatch options +alter table t alter constraint c not deferrable initially deferred; + +-- pg 18 only, via: https://www.depesz.com/2025/05/01/waiting-for-postgresql-18-allow-not-null-constraints-to-be-added-as-not-valid/ +alter table public.copy_2 add constraint id_not_null not null id not valid; diff --git a/crates/squawk_parser/test_data/err/create_function.sql b/crates/squawk_parser/test_data/err/create_function.sql new file mode 100644 index 00000000..77b38476 --- /dev/null +++ b/crates/squawk_parser/test_data/err/create_function.sql @@ -0,0 +1,2 @@ +-- regression partial definition +create function diff --git a/crates/squawk_parser/test_data/err/create_table.sql b/crates/squawk_parser/test_data/err/create_table.sql new file mode 100644 index 00000000..bfa68540 --- /dev/null +++ b/crates/squawk_parser/test_data/err/create_table.sql @@ -0,0 +1,47 @@ +-- with missing table name +create table ( + sensor_id INTEGER +); + +-- missing type +create table t (a); + +-- trailing comma +create table t (a text,); + +-- missing columns / constraints +create table t (,,,,,); + +-- a column list with SET DEFAULT is only supported for ON DELETE actions +create table t ( + a int, + b int references bar on update cascade, + c int references bar on update set null, + d int references bar on update set default, + e int references bar on update set default (a, b, c) +); + +-- conflicting options +create unlogged table t ( + a int generated always as identity, + b int generated always as identity ( + as bigint + cache 100 + increment by 10 + increment 10 + sequence name foo + restart with 500 + logged + unlogged + start with 10 + start 25 + owned by none + owned by fooo.bar + maxvalue 70 + minvalue 150 + no minvalue + no cycle + no maxvalue + cycle + ) +); diff --git a/crates/squawk_parser/test_data/err/insert.sql b/crates/squawk_parser/test_data/err/insert.sql new file mode 100644 index 00000000..02ee076e --- /dev/null +++ b/crates/squawk_parser/test_data/err/insert.sql @@ -0,0 +1,14 @@ +-- missing comma in column list +insert into t (a, b c) + values (1, 2, 3) + on conflict do nothing; + +-- missing column in column list & trailing comma +insert into t (a,,c,) + values (1, 2, 3) + on conflict do nothing; + +-- missing comma in values & trailing comma +insert into t (a, b, c) + values (4, 5 6,) + on conflict do nothing; diff --git a/crates/squawk_parser/test_data/err/select.sql b/crates/squawk_parser/test_data/err/select.sql new file mode 100644 index 00000000..7350c21a --- /dev/null +++ b/crates/squawk_parser/test_data/err/select.sql @@ -0,0 +1,26 @@ +--- via https://duckdb.org/docs/stable/sql/dialect/friendly_sql.html#trailing-commas +select + 42 as x, + array['a', 'b', 'c',] as y, + 'hello world' as z, +; + +-- trailing comma in column list +select * from t as u(a,); + +-- missing comma +select a, b c d, e from t; +-- ^ ^ comma missing +-- \-- this is a label + +-- trailing comma in args +select f(1,); + +-- missing args +select f(a,,,,,); + +-- in can only be used with tuples / sub queries +select 1 in c; + +-- trailing comma at EOF +select 1, diff --git a/crates/squawk_parser/test_data/err/select_cte.sql b/crates/squawk_parser/test_data/err/select_cte.sql new file mode 100644 index 00000000..dcb7c7e4 --- /dev/null +++ b/crates/squawk_parser/test_data/err/select_cte.sql @@ -0,0 +1,4 @@ +with t as ( + select 1 +), -- <--- extra comma! +select * from t; diff --git a/crates/squawk_parser/test_data/err/values.sql b/crates/squawk_parser/test_data/err/values.sql new file mode 100644 index 00000000..2de39b4c --- /dev/null +++ b/crates/squawk_parser/test_data/err/values.sql @@ -0,0 +1,6 @@ + +-- trailing comma and missing comma between value lists +values (1,) (1); + +-- extra comma, aka missing tuple +values (1),, (2); diff --git a/crates/squawk_parser/test_data/ok/alter_aggregate.sql b/crates/squawk_parser/test_data/ok/alter_aggregate.sql new file mode 100644 index 00000000..2c7bcd98 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_aggregate.sql @@ -0,0 +1,18 @@ +-- star +alter aggregate a (*) rename to b; + +-- simple_args +alter aggregate a (t) set schema s; + +-- complex_args +alter aggregate a (in x text, y numeric) + owner to current_user; + +-- with_order_by +alter aggregate a (x order by y) + rename to b; + +-- qualified_names +alter aggregate foo.bar (in t, u) + set schema new_schema; + diff --git a/crates/squawk_parser/test_data/ok/alter_collation.sql b/crates/squawk_parser/test_data/ok/alter_collation.sql new file mode 100644 index 00000000..7b542e7f --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_collation.sql @@ -0,0 +1,18 @@ +-- refresh +alter collation c + refresh version; + +-- rename +alter collation c + rename to d; + +-- owner +alter collation c + owner to u; +alter collation s.c + owner to current_role; + +-- set_schema +alter collation c + set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_conversion.sql b/crates/squawk_parser/test_data/ok/alter_conversion.sql new file mode 100644 index 00000000..1cb48a3c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_conversion.sql @@ -0,0 +1,13 @@ +-- rename +alter conversion c rename to n; + +-- owner +alter conversion c owner to u; +alter conversion c owner to current_user; + +-- set_schema +alter conversion c set schema s; + +-- qualified_name +alter conversion a.c set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_database.sql b/crates/squawk_parser/test_data/ok/alter_database.sql new file mode 100644 index 00000000..ee728df6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_database.sql @@ -0,0 +1,35 @@ +-- rename +alter database d rename to n; + +-- owner +alter database d owner to u; +alter database d owner to current_user; + +-- tablespace +alter database d set tablespace t; + +-- refresh +alter database d refresh collation version; + +-- set_param +alter database d set p to v; +alter database d set p = v; +alter database d set p = default; +alter database d set p from current; + +-- reset +alter database d reset p; +alter database d reset all; + +-- with_option +alter database d with allow_connections true; + +-- option_connection_limit +alter database d connection limit 10; + +-- option_is_template +alter database d is_template false; + +-- with_multiple_options +alter database d with allow_connections true connection limit 10 is_template false; + diff --git a/crates/squawk_parser/test_data/ok/alter_default_privileges.sql b/crates/squawk_parser/test_data/ok/alter_default_privileges.sql new file mode 100644 index 00000000..f18b2356 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_default_privileges.sql @@ -0,0 +1,201 @@ +-- simple +alter default privileges + grant select + on tables + to r; + +-- full +alter default privileges + for role r, current_user + in schema s, s2, s3 + grant select + on tables + to r; + +alter default privileges + for user session_user + in schema s + grant select + on tables + to r; + +-- grant_tables +alter default privileges + grant select + on tables + to group r; + +alter default privileges + grant insert + on tables + to group r; + +alter default privileges + grant update + on tables + to public, current_user, group session_user + with grant option; + +alter default privileges + grant delete + on tables + to r; + +alter default privileges + grant truncate + on tables + to r; + +alter default privileges + grant references + on tables + to r; + +alter default privileges + grant trigger + on tables + to r; + +alter default privileges + grant maintain + on tables + to r; + +alter default privileges + grant select, insert, update, delete, truncate, references, trigger, maintain + on tables + to r; + +alter default privileges + grant all + on tables + to r; + +alter default privileges + grant all privileges + on tables + to r; + +-- grant_sequences +alter default privileges + grant usage, select, update + on sequences + to u, group current_user, group session_user, group current_role + with grant option; + +alter default privileges + grant usage + on sequences + to r; + +-- grant_functions +alter default privileges + grant execute + on functions + to u; + +alter default privileges + grant all + on routines + to r; + +alter default privileges + grant all privileges + on routines + to r + with grant option; + +-- grant_types +alter default privileges + grant usage + on types + to r; + +alter default privileges + grant all privileges + on types + to r, group u, public + with grant option; + +-- grant_schemas +alter default privileges + grant usage, create + on schemas + to r; + +alter default privileges + grant all privileges + on schemas + to r, group u, public + with grant option; + +-- revoke_tables +alter default privileges + revoke grant option for + select, insert, update, delete, truncate, references, trigger, maintain + on tables + from r, group current_user + cascade; + +alter default privileges + revoke select + on tables + from r + restrict; + +-- revoke_sequences +alter default privileges + revoke grant option for + usage, select, update + on sequences + from r, group current_user + cascade; + +alter default privileges + revoke select + on sequences + from r + restrict; + +-- revoke_functions +alter default privileges + revoke grant option for + execute + on functions + from r, group current_user + cascade; + +alter default privileges + revoke all privileges + on routines + from r + restrict; + +-- revoke_types +alter default privileges + revoke grant option for + usage + on types + from r, group current_user + cascade; + +alter default privileges + revoke all privileges + on types + from r + restrict; + +-- revoke_schemas +alter default privileges + revoke grant option for + usage, create + on schemas + from r, group current_user + cascade; + +alter default privileges + revoke all privileges + on schemas + from r + restrict; + diff --git a/crates/squawk_parser/test_data/ok/alter_domain.sql b/crates/squawk_parser/test_data/ok/alter_domain.sql new file mode 100644 index 00000000..97bc9f6d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_domain.sql @@ -0,0 +1,52 @@ +-- set_default +alter domain d + set default 42; + +-- drop_default +alter domain foo.d + drop default; + +-- set_not_null +alter domain d + set not null; + +-- drop_not_null +alter domain d + drop not null; + +-- add_constraint +alter domain d + add constraint c check (value > 0); +alter domain d + add check (value > 0) not valid; +alter domain d + add constraint a check (a > b); + +-- drop_constraint +alter domain d + drop constraint c cascade; +alter domain d + drop constraint if exists c restrict; + +-- rename_constraint +alter domain d + rename constraint c to n; + +-- validate_constraint +alter domain d + validate constraint c; + +-- owner_to +alter domain d + owner to u; +alter domain d + owner to current_user; + +-- rename_to +alter domain d + rename to n; + +-- set_schema +alter domain d + set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_event_trigger.sql b/crates/squawk_parser/test_data/ok/alter_event_trigger.sql new file mode 100644 index 00000000..d46c118b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_event_trigger.sql @@ -0,0 +1,21 @@ +-- disable +alter event trigger t disable; + +-- enable +alter event trigger t enable; + +-- enable_replica +alter event trigger t enable replica; + +-- enable_always +alter event trigger t enable always; + +-- owner +alter event trigger t owner to u; + +-- owner_current_role +alter event trigger t owner to current_role; + +-- rename +alter event trigger t rename to u; + diff --git a/crates/squawk_parser/test_data/ok/alter_extension.sql b/crates/squawk_parser/test_data/ok/alter_extension.sql new file mode 100644 index 00000000..a3a5b4f6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_extension.sql @@ -0,0 +1,184 @@ +-- update_to +alter extension e update; +alter extension e update to json; +alter extension e update to 'foo'; + +-- schema +alter extension e set schema s; + +-- add_drop_access_method +alter extension e add access method o; +alter extension e drop access method o; + +-- add_drop_aggregate +alter extension e add aggregate a ( in a text order by b, c ); +alter extension e drop aggregate a (*); + +-- add_drop_cast +alter extension e add cast (bigint as text); +alter extension e drop cast (varchar(100) as smallint); + +-- add_drop_collation +alter extension e add collation o; +alter extension e add collation s.o; +alter extension e drop collation o; +alter extension e drop collation s.o; + +-- add_drop_conversion +alter extension e add conversion o; +alter extension e add conversion s.o; +alter extension e drop conversion o; +alter extension e drop conversion s.o; + +-- add_drop_domain +alter extension e add domain o; +alter extension e drop domain o; + +-- add_drop_event_trigger +alter extension e add event trigger o; +alter extension e drop event trigger o; + +-- add_drop_foreign_data_wrapper +alter extension e add foreign data wrapper o; +alter extension e drop foreign data wrapper o; + +-- add_drop_foreign_table +alter extension e add foreign table o; +alter extension e add foreign table s.o; +alter extension e drop foreign table o; +alter extension e drop foreign table s.o; + +-- add_drop_function +alter extension e add function f; +alter extension e add function s.f(in varchar(100), bigint); +alter extension e drop function f; +alter extension e drop function s.f(in a text, out b varchar(100)); + +-- add_drop_materialized_view +alter extension e add materialized view o; +alter extension e add materialized view s.o; +alter extension e drop materialized view o; +alter extension e drop materialized view s.o; + +-- add_drop_operator +alter extension e add operator << (t, varchar(100)); +alter extension e drop operator >> (u, varchar(100)); + +-- add_drop_operator_class +alter extension e add operator class o using i; +alter extension e drop operator class o using i; + +-- add_drop_operator_family +alter extension e add operator family o using i; +alter extension e drop operator family o using i; + +-- add_drop_language +alter extension e add language o; +alter extension e add procedural language o; +alter extension e drop language o; +alter extension e drop procedural language o; + +-- add_drop_procedure +alter extension e add procedure f; +alter extension e add procedure s.f(in varchar(100), bigint); +alter extension e drop procedure f; +alter extension e drop procedure s.f(in a text, out b varchar(100)); + +-- add_drop_routine +alter extension e add routine f; +alter extension e add routine s.f(in varchar(100), bigint); +alter extension e drop routine f; +alter extension e drop routine s.f(in a text, out b varchar(100)); + +-- add_drop_sequence +alter extension e add sequence o; +alter extension e add sequence s.o; +alter extension e drop sequence o; +alter extension e drop sequence s.o; + +-- add_drop_table +alter extension e add table o; +alter extension e drop table o; + +-- add_drop_text_search_configuration +alter extension e add text search configuration o; +alter extension e add text search configuration s.o; +alter extension e drop text search configuration o; +alter extension e drop text search configuration s.o; + +-- add_drop_text_search_dictionary +alter extension e add text search dictionary o; +alter extension e add text search dictionary s.o; +alter extension e drop text search dictionary o; +alter extension e drop text search dictionary s.o; + +-- add_drop_text_search_parser +alter extension e add text search parser o; +alter extension e add text search parser s.o; +alter extension e drop text search parser o; +alter extension e drop text search parser s.o; + +-- add_drop_text_search_template +alter extension e add text search template o; +alter extension e add text search template s.o; +alter extension e drop text search template o; +alter extension e drop text search template s.o; + +-- add_drop_transform +alter extension e add transform for type_name language l; +alter extension e drop transform for type_name language l; + +-- add_drop_type +alter extension e add type o; +alter extension e drop type o; + +-- add_drop_view +alter extension e add view o; +alter extension e add view s.o; +alter extension e drop view o; +alter extension e drop view s.o; + +-- add_drop_extension +alter extension e add extension o; +alter extension e drop extension o; + +-- add_drop_publication +alter extension e add publication o; +alter extension e drop publication o; + +-- add_drop_schema +alter extension e add schema o; +alter extension e drop schema o; + +-- add_drop_server +alter extension e add server o; +alter extension e drop server o; + +-- add_drop_database +alter extension e add database o; +alter extension e drop database o; + +-- add_drop_index +alter extension e add index o; +alter extension e add index s.o; +alter extension e drop index o; +alter extension e drop index s.o; + +-- add_drop_statistics +alter extension e add statistics o; +alter extension e add statistics s.o; +alter extension e drop statistics o; +alter extension e drop statistics s.o; + +-- add_drop_role +alter extension e add role o; +alter extension e drop role o; + +-- add_drop_subscription +alter extension e add subscription o; +alter extension e drop subscription o; + +-- add_drop_tablespace +alter extension e add tablespace o; +alter extension e drop tablespace o; + diff --git a/crates/squawk_parser/test_data/ok/alter_foreign_data_wrapper.sql b/crates/squawk_parser/test_data/ok/alter_foreign_data_wrapper.sql new file mode 100644 index 00000000..e8bb38f2 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_foreign_data_wrapper.sql @@ -0,0 +1,36 @@ +-- handler +alter foreign data wrapper w + handler h; + +-- no_handler +alter foreign data wrapper w + no handler; + +-- validator +alter foreign data wrapper w + validator v; + +-- no_validator +alter foreign data wrapper w + no validator; + +-- options +alter foreign data wrapper w + options (add o 'v', set o 'v', drop o); + +-- multiple +alter foreign data wrapper w + handler s.h + no handler + validator s.v + no validator + options (add o 'v', set o '', drop d); + +-- owner +alter foreign data wrapper w + owner to u; + +-- rename +alter foreign data wrapper w + rename to n; + diff --git a/crates/squawk_parser/test_data/ok/alter_foreign_table.sql b/crates/squawk_parser/test_data/ok/alter_foreign_table.sql new file mode 100644 index 00000000..ca542e98 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_foreign_table.sql @@ -0,0 +1,182 @@ +-- rename +alter foreign table t + rename to u; + +-- only_and_asterisk +alter foreign table only t + rename to u; + +alter foreign table t * + rename to u; + +-- rename_column +alter foreign table t + rename column c to d; + +alter foreign table t + rename c to d; + +-- set_schema +alter foreign table f.t + set schema s; + +-- action_add_column +alter foreign table t + add column c int; + +alter foreign table t + add c int collate "fr_FR" not null check (a > 10); + +-- action_drop_column +alter foreign table t + drop c cascade; + +alter foreign table t + drop column if exists c cascade; + +alter foreign table t + drop column if exists c restrict; + +-- action_column_type +alter foreign table t + alter column c type int; + +alter foreign table t + alter column c set data type int collate "fr_FR"; + +-- action_set_default +alter foreign table t + alter column c set default 10 * 10; + +alter foreign table t + alter c set default 10 * 10; + +-- action_drop_default +alter foreign table t + alter column c drop default; + +alter foreign table t + alter c drop default; + +-- action_not_null +alter foreign table t + alter column c drop not null; + +alter foreign table t + alter c set not null; + +-- action_set_statistics +alter foreign table t + alter column c set statistics 1; + +alter foreign table t + alter c set statistics 1; + +-- action_set +alter foreign table t + alter column c set (a, b = 1); + +alter foreign table t + alter c set (a, b = 1); + +-- action_reset +alter foreign table t + alter column c reset (a, b); + +alter foreign table t + alter c reset (a); + +-- action_set_storage +alter foreign table t + alter column c set storage plain; + +alter foreign table t + alter c set storage external; + +alter foreign table t + alter c set storage extended; + +alter foreign table t + alter c set storage main; + +alter foreign table t + alter c set storage default; + +-- action_options +alter foreign table t + alter column c options(b '', add c 'c', set x '', drop x); + +alter foreign table t + alter c options(set x ''); + +-- action_add_table_constraint +alter foreign table t + add constraint c check (a > b) not valid; + +alter foreign table t + add constraint c check (a > b); + +-- action_validate_constraint +alter foreign table t + validate constraint c; + +-- action_drop_constraint +alter foreign table t + drop constraint if exists c restrict; + +alter foreign table t + drop constraint c cascade; + +-- action_disable_trigger +alter foreign table t + disable trigger t; + +alter foreign table t + disable trigger all; + +alter foreign table t + disable trigger user; + +-- action_enable_replica_trigger +alter foreign table t + enable replica trigger t; + +-- action_enable_always_trigger +alter foreign table t + enable always trigger t; + +-- action_set_without_oids +alter foreign table t + set without oids; + +-- action_inherit +alter foreign table t + inherit u; + +alter foreign table s.t + inherit s.u; + +-- action_no_inherit +alter foreign table t + no inherit u; + +alter foreign table s.t + no inherit s.u; + +-- action_owner_to +alter foreign table t + owner to u; + +alter foreign table t + owner to current_user; + +-- multiple_actions +alter foreign table t + add column c int, + drop column d cascade, + alter column e set not null; + +-- action_owner +alter foreign table if exists t + owner to u; + diff --git a/crates/squawk_parser/test_data/ok/alter_function.sql b/crates/squawk_parser/test_data/ok/alter_function.sql new file mode 100644 index 00000000..a6dc8403 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_function.sql @@ -0,0 +1,48 @@ +-- simple +alter function f stable; + +-- rename +alter function f rename to g; +alter function s.f rename to g; + +-- action_with_params +alter function f(int, text) strict; + +-- owner +alter function f owner to current_user; + +-- schema +alter function f set schema s; + +-- multiple_actions +alter function f + called on null input + returns null on null input + strict + immutable + stable + volatile + not leakproof + leakproof + external security invoker + security invoker + external security definer + security definer + parallel unsafe + parallel restricted + parallel safe + cost 100 + rows 10 + support f + set c to 1 + set c = 1 + set c = default + set c from current + reset c + reset all + restrict; + +-- depends +alter function f depends on extension e; +alter function f no depends on extension e; + diff --git a/crates/squawk_parser/test_data/ok/alter_group.sql b/crates/squawk_parser/test_data/ok/alter_group.sql new file mode 100644 index 00000000..5d6a6e01 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_group.sql @@ -0,0 +1,24 @@ +-- add +alter group g add user u; + +-- add_multiple +alter group g add user u, v, w; + +-- drop +alter group g drop user u; + +-- drop_multiple +alter group g drop user u, v, w; + +-- rename +alter group g rename to n; + +-- current_role +alter group current_role add user u; + +-- current_user +alter group current_user drop user u; + +-- session_user +alter group session_user add user u; + diff --git a/crates/squawk_parser/test_data/ok/alter_index.sql b/crates/squawk_parser/test_data/ok/alter_index.sql new file mode 100644 index 00000000..586b77e3 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_index.sql @@ -0,0 +1,36 @@ +-- rename +alter index i rename to j; +alter index if exists s.i rename to j; + +-- set_tablespace +alter index i set tablespace t; +alter index if exists s.i set tablespace t; + +-- set_params +alter index i set (a); +alter index if exists s.i set (a=1, b='v'); + +-- reset_params +alter index i reset (a); +alter index if exists s.i reset (a, b); + +-- attach +alter index i attach partition p; +alter index s.i attach partition s.p; + +-- depends +alter index i no depends on extension e; +alter index s.i depends on extension e; + +-- alter_column +alter index i alter 1 set statistics 100; +alter index if exists s.i alter column 1 set statistics 100; + +-- all_tablespace +alter index all in tablespace t + set tablespace n; +alter index all in tablespace t + owned by r, s + set tablespace n + nowait; + diff --git a/crates/squawk_parser/test_data/ok/alter_language.sql b/crates/squawk_parser/test_data/ok/alter_language.sql new file mode 100644 index 00000000..02c6f189 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_language.sql @@ -0,0 +1,8 @@ +-- rename +alter language x rename to y; +alter procedural language x rename to y; + +-- owner +alter language x owner to u; +alter procedural language x owner to current_user; + diff --git a/crates/squawk_parser/test_data/ok/alter_large_object.sql b/crates/squawk_parser/test_data/ok/alter_large_object.sql new file mode 100644 index 00000000..83b12388 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_large_object.sql @@ -0,0 +1,6 @@ +-- simple +alter large object 12345 owner to u; + +-- current_role +alter large object 12345 owner to current_role; + diff --git a/crates/squawk_parser/test_data/ok/alter_materialized_view.sql b/crates/squawk_parser/test_data/ok/alter_materialized_view.sql new file mode 100644 index 00000000..03a10aa9 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_materialized_view.sql @@ -0,0 +1,77 @@ +-- rename_view +alter materialized view v rename to n; +alter materialized view if exists s.v rename to n; + +-- rename_column +alter materialized view v + rename c to n; +alter materialized view if exists s.v + rename column c to n; + +-- set_schema +alter materialized view v set schema s; +alter materialized view if exists v set schema s; + +-- depends_extension +alter materialized view v depends on extension e; +alter materialized view v no depends on extension e; + +-- set_tablespace +alter materialized view all in tablespace t + set tablespace n; +alter materialized view all in tablespace t + owned by current_user, u + set tablespace n nowait; + +-- action_alter_col_stats +alter materialized view v + alter c set statistics 100; + +alter materialized view v + alter column c set statistics -1; + +alter materialized view v + alter column c set statistics default; + +-- action_alter_col_set +alter materialized view v + alter column c set (n_distinct = 1.0); + +alter materialized view v + alter c set (a = true, b = 1); + +-- action_alter_col_reset +alter materialized view v alter c reset (n_distinct); +alter materialized view v alter column c reset (n_distinct, n_distinct_inherited); + +-- action_alter_col_storage +alter materialized view v + alter c set storage plain; + +alter materialized view v + alter c set storage external; + +alter materialized view v + alter c set storage extended; + +alter materialized view v + alter c set storage main; + +alter materialized view s.v + alter c set storage default; + +-- action_alter_col_compression +alter materialized view v + alter c set compression pglz; + +alter materialized view v + alter column c set compression pglz; + +-- action_cluster +alter materialized view v + cluster on i; + +-- action_set_without_cluster +alter materialized view v + set without cluster; + diff --git a/crates/squawk_parser/test_data/ok/alter_operator.sql b/crates/squawk_parser/test_data/ok/alter_operator.sql new file mode 100644 index 00000000..b1931b95 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_operator.sql @@ -0,0 +1,23 @@ +-- owner +alter operator p.+ (int4, int4) + owner to u; + +-- schema +alter operator + (none, text) + set schema s; + +-- options +alter operator & (bool, bool) + set ( + restrict = r, + join = j, + commutator = c, + negator = n, + hashes = enabled, + merges = enabled + ); + +-- none_options +alter operator % (int, int) + set (restrict = none, join = none); + diff --git a/crates/squawk_parser/test_data/ok/alter_operator_class.sql b/crates/squawk_parser/test_data/ok/alter_operator_class.sql new file mode 100644 index 00000000..c24a897e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_operator_class.sql @@ -0,0 +1,18 @@ +-- rename +alter operator class c using m + rename to n; + +alter operator class s.c using m + rename to n; + +-- owner +alter operator class c using m + owner to u; + +alter operator class c using m + owner to current_user; + +-- schema +alter operator class c using m + set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_operator_family.sql b/crates/squawk_parser/test_data/ok/alter_operator_family.sql new file mode 100644 index 00000000..b6b0036a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_operator_family.sql @@ -0,0 +1,62 @@ +-- simple +alter operator family f using i add + operator 1 < (t, u); + +-- multi +alter operator family f using i add + operator 1 && (t, u), + function 1 f, + function 1 (t) f(in a text), + function 1 (t, varchar(100)) f; + +-- add_op_for_search +alter operator family f using i add + operator 1 > (t, u) for search; + +-- add_op_for_order +alter operator family f using i add + operator 1 > (t, u) for order by s; + +-- add_func +alter operator family f using i add + function 1 f(t); + +-- add_func_with_params +alter operator family f using i add + function 1 (t, u) f(a, b); + +-- drop_op +alter operator family f using i drop + operator 1 (t, u); + +-- drop_op_single_param +alter operator family f using i drop + operator 1 (t); + +-- drop_func +alter operator family f using i drop + function 1 (t, u); + +-- drop_func_single_param +alter operator family f using i drop + function 1 (t); + +-- drop_multiple +alter operator family f using i drop + operator 1 (t, u), + function 2 (t); + +-- rename +alter operator family f using i + rename to n; + +-- owner +alter operator family f using i + owner to u; +alter operator family f using i + owner to current_user; + +-- schema +alter operator family foo.f using i + set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_policy.sql b/crates/squawk_parser/test_data/ok/alter_policy.sql new file mode 100644 index 00000000..7bea23c5 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_policy.sql @@ -0,0 +1,26 @@ +-- rename +alter policy p on t + rename to q; + +-- to_role +alter policy p on t + to r; + +-- to_multiple_roles +alter policy p on t + to r, public, current_user; + +-- using_expr +alter policy p on t + using (a = b); + +-- with_check +alter policy p on t + with check (c > d); + +-- full +alter policy p on t + to r, s + using (a = b) + with check (c > d); + diff --git a/crates/squawk_parser/test_data/ok/alter_procedure.sql b/crates/squawk_parser/test_data/ok/alter_procedure.sql new file mode 100644 index 00000000..ddc17934 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_procedure.sql @@ -0,0 +1,55 @@ +-- rename +alter procedure p + rename to q; +alter procedure foo.p(int, text) + rename to q; + +-- owner +alter procedure p + owner to u; +alter procedure p + owner to current_user; + +-- set_schema +alter procedure p + set schema s; + +-- security +alter procedure p + security invoker + external security invoker + security definer + external security definer + restrict; + +-- actions +alter procedure p + security invoker + set c = 1 + set d from current + reset z + reset all + restrict; + +-- set_param +alter procedure p + set c to v; +alter procedure p + set c = v; +alter procedure p + set c = default; +alter procedure p + set c from current; + +-- reset_param +alter procedure p + reset c; +alter procedure p + reset all; + +-- depends +alter procedure p + depends on extension e; +alter procedure p + no depends on extension e; + diff --git a/crates/squawk_parser/test_data/ok/alter_publication.sql b/crates/squawk_parser/test_data/ok/alter_publication.sql new file mode 100644 index 00000000..864b222d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_publication.sql @@ -0,0 +1,26 @@ +-- add_table +alter publication p add table t; +alter publication p add table t1, table t2 where (a > b), table only t, table t (a, b); + +-- add_tables_in_schema +alter publication p add tables in schema s; +alter publication p add tables in schema current_schema; + +-- set_table +alter publication p set table t; +alter publication p set table t1, table t2 where (a > b), table only t, table t (a, b); + +-- set_parameters +alter publication p set (param1, param2 = value); + +-- drop_table +alter publication p drop table t; +alter publication p drop table t1, table t2 where (a > b), table only t, table t (a, b); + +-- owner_to +alter publication p owner to u; +alter publication p owner to current_user; + +-- rename +alter publication p rename to q; + diff --git a/crates/squawk_parser/test_data/ok/alter_role.sql b/crates/squawk_parser/test_data/ok/alter_role.sql new file mode 100644 index 00000000..4aa0247e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_role.sql @@ -0,0 +1,51 @@ +-- with_options +alter role r with superuser; + +-- all_options +alter role r + with superuser + nosuperuser + nosuperuser + createdb + nocreatedb + createrole + nocreaterole + inherit + noinherit + login + nologin + replication + noreplication + bypassrls + nobypassrls + connection limit 100 + encrypted password 'foo' + password 'bar' password null + valid until '2042-02-22'; + +-- rename +alter role r rename to newname; + +-- set_config +alter role r set param = 'value'; +alter role r set param to 'value'; +alter role r set param to default; + +-- set_config_from_current +alter role r set param from current; + +-- reset_config +alter role r reset param; + +-- reset_all +alter role r reset all; + +-- in_database +alter role r in database d set param to 'value'; + +-- using_current_user +alter role current_user with nologin; + +-- for_all_roles +alter role all reset all; + diff --git a/crates/squawk_parser/test_data/ok/alter_routine.sql b/crates/squawk_parser/test_data/ok/alter_routine.sql new file mode 100644 index 00000000..870c0dbe --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_routine.sql @@ -0,0 +1,54 @@ +-- simple +alter routine r + stable; + +-- rename +alter routine r + rename to n; + +-- owner +alter routine r + owner to current_user; + +-- schema +alter routine r + set schema s; + +-- depends +alter routine r + depends on extension e; + +alter routine r + no depends on extension e; + +-- no_depends +alter routine r + no depends on extension e; + +-- with_params +alter routine f(in a text, out b int) + parallel safe; + +-- all_actions +alter routine r + immutable + stable + volatile + not leakproof + leakproof + external security invoker + security invoker + security definer + external security definer + parallel unsafe + parallel restricted + parallel safe + cost 10 + rows 10 + set c = 1 + set c = default + set c to true + reset c + reset all + restrict; + diff --git a/crates/squawk_parser/test_data/ok/alter_rule.sql b/crates/squawk_parser/test_data/ok/alter_rule.sql new file mode 100644 index 00000000..74dbbd7f --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_rule.sql @@ -0,0 +1,6 @@ +-- simple +alter rule r on t rename to n; + +-- with_schema +alter rule r on schema.t rename to n; + diff --git a/crates/squawk_parser/test_data/ok/alter_schema.sql b/crates/squawk_parser/test_data/ok/alter_schema.sql new file mode 100644 index 00000000..036be79a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_schema.sql @@ -0,0 +1,7 @@ +-- rename +alter schema s rename to n; + +-- owner +alter schema s owner to u; +alter schema s owner to current_user; + diff --git a/crates/squawk_parser/test_data/ok/alter_sequence.sql b/crates/squawk_parser/test_data/ok/alter_sequence.sql new file mode 100644 index 00000000..4406dba4 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_sequence.sql @@ -0,0 +1,41 @@ +-- full +alter sequence if exists foo.s + as varchar(100) + increment by 2 + minvalue 1 + no minvalue + maxvalue 100 + no maxvalue + start 10 + start with 10 + restart + restart 10 + restart with 10 + cache 10 + no cycle + cycle + owned by foo.c + owned by none; + +-- set_logged +alter sequence s + set logged; + +alter sequence s + set unlogged; + +-- owner_to +alter sequence s + owner to u; + +alter sequence s + owner to current_user; + +-- rename +alter sequence s + rename to t; + +-- schema +alter sequence s + set schema x; + diff --git a/crates/squawk_parser/test_data/ok/alter_server.sql b/crates/squawk_parser/test_data/ok/alter_server.sql new file mode 100644 index 00000000..70c8acda --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_server.sql @@ -0,0 +1,19 @@ +-- simple +alter server s + version 'v1'; + +-- full +alter server s + version 'v1' + options (add o 'val', drop p); + +-- owner +alter server s + owner to u; +alter server s + owner to current_user; + +-- rename +alter server s + rename to t; + diff --git a/crates/squawk_parser/test_data/ok/alter_statistics.sql b/crates/squawk_parser/test_data/ok/alter_statistics.sql new file mode 100644 index 00000000..d2c516f7 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_statistics.sql @@ -0,0 +1,14 @@ +-- owner +alter statistics s owner to u; +alter statistics foo.s owner to current_user; + +-- rename +alter statistics s rename to n; + +-- schema +alter statistics s set schema n; + +-- statistics_value +alter statistics s set statistics 100; +alter statistics s set statistics default; + diff --git a/crates/squawk_parser/test_data/ok/alter_subscription.sql b/crates/squawk_parser/test_data/ok/alter_subscription.sql new file mode 100644 index 00000000..0ea7f35a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_subscription.sql @@ -0,0 +1,37 @@ +-- connection +alter subscription s connection 'host=localhost port=5432'; + +-- set_publication +alter subscription s set publication p; +alter subscription s set publication p, q, r with (a, b = true); + +-- add_publication +alter subscription s add publication p; +alter subscription s add publication a, b, c with (a, b = 1); + +-- drop_publication +alter subscription s drop publication p; +alter subscription s drop publication a, b, c with (a, b = 1); + +-- refresh +alter subscription s refresh publication with (copy_data = false); + +-- enable +alter subscription s enable; + +-- disable +alter subscription s disable; + +-- set_parameters +alter subscription s set (slot_name = 'new_slot', synchronous_commit = 'off'); + +-- skip +alter subscription s skip (lsn = '0/12345678'); + +-- owner +alter subscription s owner to u; +alter subscription s owner to current_user; + +-- rename +alter subscription s rename to t; + diff --git a/crates/squawk_parser/test_data/ok/alter_system.sql b/crates/squawk_parser/test_data/ok/alter_system.sql new file mode 100644 index 00000000..64bd78c3 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_system.sql @@ -0,0 +1,22 @@ +-- set_to +alter system set p to 'v'; + +-- set_equals +alter system set p = 'v'; + +-- schema +alter system set foo.p = 'v'; +alter system reset foo.p; + +-- set_multiple +alter system set p to 'v1', 'v2', 'v3'; + +-- set_default +alter system set p to default; + +-- reset_param +alter system reset p; + +-- reset_all +alter system reset all; + diff --git a/crates/squawk_parser/test_data/ok/alter_table.sql b/crates/squawk_parser/test_data/ok/alter_table.sql new file mode 100644 index 00000000..37cc0b00 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_table.sql @@ -0,0 +1,266 @@ +-- add column +alter table products add column description text; + +-- change column data type +alter table products alter column price type numeric(10, 2); + + +-- alter_constraint +alter table t alter constraint c; +alter table t alter constraint c deferrable; +alter table t alter constraint c not deferrable; +alter table t alter constraint c not deferrable initially immediate; + + +-- validate_constraint +alter table t validate constraint foo; + + +-- change column default +alter table products alter column price set default 7.77; + +-- remove column default +alter table products alter column price drop default; + + +-- alter_column +alter table t alter c set data type int collate "foo" using a > b; +alter table t alter c type int; + +alter table t alter c set default 10 * b; +alter table t alter c drop default; + +alter table t alter c set not null; +alter table t alter c drop not null; + +alter table t alter c drop expression; +alter table t alter c drop expression if exists; + +alter table t alter c add generated by default as identity; +alter table t alter c add generated always as identity; +alter table t alter c add generated always as identity ( sequence name foo cycle ); + +alter table t alter c set generated always set sequence name bar restart 10; +alter table t alter c set generated always set sequence name bar restart with 10; + +alter table t alter c drop identity; +alter table t alter c drop identity if exists; + +alter table t alter c set statistics 10; + +alter table t alter c set ( foo = bar, buzz = b ); +alter table t alter c reset ( foo, buzz, b ); +alter table t alter c reset ( p.foo, buzz, b ); +alter table t alter c set ( b = a.b, z = 'foo', w = 10, json = constraint ); + +alter table t alter c set storage plain; +alter table t alter c set storage external; +alter table t alter c set storage extended; +alter table t alter c set storage main; +alter table t alter c set storage default; + +alter table t alter c set compression default; +alter table t alter c set compression foo; + +alter table t alter c restart; + +-- inherit +alter table t inherit t1; +alter table t no inherit t1; + +-- remove constraint +alter table products drop constraint some_name; + +-- remove column not null constraint +alter table products alter column product_no drop not null; + +-- remove constraint if exists +alter table products drop constraint if exists some_name; + +alter table t drop constraint if exists c restrict; +alter table t drop constraint if exists c cascade; + + +-- disable_trigger +alter table t disable trigger foo; +alter table t disable trigger all; +alter table t disable trigger user; + +-- enable_trigger +alter table t enable trigger foo; +alter table t enable trigger all; +alter table t enable trigger user; + +alter table t enable replica trigger c; +alter table t enable always trigger c; + + +-- replica_identity +alter table t replica identity default; +alter table t replica identity using index i; +alter table t replica identity full; +alter table t replica identity nothing; + +-- rule_enable_disable +alter table t disable rule r; +alter table t enable rule r; + +alter table t enable replica rule r; +alter table t enable always rule r; + + +-- row_level_security +alter table t disable row level security; +alter table t enable row level security; +alter table t force row level security; +alter table t no force row level security; + + +-- cluster +alter table t cluster on i; +alter table t set without cluster; +alter table t set without oids; + +-- access_method +alter table t set access method foo; + +alter table t set logged; +alter table t set unlogged; + +-- of_type +alter table t of int8; +alter table t not of; + +-- column constraint +alter table products add column description text check (description <> ''); + +-- add column not null constraint +alter table products alter column product_no set not null; + +-- multi constraints +alter table products add column description text check (description <> '') not null; + +alter table t alter c type timestamptz using c at time zone 'UTC'; + +-- remove_column +-- remove column +alter table products drop column description; + +-- remove column cascade +alter table products drop column description cascade; + +-- remove column restrict +alter table t drop column c restrict; + +-- remove column concise +alter table products drop description; + +-- remove column if exists +alter table products drop column if exists description; + + +-- add table_constraint +alter table products add check (name <> ''); +alter table products add constraint some_name unique (product_no); +alter table products add unique nulls not distinct (a, b, c) with (foo = false, a = true); +alter table products add primary key (a, b); + +alter table t add primary key (a) + include (a, b) + with (a = 1) + using index tablespace foo; + +alter table t add exclude ( + a with =, + tsrange(b, c) with && +); +alter table t add exclude using gist ( + a with =, + tsrange(b, c) with && +) WHERE (d = 'active'); + +alter table t add foreign key (a, b) references t1; +alter table t add foreign key (a, b) references t1 match full; +alter table t add foreign key (a, b) references t1 match simple; +alter table t add foreign key (a, b) references t1(e, f) match full on delete no action on update set null; + +alter table t add foreign key (a) references t1 on delete no action; +alter table t add foreign key (a) references t1 on delete restrict; +alter table t add foreign key (a) references t1 on delete cascade; +alter table t add foreign key (a) references t1 on delete set null; +alter table t add foreign key (a) references t1 on delete set null (a, b); +alter table t add foreign key (a) references t1 on delete set default; +alter table t add foreign key (a) references t1 on delete set default (a, b); + +alter table products add foreign key (product_group_id) references product_groups; + +-- table_constraint_using_index +alter table t add unique using index foo; +alter table t add primary key using index foo; + +alter table t add constraint c unique using index foo; +alter table t add constraint c primary key using index foo; + +-- not valid check +alter table t add constraint foo_not_null + check ("foo" is not null) not valid; + + +-- rename column +alter table products rename column product_no to product_number; + +alter table if exists only t +rename column c to d; + +alter table t * +rename column c to d; + +-- rename table +alter table products rename to items; + +alter table only (a) rename to b; + +-- rename constraint +alter table t rename constraint a to b; + +-- set_schema +alter table t set schema foo; + +-- set tablespace +alter table all in tablespace foo set tablespace bar; + +-- set tablespace all +alter table all in tablespace foo owned by a, b, c +set tablespace bar nowait; + +-- set tablespace owned by +alter table all in tablespace foo owned by bar +set tablespace buz; + +alter table t set tablespace foo; + +-- alter_table_owner +alter table table_name owner to new_owner; + +-- default +alter table t attach partition f default; + +-- partition spec +alter table t attach partition f for values in ('bar', 'buzz'); + +-- multiple_actions +alter table t not of, not of, set logged, set unlogged; + +-- from pg docs +ALTER TABLE transactions + ADD COLUMN status varchar(30) DEFAULT 'old', + ALTER COLUMN status SET default 'current'; + +-- simple +alter table t detach partition f; + +-- concurrently +alter table t detach partition f concurrently; + +-- finalize +alter table t detach partition f finalize; diff --git a/crates/squawk_parser/test_data/ok/alter_table_pg17.sql b/crates/squawk_parser/test_data/ok/alter_table_pg17.sql new file mode 100644 index 00000000..257b3b72 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_table_pg17.sql @@ -0,0 +1,6 @@ + +alter table t alter c set expression as ( a > b ); + +alter table t set access method default; + +alter table t add foreign key (a, b) references t1 match partial; diff --git a/crates/squawk_parser/test_data/ok/alter_tablespace.sql b/crates/squawk_parser/test_data/ok/alter_tablespace.sql new file mode 100644 index 00000000..cef6a07b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_tablespace.sql @@ -0,0 +1,19 @@ +-- rename +alter tablespace t rename to u; + +-- owner +alter tablespace t owner to u; +alter tablespace t owner to current_user; + +-- set_option +alter tablespace t set (o = v); + +-- set_multiple_options +alter tablespace t set (o1 = v1, o2 = v2); + +-- reset_option +alter tablespace t reset (o); + +-- reset_multiple_options +alter tablespace t reset (o1, o2); + diff --git a/crates/squawk_parser/test_data/ok/alter_text_search_configuration.sql b/crates/squawk_parser/test_data/ok/alter_text_search_configuration.sql new file mode 100644 index 00000000..7fd180c6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_text_search_configuration.sql @@ -0,0 +1,50 @@ +-- add_mapping +alter text search configuration n + add mapping for t with d; + +alter text search configuration foo.n + add mapping for t, u with foo.d, foo.e; + +-- alter_mapping +alter text search configuration n + alter mapping for t with d; + +alter text search configuration f.n + alter mapping for t with f.d; + +-- alter_mapping_replace +alter text search configuration n + alter mapping replace o with n; + +alter text search configuration f.n + alter mapping replace f.o with f.n; + +-- alter_mapping_for_replace +alter text search configuration n + alter mapping for t replace o with n; + +alter text search configuration f.n + alter mapping for t replace f.o with f.n; + +-- drop_mapping +alter text search configuration n + drop mapping for t; + +alter text search configuration f.n + drop mapping if exists for t, b; + +-- rename +alter text search configuration n rename to m; + +alter text search configuration f.n rename to m; + +-- owner_to +alter text search configuration n owner to u; + +alter text search configuration f.n owner to current_user; + +-- set_schema +alter text search configuration n set schema s; + +alter text search configuration f.n set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_text_search_dictionary.sql b/crates/squawk_parser/test_data/ok/alter_text_search_dictionary.sql new file mode 100644 index 00000000..49915a9a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_text_search_dictionary.sql @@ -0,0 +1,16 @@ +-- options +alter text search dictionary foo.d ( + a = 1, + b +); + +-- rename +alter text search dictionary d rename to n; + +-- owner +alter text search dictionary d owner to u; +alter text search dictionary d owner to current_user; + +-- schema +alter text search dictionary d set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_text_search_parser.sql b/crates/squawk_parser/test_data/ok/alter_text_search_parser.sql new file mode 100644 index 00000000..7eb58949 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_text_search_parser.sql @@ -0,0 +1,8 @@ +-- rename +alter text search parser p rename to q; + +-- set_schema +alter text search parser p set schema s; + +alter text search parser foo.p set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_text_search_template.sql b/crates/squawk_parser/test_data/ok/alter_text_search_template.sql new file mode 100644 index 00000000..8254db64 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_text_search_template.sql @@ -0,0 +1,6 @@ +-- rename +alter text search template t rename to u; + +-- set_schema +alter text search template foo.t set schema s; + diff --git a/crates/squawk_parser/test_data/ok/alter_trigger.sql b/crates/squawk_parser/test_data/ok/alter_trigger.sql new file mode 100644 index 00000000..dfd01ac1 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_trigger.sql @@ -0,0 +1,9 @@ +-- rename +alter trigger t on x rename to u; + +-- depends_on +alter trigger t on x depends on extension e; + +-- full +alter trigger t on s.t no depends on extension e; + diff --git a/crates/squawk_parser/test_data/ok/alter_type.sql b/crates/squawk_parser/test_data/ok/alter_type.sql new file mode 100644 index 00000000..83ca1278 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_type.sql @@ -0,0 +1,56 @@ +-- owner +alter type t owner to u; +alter type t owner to current_user; + +-- rename +alter type t rename to u; + +-- schema +alter type t set schema s; + +-- rename_attribute +alter type t rename attribute a to b; + +-- rename_attribute_cascade +alter type s.t rename attribute a to b cascade; +alter type s.t rename attribute a to b restrict; + +-- add_value +alter type t add value 'v'; + +-- add_value_full +alter type s.t add value if not exists 'v' before 'w'; +alter type s.t add value if not exists 'v' after 'w'; + +-- rename_value +alter type t rename value 'v' to 'w'; + +-- set_property +alter type t set (p = 'v'); +alter type t set (p = 'v', q = 'w'); + +-- add_attribute +alter type t add attribute a b; + +-- add_attribute_collate +alter type t add attribute a b collate c; + +-- add_attribute_cascade +alter type t add attribute a text cascade; +alter type t add attribute a varchar(100) restrict; + +-- drop_attribute +alter type t drop attribute a; +alter type t drop attribute if exists a cascade; +alter type t drop attribute if exists a restrict; + +-- alter_attribute +alter type t alter attribute a type b; + +-- alter_attribute_set_data +alter type s.t alter attribute a set data type varchar(100) collate c cascade; +alter type t alter attribute a type t restrict; + +-- multiple_actions +alter type t add attribute a b, drop attribute c; + diff --git a/crates/squawk_parser/test_data/ok/alter_user.sql b/crates/squawk_parser/test_data/ok/alter_user.sql new file mode 100644 index 00000000..665bc18d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_user.sql @@ -0,0 +1,41 @@ +-- simple +alter user u superuser; + +-- full +alter user u with + superuser + nosuperuser + createdb + nocreatedb + createrole + nocreaterole + inherit + noinherit + login + nologin + replication + noreplication + bypassrls + nobypassrls + connection limit 10 + encrypted password '' + password null + password 'foo' + valid until '2025-01-01'; + +-- rename_user +alter user u rename to v; + +-- set +alter user u set p = 'value'; +alter user u set p to 'value'; +alter user u set p to default; + +alter user u in database d set p to 'value'; +alter user u set p from current; + +-- reset +alter user u reset p; +alter user u reset all; +alter user u in database d reset p; + diff --git a/crates/squawk_parser/test_data/ok/alter_user_mapping.sql b/crates/squawk_parser/test_data/ok/alter_user_mapping.sql new file mode 100644 index 00000000..6a266b8e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_user_mapping.sql @@ -0,0 +1,5 @@ +-- full +alter user mapping for current_role + server s + options (add a 'v', set b 'w', drop c); + diff --git a/crates/squawk_parser/test_data/ok/alter_view.sql b/crates/squawk_parser/test_data/ok/alter_view.sql new file mode 100644 index 00000000..860b454a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/alter_view.sql @@ -0,0 +1,36 @@ +-- column_set_default +alter view v alter c set default 42; + +alter view if exists v alter column c set default current_timestamp; + +-- column_drop_default +alter view v alter column c drop default; + +-- owner_to +alter view v owner to u; + +-- owner_to_current_role +alter view if exists s.v owner to current_role; + +-- owner_to_current_user +alter view v owner to current_user; + +-- owner_to_session_user +alter view v owner to session_user; + +-- rename_to +alter view v rename to n; + +-- rename_column +alter view v rename column a to b; +alter view v rename a to b; + +-- set_schema +alter view v set schema s; + +-- set_options +alter view v set (a = 'x', b = 100, c, d = true); + +-- reset_options +alter view v reset (a, b, c); + diff --git a/crates/squawk_parser/test_data/ok/analyze.sql b/crates/squawk_parser/test_data/ok/analyze.sql new file mode 100644 index 00000000..2188a313 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/analyze.sql @@ -0,0 +1,10 @@ +-- simple +analyze; +analyse; + +-- full +analyze verbose foo.bar, foo.bar(a, b, c), foo; + +-- full_parens +analyze (verbose false, skip_locked, buffer_usage_limit 10) foo.bar(a, b, c); + diff --git a/crates/squawk_parser/test_data/ok/call.sql b/crates/squawk_parser/test_data/ok/call.sql new file mode 100644 index 00000000..79636d08 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/call.sql @@ -0,0 +1,9 @@ +-- simple +CALL do_db_maintenance(); + +-- with_schema +CALL partman.partition_data_proc('partman_test.time_taptest_table'); + +-- with_named_args +CALL do_db_maintenance(x => '1', null, b => 'd'); + diff --git a/crates/squawk_parser/test_data/ok/checkpoint.sql b/crates/squawk_parser/test_data/ok/checkpoint.sql new file mode 100644 index 00000000..66d2728c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/checkpoint.sql @@ -0,0 +1,3 @@ +-- checkpoint +checkpoint; + diff --git a/crates/squawk_parser/test_data/ok/close.sql b/crates/squawk_parser/test_data/ok/close.sql new file mode 100644 index 00000000..f87b815c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/close.sql @@ -0,0 +1,4 @@ +-- pg_docs +close foo; +close all; + diff --git a/crates/squawk_parser/test_data/ok/cluster.sql b/crates/squawk_parser/test_data/ok/cluster.sql new file mode 100644 index 00000000..ea1042ce --- /dev/null +++ b/crates/squawk_parser/test_data/ok/cluster.sql @@ -0,0 +1,18 @@ +-- simple +cluster; + +-- full +cluster (verbose false) foo.bar using idx; + +-- options_only +cluster (verbose false); + +-- pre_14 +cluster verbose foo.bar using idx; + +-- pre_17 +cluster verbose; + +-- pre_8_3 +cluster verbose f on foo.bar; + diff --git a/crates/squawk_parser/test_data/ok/comment.sql b/crates/squawk_parser/test_data/ok/comment.sql new file mode 100644 index 00000000..c4900414 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/comment.sql @@ -0,0 +1,155 @@ +-- access_method +comment on access method m is ''; + +-- aggregate_star +comment on aggregate my_agg (*) is ''; + +-- aggregate +comment on aggregate a (*) is ''; + +-- aggregate_with_params +comment on aggregate a (in a text, text) is ''; + +-- aggregate_order_by +comment on aggregate a (int, text order by timestamp) is ''; + +-- cast +comment on cast (s as t) is ''; + +-- collation +comment on collation c is ''; + +-- column +comment on column a.b is ''; + +-- constraint_on_table +comment on constraint c on t is ''; + +-- constraint_on_domain +comment on constraint c on domain d is ''; + +-- conversion +comment on conversion c is ''; + +-- database +comment on database d is ''; + +-- domain +comment on domain d is ''; + +-- extension +comment on extension e is ''; + +-- event_trigger +comment on event trigger e is ''; + +-- foreign_data_wrapper +comment on foreign data wrapper f is ''; + +-- foreign_table +comment on foreign table f is ''; + +-- function +comment on function f() is ''; + +-- function_with_args +comment on function f(in a int, b int, text) is ''; + +-- index +comment on index idx is ''; + +-- large_object +comment on large object 1 is ''; + +-- materialized_view +comment on materialized view v is ''; + +-- operator +comment on operator @>(jsonb, jsonb) is ''; + +comment on operator @>(varchar(100), varchar(200)) is ''; + +-- operator_class +comment on operator class c using i is ''; + +-- operator_family +comment on operator family f using i is ''; + +-- policy +comment on policy p on t is ''; + +-- language +comment on language l is ''; + +-- procedural_language +comment on procedural language l is ''; + +-- procedure +comment on procedure p() is ''; + +-- procedure_with_args +comment on procedure p(in a date, b date, bigint) is ''; + +-- publication +comment on publication p is ''; + +-- role +comment on role r is ''; + +-- routine +comment on routine r() is ''; + +-- routine_with_args +comment on routine r(in a text, out b json, bigint) is ''; + +-- rule +comment on rule r on t is ''; + +-- schema +comment on schema s is ''; + +-- sequence +comment on sequence s is ''; + +-- server +comment on server s is ''; + +-- statistics +comment on statistics s is ''; + +-- subscription +comment on subscription s is ''; + +-- table +comment on table t is ''; + +-- table_null +comment on table t is null; + +-- tablespace +comment on tablespace t is ''; + +-- text_search_configuration +comment on text search configuration t is ''; + +-- text_search_dictionary +comment on text search dictionary t is ''; + +-- text_search_parser +comment on text search parser t is ''; + +-- text_search_template +comment on text search template t is ''; + +-- transform +comment on transform for t language l is ''; + +-- trigger +comment on trigger t on u is ''; + +-- type_ +comment on type t is ''; + +-- view +comment on view v is ''; + diff --git a/crates/squawk_parser/test_data/ok/copy.sql b/crates/squawk_parser/test_data/ok/copy.sql new file mode 100644 index 00000000..cfb35b77 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/copy.sql @@ -0,0 +1,48 @@ +-- simple_copy_from +copy copytest from '/tmp/copy.data'; + +-- copy_to +COPY country TO STDOUT (DELIMITER '|'); + +-- copy_from +COPY country FROM '/usr1/proj/bray/sql/country_data'; + +-- copy_to_file +COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy'; + +-- copy_to_compress_filed +COPY country TO PROGRAM 'gzip > /usr1/proj/bray/sql/country_data.gz'; + +-- log_setting +copy x (i, y) from '/tmp/input.file' ( on_error ignore, log_verbosity verbose ); + +-- on_error +copy copytest from '/tmp/copy.data' ( on_error ignore ); + +-- all_the_options +copy t from 'foo' ( + format csv, + freeze, + freeze true, + freeze false, + delimiter ',', + null '\n', + default 'foo', + header, + header true, + header false, + header match, + quote 'foo', + escape 'bar', + force_quote *, + force_quote (a, b, c, d), + force_not_null *, + force_not_null (a), + force_null *, + force_null (a, b), + on_error stop, + on_error ignore, + encoding 'utf8', + log_verbosity verbose +); + diff --git a/crates/squawk_parser/test_data/ok/create_access_method.sql b/crates/squawk_parser/test_data/ok/create_access_method.sql new file mode 100644 index 00000000..2a8a28e5 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_access_method.sql @@ -0,0 +1,10 @@ +-- simple +create access method m + type table + handler f; + +-- full +create access method m + type index + handler bar.f; + diff --git a/crates/squawk_parser/test_data/ok/create_aggregate.sql b/crates/squawk_parser/test_data/ok/create_aggregate.sql new file mode 100644 index 00000000..388178cf --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_aggregate.sql @@ -0,0 +1,127 @@ +-- simple_old_syntax +create aggregate a ( + basetype = t, + sfunc = f, + stype = u +); + +-- full_old_syntax +create or replace aggregate foo.my_aggregate ( + basetype = foo.input_type, + sfunc = foo.state_function, + stype = foo.state_type, + sspace = 1024, + finalfunc = foo.final_function, + finalfunc_extra = true, + finalfunc_modify = read_only, + combinefunc = foo.combine_function, + serialfunc = foo.serial_function, + deserialfunc = foo.deserial_function, + initcond = '0', + msfunc = foo.moving_state_function, + minvfunc = foo.moving_inverse_function, + mstype = foo.moving_state_type, + msspace = 2048, + mfinalfunc = foo.moving_final_function, + mfinalfunc_extra = true, + mfinalfunc_modify = shareable, + minitcond = '{"initial":"value"}', + sortop = < +); + +-- simple +create aggregate a(t) ( + sfunc = f, + stype = t +); + +-- full +create or replace aggregate a(in a p.bar, text, smallint) ( + sfunc = f, + stype = t, + sspace = 1024, + finalfunc = ff, + finalfunc_extra, + finalfunc_modify = read_only, + combinefunc = cf, + serialfunc = sf, + deserialfunc = df, + initcond = '0', + msfunc = msf, + minvfunc = mif, + mstype = mt, + msspace = 2048, + mfinalfunc = mff, + mfinalfunc_extra, + mfinalfunc_modify = shareable, + minitcond = '{"initial":"value"}', + sortop = <, + parallel = safe +); + +-- ordered_aggregate +create or replace aggregate percentile_disc( + in p1 float8, +-- in p2 text ORDER BY in value1 anyelement, + in value2 timestamp ORDER BY a, + result numeric +) ( + sfunc = percentile_disc_transition, + stype = internal, + sspace = 1024, + finalfunc = percentile_disc_final, + finalfunc_extra, + finalfunc_modify = read_only, + initcond = '0.5', + parallel = safe, + hypothetical +); + +-- doc_example_1 +CREATE AGGREGATE array_accum (anycompatible) +( + sfunc = array_append, + stype = anycompatiblearray, + initcond = '{}' +); + +-- doc_example_2 +CREATE AGGREGATE array_agg (anynonarray) +( + sfunc = array_agg_transfn, + stype = internal, + finalfunc = array_agg_finalfn, + finalfunc_extra +); + +-- doc_example_3 +CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement) +( + sfunc = ordered_set_transition, + stype = internal, + finalfunc = percentile_disc_final, + finalfunc_extra +); + +-- doc_example_4 +CREATE AGGREGATE sum (complex) +( + sfunc = complex_add, + stype = complex, + initcond = '(0,0)', + msfunc = complex_add, + minvfunc = complex_sub, + mstype = complex, + minitcond = '(0,0)' +); + +-- doc_example_5 +CREATE AGGREGATE unsafe_sum (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi +); + diff --git a/crates/squawk_parser/test_data/ok/create_cast.sql b/crates/squawk_parser/test_data/ok/create_cast.sql new file mode 100644 index 00000000..79f7c354 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_cast.sql @@ -0,0 +1,14 @@ +-- simple +create cast (t as u) + without function; + +-- inout +create cast (t as u) + with inout + as implicit; + +-- full +create cast (foo.t as bar.u) + with function foo.bar(in a text, out b bigint, text) + as assignment; + diff --git a/crates/squawk_parser/test_data/ok/create_collation.sql b/crates/squawk_parser/test_data/ok/create_collation.sql new file mode 100644 index 00000000..401a5f6a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_collation.sql @@ -0,0 +1,17 @@ +-- simple +create collation c from d; + +-- from_full +create collation if not exists foo.c from bar.d; + +-- with_options +create collation if not exists foo.c ( + locale = 'foo', + lc_collate = 1, + lc_ctype = false, + provider = 'foo', + deterministic = false, + rules = r, + version = '100' +); + diff --git a/crates/squawk_parser/test_data/ok/create_conversion.sql b/crates/squawk_parser/test_data/ok/create_conversion.sql new file mode 100644 index 00000000..13e8a676 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_conversion.sql @@ -0,0 +1,12 @@ +-- simple +create conversion c + for '' + to '' + from f; + +-- full +create default conversion foo.bar.c + for '' + to '' + from foo.bar; + diff --git a/crates/squawk_parser/test_data/ok/create_database.sql b/crates/squawk_parser/test_data/ok/create_database.sql new file mode 100644 index 00000000..63aef390 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_database.sql @@ -0,0 +1,23 @@ +-- simple +create database d; + +-- full +create database d + with owner 'foo' + template = 'foo' + encoding = 'utf-8' + strategy = 10 + locale = 'fr_FR' + lc_collate = 'fr_FR' + lc_ctyep = 10 + builtin_locale = 'en' + icu_locale = 'en' + icu_rules = '' + locale_provider = './foo/bar' + collation_version = 10 + tablespace = full + allow_connections = false + connection limit = 1000 + is_template = false + oid 1010; + diff --git a/crates/squawk_parser/test_data/ok/create_domain.sql b/crates/squawk_parser/test_data/ok/create_domain.sql new file mode 100644 index 00000000..529f4e82 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_domain.sql @@ -0,0 +1,11 @@ +-- simple +create domain d int; + +-- full +create domain d as varchar(100) + collate "fr_FR" + default 'fooooo' + constraint c check (a > b) + not null + null; + diff --git a/crates/squawk_parser/test_data/ok/create_event_trigger.sql b/crates/squawk_parser/test_data/ok/create_event_trigger.sql new file mode 100644 index 00000000..fc29ebe1 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_event_trigger.sql @@ -0,0 +1,14 @@ +-- simple +create event trigger t on e + execute function f(); + +-- full +create event trigger t on e + when x in ('foo', 'bar', 'buzz') + and real in ('a') + execute function foo.f(); + +-- doc_example_1 +CREATE EVENT TRIGGER abort_ddl ON ddl_command_start + EXECUTE FUNCTION abort_any_command(); + diff --git a/crates/squawk_parser/test_data/ok/create_ext.sql b/crates/squawk_parser/test_data/ok/create_ext.sql new file mode 100644 index 00000000..caf82988 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_ext.sql @@ -0,0 +1,15 @@ +-- create_extension +create extension foo; +create extension if not exists foo; + +create extension hstore schema addons; + +create extension foo + with schema bar + version foo + cascade; + +create extension foo + schema bar + version 'buzz'; + diff --git a/crates/squawk_parser/test_data/ok/create_foreign_data_wrapper.sql b/crates/squawk_parser/test_data/ok/create_foreign_data_wrapper.sql new file mode 100644 index 00000000..e8885e4c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_foreign_data_wrapper.sql @@ -0,0 +1,11 @@ +-- simple +create foreign data wrapper w; + +-- full +create foreign data wrapper w + handler foo.bar + no handler + validator f.bar + no validator + options (a 'foo', b 'bar'); + diff --git a/crates/squawk_parser/test_data/ok/create_foreign_table.sql b/crates/squawk_parser/test_data/ok/create_foreign_table.sql new file mode 100644 index 00000000..0cfa4706 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_foreign_table.sql @@ -0,0 +1,73 @@ +-- simple +create foreign table t() + server s; + +-- full +create foreign table if not exists t( + a text, + b foo.bigint + options (a 'b', c 'd') + collate "fr_FR" + constraint c + not null + null + check (x > b) no inherit + default 10 * 2 + generated always as (x + 2) stored, + constraint fooo + check (a > b) +) + inherits (foo.bar, bar) + server s + options (a 'b', c 'd'); + +-- partitioned_simple +create foreign table t + partition of u + default + server s; + +-- partitioned +create foreign table if not exists t + partition of foo.u( + a with options not null check (a > 10), + b null default 'foo', + check (a > b) + ) + default + server s + options (a 'b', c 'd'); + +-- partitioned_bound_spec_in +create foreign table if not exists t + partition of u( + a + ) + for values in (a > b) + server s; + +-- partitioned_bound_spec_from +create foreign table if not exists t + partition of u( + a + ) + for values from (a > b, minvalue, maxvalue) + to (maxvalue, minvalue) + server s; + +-- partitioned_bound_spec_with +create foreign table if not exists t + partition of u( + a + ) + for values with (modulus 10, remainder 2) + server s; + +-- with schema +create foreign table cal.event_types ( + attrs jsonb +) + server cal_server + options ( + object 'event-types' + ); diff --git a/crates/squawk_parser/test_data/ok/create_function.sql b/crates/squawk_parser/test_data/ok/create_function.sql new file mode 100644 index 00000000..72a1ef01 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_function.sql @@ -0,0 +1,409 @@ +-- create_func_with_in_out +create function dup(in int, out f1 int, out f2 text) + as $$ select $1, cast($1 as text) || ' is text' $$ + language sql; + +-- security_definer +CREATE FUNCTION check_password(uname TEXT, pass TEXT) +RETURNS BOOLEAN AS $$ +DECLARE passed BOOLEAN; +BEGIN + SELECT (pwd = $2) INTO passed + FROM pwds + WHERE username = $1; + + RETURN passed; +END; +$$ LANGUAGE plpgsql + SECURITY DEFINER + -- Set a secure search_path: trusted schema(s), then 'pg_temp'. + SET search_path = admin, pg_temp; + +-- create_function_with_percent_type +-- column type return +create function f(a t.c%type) +returns t.b%type +as '' language plpgsql; + +-- setof return +create function f(int) +returns setof b.foo +as '' language sql; + +-- void return +create function f(int) +returns void +as '' language sql; + +-- omitted return +create function f() +as '' language 'sql'; + +-- schema +create function public.f() +returns int +as 'select 1' language 'sql'; + +create function a.b.c.d() +returns int +as 'select 1' language 'sql'; + +create function public.a() +returns numeric[] +as '' language 'sql'; + +-- returns table +create function f() +returns table (a text, b int) +as '' language sql; + +-- transform +create function f() +returns void +transform for type t, for type b +as '' +language sql; + +-- transform with type with args +create function f() +returns varchar(255) +transform for type varchar(100) +as '' +language sql; + +-- window +create function f() +returns void +window +as '' +language sql; + +-- immutable, stable, volatile +create function f() +returns void +immutable +as '' +language sql; + +create function f() +returns void +stable +as '' +language sql; + +create function f() +returns void +volatile +as '' +language sql; + +-- [ not ] leakproof +create function f() +returns void +not leakproof +as '' +language sql; + +create function f() +returns void +leakproof +as '' +language sql; + +-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT +create function f() +returns void +called on null input +as '' +language sql; + +create function f() +returns void +returns null on null input +as '' +language sql; + +create function f() +returns void +strict +as '' +language sql; + +-- [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER +create function f() +returns void +external security invoker +as '' +language sql; + +create function f() +returns void +security invoker +as '' +language sql; + +create function f() +returns void +external security definer +as '' +language sql; + +create function f() +returns void +security definer +as '' +language sql; + +-- parallel +create function f() +returns void +parallel unsafe +as '' +language sql; + +create function f() +returns void +parallel restricted +as '' +language sql; + +create function f() +returns void +parallel safe +as '' +language sql; + + +-- cost +create function f() +returns void +cost 100 +as '' +language sql; + +-- rows +create function f() +returns void +rows 10 +as '' +language sql; + + +-- suport +create function f() +returns void +support foo.bar +as '' +language sql; + +create function f() +returns void +support bar +as '' +language sql; + +-- set configuration_parameter +create function f() +returns void +set foo.bar from current +as '' +language sql; + +create function f() +returns void +set bar to 'foo' +as '' +language sql; + +create function f() +returns void +set bar = 1 +as '' +language sql; + +-- as def +create function f() +returns void +as 'select 1' +language sql; + +-- as 'object_file', 'link_symbol' +create function f() +returns void +as 'foo', 'bar' +language foo; + +-- return +create function f() +returns void +language sql +return (select 1); + +-- begin atomic +create function f() +returns void +language sql +begin atomic + select 1; + select 2; +end; + +create function f() +returns void +language sql +begin atomic + select 1; + end; +end; + +-- lots of ; +create function f() +returns void +language sql +begin atomic +; +; +; +; + select 1; +; +; +;; +end; + +-- all options +create function f() + returns void + language sql + transform for type foo + window + immutable + not leakproof + strict + external security invoker + parallel safe + cost 1000 + rows 1000 + support foo.bar + set a.b = 10 + as '' + as 'foo', 'bar' + return (select 1); + +-- regression +create function foo(int8) +returns int +as 'select 1 + 1' +language sql; + +create function f(bitmask bit(8)) +returns boolean +as '0' +language sql; + +-- argmode +create function foo(in int8) +returns void +as '' +language sql; + +create function foo(out int8) +returns void +as '' +language sql; + +create function foo(in out int8) +returns void +as '' +language sql; + +create function foo(inout int8) +returns void +as '' +language sql; + +create function foo(variadic int8) +returns void +as '' +language sql; + +-- with_arg_names + + +-- single arg +create function foo(arg int8) +returns void +as '' +language sql; + +-- multi args +create function foo(arg float, arg2 int4) +returns void +as '' +language sql; + +-- named and unnamed +create function foo(arg float, int4) +returns void +as '' +language sql; + +-- default +-- = +create function foo(arg float = 1, int4 = 4) +returns void +as '' +language sql; + +-- not a parser error but something to warn about +create function foo(arg float = 1, int4) +returns void +as '' +language sql; + +-- default +create function foo(arg int default 1) +returns void +as '' +language sql; + +-- expr w/ default +create function foo(arg int default 1 * 2) +returns void +as '' +language sql; + +-- expr w/ = +create function foo(arg int = 1 * 2) +returns void +as '' +language sql; + +-- param_type_order +-- mode name type +create function f(in arg int8) +returns void +as '' language sql; + +-- mode type +create function f(in int8) +returns void +as '' language sql; + +-- name mode type +create function f(int8 in int8) +returns void +as '' language sql; + +-- name type +create function f(int8 int8) +returns void +as '' language sql; + +-- type +create function f(int8) +returns void +as '' language sql; + + + diff --git a/crates/squawk_parser/test_data/ok/create_group.sql b/crates/squawk_parser/test_data/ok/create_group.sql new file mode 100644 index 00000000..bb48d3eb --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_group.sql @@ -0,0 +1,31 @@ +-- simple +create group g; + +-- full +create group g + with superuser + nosuperuser + nosuperuser + createdb + nocreatedb + createrole + nocreaterole + inherit + noinherit + login + nologin + replication + noreplication + bypassrls + nobypassrls + connection limit 100 + encrypted password 'foo' + password 'bar' + password null + valid until '2042-02-22' + in role foo, bar, buzz + in group foo + role r, current_user + admin foo, bar, buzz + sysid 100; + diff --git a/crates/squawk_parser/test_data/ok/create_index.sql b/crates/squawk_parser/test_data/ok/create_index.sql new file mode 100644 index 00000000..40e60317 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_index.sql @@ -0,0 +1,62 @@ +-- create_index +-- simple +create index on t (c); + +-- more options +create unique index concurrently + if not exists i + on only t + using bar (c); + +-- column options +create index on t (c collate "fr_FR" asc nulls last); +create index on t (c desc nulls first); + +-- opclass +create index on t ( + a text_pattern_ops (strength = primary, variant = default), + b text_pattern_ops (strength = primary) +); + +-- column expr +create index on t ((f(c) + 2), b); + +-- trailing options +create index on t (c) + include (a, b) + nulls not distinct + with (foo = bar, buzz) + tablespace space + where x > 10; + +create index on t (c) + nulls distinct + where x is not null; + +-- schema +create index on public.t (c); + +-- doc_examples +CREATE UNIQUE INDEX title_idx ON films (title); + +CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating); + +CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off); + +CREATE INDEX ON films ((lower(title))); + +CREATE INDEX title_idx_german ON films (title COLLATE "de_DE"); + +CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST); + +CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70); + +CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off); + +CREATE INDEX code_idx ON films (code) TABLESPACE indexspace; + +CREATE INDEX pointloc + ON points USING gist (box(location,location)); + +CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity); + diff --git a/crates/squawk_parser/test_data/ok/create_language.sql b/crates/squawk_parser/test_data/ok/create_language.sql new file mode 100644 index 00000000..600d8394 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_language.sql @@ -0,0 +1,9 @@ +-- simple +create language l; + +-- full +create or replace trusted procedural language l + handler foo.bar + inline f.b + validator x.y; + diff --git a/crates/squawk_parser/test_data/ok/create_materialized_view.sql b/crates/squawk_parser/test_data/ok/create_materialized_view.sql new file mode 100644 index 00000000..68738098 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_materialized_view.sql @@ -0,0 +1,21 @@ +-- simple +create materialized view t + as select 1; + +-- full +create materialized view if not exists foo.bar + (a, b, c) + using u + with (x = 10, bar, buzz = true) + tablespace t + as select 1, 2, 3 + with no data; + +-- table +create materialized view t + as table u; + +-- values +create materialized view t + as values (1), (2, 2); + diff --git a/crates/squawk_parser/test_data/ok/create_operator.sql b/crates/squawk_parser/test_data/ok/create_operator.sql new file mode 100644 index 00000000..237b31ab --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_operator.sql @@ -0,0 +1,23 @@ +-- simple +create operator > ( + function = f +); + +-- procedure +create operator # ( + procedure = p +); + +-- full +create operator foo.bar.>>-# ( + function = foo.bar.f, + leftarg = varchar(100), + rightarg = foo.bigint, + commutator = &&&&, + negator = <->, + restrict = r, + join = j, + hashes, + merges +); + diff --git a/crates/squawk_parser/test_data/ok/create_operator_class.sql b/crates/squawk_parser/test_data/ok/create_operator_class.sql new file mode 100644 index 00000000..cc520e80 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_operator_class.sql @@ -0,0 +1,15 @@ +-- simple +create operator class c for type t + using i as storage s; + +-- full +create operator class foo.c for type varchar(100) + using i family foo.f as + storage s, + operator 1 &&, + operator 100 <<<< (text, foo.bigint) for search, + operator 100 # (varchar(100), varchar(10)) for order by foo.bar, + function 1010 foo, + function 1010 (bigint) foo.bar(in b text, out a text, text), + function 1010 (bigint, smallint) foo.bar(text, text); + diff --git a/crates/squawk_parser/test_data/ok/create_operator_family.sql b/crates/squawk_parser/test_data/ok/create_operator_family.sql new file mode 100644 index 00000000..c557ba2e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_operator_family.sql @@ -0,0 +1,6 @@ +-- simple +create operator family f using i; + +-- full +create operator family a.b using i; + diff --git a/crates/squawk_parser/test_data/ok/create_policy.sql b/crates/squawk_parser/test_data/ok/create_policy.sql new file mode 100644 index 00000000..286962ec --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_policy.sql @@ -0,0 +1,34 @@ +-- simple +create policy p on t; + +-- as_ +create policy p on t + as permissive; + +create policy p on t + as restrictive; + +-- full +create policy p on foo.t + as permissive + for all + to public, current_role, current_user, session_user + using (x > b and 1 < 2) + with check ( x < 1); + +-- for_ +create policy p on t + for all; + +create policy p on t + for select; + +create policy p on t + for insert; + +create policy p on t + for update; + +create policy p on t + for delete; + diff --git a/crates/squawk_parser/test_data/ok/create_procedure.sql b/crates/squawk_parser/test_data/ok/create_procedure.sql new file mode 100644 index 00000000..fc0c32ca --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_procedure.sql @@ -0,0 +1,31 @@ +-- simple +create procedure p() +language sql; + +-- full +create or replace procedure p( + in a text DEFAULT 'foo', + out b bigint = 10, + bigint = 1 +) +language sql +transform for type foo.t, for type text +external security invoker +security invoker +external security definer +security definer +set foo to true +set bar = false +set buzz from current +as 'foo' +as 'foo', 'bar' +return 10 + 1; + +-- with_select_body +create or replace procedure p() +language sql +begin atomic + select 1; + select 2; +end; + diff --git a/crates/squawk_parser/test_data/ok/create_publication.sql b/crates/squawk_parser/test_data/ok/create_publication.sql new file mode 100644 index 00000000..a308e7f6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_publication.sql @@ -0,0 +1,23 @@ +-- simple +create publication p; + +-- all_tables +create publication p + for all tables + with (foo = bar, bar); + +-- table +create publication p for + table only foo.bar, + table foo.bar.buzz *, + table foo, + table foo(a, b, c) where (x > 10 or a != b), + table only (foo) + with (foo = bar, bar); + +-- table_in_schema +create publication p + for tables in schema a, b, c, current_schema; + +-- multiple tables +create publication pub for table chats, users; diff --git a/crates/squawk_parser/test_data/ok/create_role.sql b/crates/squawk_parser/test_data/ok/create_role.sql new file mode 100644 index 00000000..00751e4b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_role.sql @@ -0,0 +1,29 @@ +-- simple +create role u; + +-- full +create role u + with superuser + nosuperuser + nosuperuser + createdb + nocreatedb + createrole + nocreaterole + inherit + noinherit + login + nologin + replication + noreplication + bypassrls + nobypassrls + connection limit 100 + encrypted password 'foo' + password 'bar' password null + valid until '2042-02-22' + in role foo, bar, buzz + in group foo + admin foo + sysid 100; + diff --git a/crates/squawk_parser/test_data/ok/create_rule.sql b/crates/squawk_parser/test_data/ok/create_rule.sql new file mode 100644 index 00000000..a05c8bf6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_rule.sql @@ -0,0 +1,36 @@ +-- simple +create rule r as on select + to t + do nothing; + +-- full +create or replace rule r as on select + to foo.t + where new.foo = old.foo or old.id != new.id + do ( + select 1; + insert into t values (1, 2); + delete from t; + values (1, 2); + update t set foo = 1; + notify f; + ); + +-- doc_1 +CREATE RULE "_RETURN" AS + ON SELECT TO t1 + DO INSTEAD + SELECT * FROM t2; + +CREATE RULE "_RETURN" AS + ON SELECT TO t2 + DO INSTEAD + SELECT * FROM t1; + +SELECT * FROM t1; + +-- doc_2 +CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable; + +UPDATE mytable SET name = 'foo' WHERE id = 42; + diff --git a/crates/squawk_parser/test_data/ok/create_sequence.sql b/crates/squawk_parser/test_data/ok/create_sequence.sql new file mode 100644 index 00000000..02075186 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_sequence.sql @@ -0,0 +1,19 @@ +-- simple +create sequence s; + +-- full +create temporary sequence if not exists s + as varchar(100) + increment by 10 + minvalue 1 + no minvalue + maxvalue 100 + no maxvalue + start with 10 + cache 10 + no cycle + owned by foo.bar; + +-- unlogged +create unlogged sequence s; + diff --git a/crates/squawk_parser/test_data/ok/create_server.sql b/crates/squawk_parser/test_data/ok/create_server.sql new file mode 100644 index 00000000..53bbf9ff --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_server.sql @@ -0,0 +1,13 @@ +-- simple +create server s foreign data wrapper f; + +-- full +create server if not exists s + type 'bar' + version 'foo' + foreign data wrapper f + options (a 'foo', bar 'b'); + +-- docs_1 +CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foo', dbname 'foodb', port '5432'); + diff --git a/crates/squawk_parser/test_data/ok/create_statistics.sql b/crates/squawk_parser/test_data/ok/create_statistics.sql new file mode 100644 index 00000000..5d57e707 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_statistics.sql @@ -0,0 +1,17 @@ +-- simple +create statistics on (a) from t; + +-- full +create statistics if not exists foo.s(mcv, ndistinct, dependencies) +on (foo), bar, buzz, (a + b) +from foo.t; + +-- docs_1 +CREATE STATISTICS s1 (dependencies) ON a, b FROM t1; + +-- docs_2 +CREATE STATISTICS s2 (mcv) ON a, b FROM t2; + +-- docs_3 +CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3; + diff --git a/crates/squawk_parser/test_data/ok/create_subscription.sql b/crates/squawk_parser/test_data/ok/create_subscription.sql new file mode 100644 index 00000000..f6120b98 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_subscription.sql @@ -0,0 +1,25 @@ +-- simple +create subscription s + connection '' + publication a; + +-- full +create subscription s + connection 'host=10.0.0.1 port=5432 user=u dbname=d' + publication a, b, c + with ( + connect = false, + create_slot = true, + enabled = false, + slot_name = 'bar', + binary = true, + copy_data = true, + synchronous_commit = off, + two_phase = false, + disable_on_error = true, + password_required = false, + run_as_owner = true, + origin = 'foo', + failover = false + ); + diff --git a/crates/squawk_parser/test_data/ok/create_table.sql b/crates/squawk_parser/test_data/ok/create_table.sql new file mode 100644 index 00000000..2390fdee --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_table.sql @@ -0,0 +1,320 @@ +-- create_table +-- simple +create table t ( + a text, + b integer +); + +-- with schema prefix +create table foo.t ( + a text, + b integer +); + +-- like source_table +create table t ( + a text, + like large_data_table, + b integer +); + +-- like option +create table t ( + a text, + like bar.b including comments +); + +-- like options +create table t ( + a text, + like bar.b including comments including constraints excluding defaults excluding generated excluding identity excluding indexes excluding statistics including storage excluding all +); + +-- with prefix options +create global temporary table if not exists t ( + a text +); +create local temp table t ( + a text +); + +-- unlogged +create unlogged table t ( + a text +); + +-- inherits from parent +create table t (a int) +inherits (foo.bar, bar, buzz); + +-- partition range +create table t (a int) +partition by range ( + foo collate "fr_FR" text_pattern_ops, + bar, + extract(month from b), + (a || b) collate buzz +); + +-- partition list +create table t (b int) +partition by hash (z); + +-- partition hash +create table t (b int) +partition by list (z, b); + +-- using +create table t (a int) +using bar; + +-- with +create table t (a int) +with ( + foo, + bar = 1, + buzz.bar = false +); + +-- without +create table t (a int) +without OIDS; + +-- on commit +create table t (a int) +on commit preserve rows; + +create table t (a int) +on commit delete rows; + +create table t (a int) +on commit drop; + +-- tablespace +create table t (a int) +tablespace bar; + + +-- like_column +create table u ( + a text, + "like" a, + like t +); + +-- create_table_column_constraints +-- not null +create table t ( + b int not null +); + +-- null +create table t ( + b int null +); + +-- default +create table t ( + b int default 100 +); + +-- unique constraint +create table t ( + a int unique, + b int unique nulls not distinct, + c int unique with ( + fillfactor, + toast_tuple_target = 100, + parallel_workers = 5, + autovacuum_enabled = false, + autovacuum_vacuum_cost_delay = 10.1 + -- others omitted + ), + d int unique using index tablespace foo +); + +-- references actions order +create table t ( + b int references foo + on update no action + on delete no action +); + +-- primary key +create table t ( + a int primary key with ( autovacuum_enabled ), + a int primary key +); + +-- check constraint +create table t ( + b int check (b > 10), + c int check (c > 10) no inherit +); + +-- defer +create table t ( + a int check (a > 10) deferrable, + b int not null not deferrable, + c int not null initially deferred, + d int not null initially immediate +); + +-- constraint +create table t ( + b int constraint foo null +); + +-- generated stored +create unlogged table t ( + a int, + b int generated always as ( + a * 2 + ) stored +); + +-- create_table_table_constraints + +-- named constraint +create table t ( + a int, + b text, + constraint foo check (a > b) no inherit +); + +-- check constraint +create table t ( + a int, + b text, + check (a > b) +); + +-- unique constraint +create table t ( + a int, + b text, + unique nulls not distinct (a, b) with ( bar = false ) +); + +-- unique with name constraint +create table t ( + a int, + b text, + unique (a) deferrable initially deferred +); + +-- primary key constraint +create table t ( + a int, + b text, + primary key (a, b) using index tablespace bar +); + +-- exclude constraint +create table t ( + a int, + b text, + exclude using btree ( a with f.buzz.> ) where ( a > 10 ) +); + +-- exclude constraint multiple exclusions +create table t ( + a int, + b text, + exclude using btree ( a with buzz.>, b with < ) + where ( a > 10 and b like '%foo' ) +); + +-- exclude constraint all clauses exclusions +create table t ( + a int, + b text, + exclude using btree ( a with > ) + include (a, b) + with (x = 10, z) + using index tablespace foo + where ( a > 10 and b like '%foo' ) + deferrable +); + +-- foreign key constraint +create table t ( + a int, + b text, + foreign key ( a, b ) references bizz.bar ( a, b ) +); + +-- everything +create table t ( + a int, + b text, + constraint foo check (a > b) no inherit, + check (a > b), + unique nulls not distinct (a, b) with ( bar = false ), + primary key (a, b) using index tablespace bar, + exclude using btree ( a with buzz.> ) where ( a > 10 ), + foreign key ( a, b ) references bizz.bar ( a, b ), + unique (a) deferrable initially deferred, + check (i * 2 >= o) not deferrable initially immediate +); + + +-- multi_dimensional_arrays +CREATE TABLE sal_emp ( + name text, + pay_by_quarter integer[], + schedule text[][] +); + +-- array_with_params +CREATE TABLE tictactoe ( + squares integer[3][3] +); + +-- array_alt_syntax +CREATE TABLE tictactoe ( + pay_by_quarter integer ARRAY[4], + pay_by_quarter integer ARRAY +); + +-- create_table_of_type +-- simple +create table t of bar.foo; + +-- with column defs +create table t of bar.foo ( + a, + b not null, + c with options not null, + check (a > b) +); + +-- create_table_partition_of +-- default +create table t +partition of foo.bar default; + +-- partition with +create table t +partition of foo.bar +for values with (modulus 1, remainder 1); + +-- partition in +create table t +partition of foo.bar +for values in ('bar', 'buzz'); + +-- partition from to +create table t +partition of foo.bar +for values from ('bar') to ('buzz'); + +-- missing entries +create table t (); + +-- regression +CREATE TABLE sensors_uncompressed ( + sensor_id INTEGER, + ts TIMESTAMPTZ NOT NULL, + value REAL +); diff --git a/crates/squawk_parser/test_data/ok/create_table_as.sql b/crates/squawk_parser/test_data/ok/create_table_as.sql new file mode 100644 index 00000000..fa6fa581 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_table_as.sql @@ -0,0 +1,19 @@ +-- execute +create temp table t on commit drop as + execute f(a); + +-- select +create table t as + select * from u where c >= b; + +-- table +create table t as + table u; + +-- values +create temporary table t as + values (1); + +create temporary table t as + values (1, 3), (a, 5); + diff --git a/crates/squawk_parser/test_data/ok/create_table_pg17.sql b/crates/squawk_parser/test_data/ok/create_table_pg17.sql new file mode 100644 index 00000000..76350371 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_table_pg17.sql @@ -0,0 +1,32 @@ +-- match partial not implemented yet +create table t ( + a int, + b int references foo.bar ( bar ) match partial + on delete no action + on update set null ( a, b ) +); + + +-- temporal_foreign_key +CREATE TABLE orders ( + id int8 generated BY DEFAULT AS IDENTITY, + address_id int8 NOT NULL, + address_valid_at tstzrange NOT NULL, + content text, + CONSTRAINT order_address FOREIGN KEY ( address_id, PERIOD address_valid_at ) REFERENCES addresses ( id, PERIOD valid_range ) +); + +-- unique_constraint_without_overlaps +create table t ( + a int, + b text, + unique (a without overlaps) +); + +-- temporal_primary_key +CREATE TABLE addresses ( + id int8 generated BY DEFAULT AS IDENTITY, + valid_range tstzrange NOT NULL DEFAULT tstzrange(now(), 'infinity', '[)'), + recipient text NOT NULL, + PRIMARY KEY (id, valid_range WITHOUT OVERLAPS) +); diff --git a/crates/squawk_parser/test_data/ok/create_tablespace.sql b/crates/squawk_parser/test_data/ok/create_tablespace.sql new file mode 100644 index 00000000..69e78a04 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_tablespace.sql @@ -0,0 +1,14 @@ +-- simple +create tablespace t location ''; + +-- full +create tablespace t + owner current_role + location '' + with ( + seq_page_cost = 10, + random_page_cost = 1, + effective_io_concurrency = 0, + maintenance_io_concurrency = 4 + ); + diff --git a/crates/squawk_parser/test_data/ok/create_text_search_config.sql b/crates/squawk_parser/test_data/ok/create_text_search_config.sql new file mode 100644 index 00000000..d964557c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_text_search_config.sql @@ -0,0 +1,10 @@ +-- simple +create text search configuration name ( + parser = parser_name +); + +-- full +create text search configuration foo.name ( + config = source_config +); + diff --git a/crates/squawk_parser/test_data/ok/create_text_search_dict.sql b/crates/squawk_parser/test_data/ok/create_text_search_dict.sql new file mode 100644 index 00000000..8c828086 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_text_search_dict.sql @@ -0,0 +1,12 @@ +-- simple +create text search dictionary name ( + template = t +); + +-- full +create text search dictionary foo.name ( + template = t, + foo = bar, + a = b +); + diff --git a/crates/squawk_parser/test_data/ok/create_text_search_parser.sql b/crates/squawk_parser/test_data/ok/create_text_search_parser.sql new file mode 100644 index 00000000..11dddde5 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_text_search_parser.sql @@ -0,0 +1,17 @@ +-- simple +create text search parser name ( + start = start_function, + gettoken = gettoken_function, + end = end_function, + lextypes = lextypes_function +); + +-- full +create text search parser foo.name ( + start = start_function, + gettoken = gettoken_function, + end = end_function, + lextypes = lextypes_function, + headline = headline_function +); + diff --git a/crates/squawk_parser/test_data/ok/create_text_search_template.sql b/crates/squawk_parser/test_data/ok/create_text_search_template.sql new file mode 100644 index 00000000..fdb32061 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_text_search_template.sql @@ -0,0 +1,11 @@ +-- simple +create text search template name ( + lexize = f +); + +-- full +create text search template foo.name ( + INIT = init_function, + lexize = lexize_function +); + diff --git a/crates/squawk_parser/test_data/ok/create_transform.sql b/crates/squawk_parser/test_data/ok/create_transform.sql new file mode 100644 index 00000000..8a1b8133 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_transform.sql @@ -0,0 +1,12 @@ +-- simple +create transform for t language l ( + from sql with function t, + to sql with function g +); + +-- full +create or replace transform for foo.t(10231) language l ( + from sql with function bar.foo.f(a text), + to sql with function g +); + diff --git a/crates/squawk_parser/test_data/ok/create_trigger.sql b/crates/squawk_parser/test_data/ok/create_trigger.sql new file mode 100644 index 00000000..682b6c71 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_trigger.sql @@ -0,0 +1,35 @@ +-- create_trigger +CREATE TRIGGER update_foo_column +BEFORE INSERT ON core_recipe +FOR EACH ROW +EXECUTE PROCEDURE foo_update_trigger(); + +-- with_most_fields +create or replace trigger buzz instead of insert or delete +on foo.bar.buzz +referencing + old table as foo + new table as bar +for each statement +when (x > 10 and b is not null) +execute function x.y.z(1,2,'3'); + +-- constraint +create constraint trigger t after insert or delete +on f +for each row +execute function f(); + +-- with_most_fields_part2 +create trigger bar after update of a, b, c +on foo +referencing + new table bar + old table foo +for row +execute procedure foo('bar'); + +-- simple +create trigger bar before truncate or delete or insert +on buzz +execute function a(); diff --git a/crates/squawk_parser/test_data/ok/create_type.sql b/crates/squawk_parser/test_data/ok/create_type.sql new file mode 100644 index 00000000..aee991be --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_type.sql @@ -0,0 +1,62 @@ +-- create_type_as +create type t as (); + +create type t as ( + a int8 collate "fr_FR" +); + +create type t as ( + a int8 collate "fr_FR", + b int, + c text +); + +-- create_type_as_enum +create type t as enum (); +create type t as enum ('a'); +create type t as enum ('a', 'b', 'c'); + +-- create_type_as_range +create type t as range ( + subtype = bigint +); + + + +-- schema +create type public.t; +create type a.b.c.d; + +-- create_type_name +create type t; + +create type t ( + input = foo.bar.func_name, + output = func_name +); + +create type t ( + input = foo.bar.func_name, + output = func_name, + receive = receive_function, + send = send_function, + typmod_in = type_modifier_input_function, + typmod_out = type_modifier_output_function, + analyze = analyze_function, + subscript = subscript_function, + internallength = variable, + passedbyvalue, + -- The allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries. + alignment = 1, + storage = plain, + like = like_type, + -- see: https://www.postgresql.org/docs/17/catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE + category = 'U', + preferred = false, + default = null, + element = float4, + delimiter = ',', + collatable = true +); + + diff --git a/crates/squawk_parser/test_data/ok/create_user.sql b/crates/squawk_parser/test_data/ok/create_user.sql new file mode 100644 index 00000000..c2a505ab --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_user.sql @@ -0,0 +1,32 @@ +-- simple +create user u; + +-- full +create user u + with superuser + nosuperuser + nosuperuser + createdb + nocreatedb + createrole + nocreaterole + inherit + noinherit + login + nologin + replication + noreplication + bypassrls + nobypassrls + connection limit 100 + encrypted password 'foo' + password 'bar' + password null + valid until '2042-02-22' + in role foo, bar, buzz + in group foo + role foo + admin foo + user foo + sysid 100; + diff --git a/crates/squawk_parser/test_data/ok/create_view.sql b/crates/squawk_parser/test_data/ok/create_view.sql new file mode 100644 index 00000000..dbbfe077 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/create_view.sql @@ -0,0 +1,45 @@ +-- docs +CREATE VIEW vista AS SELECT 'Hello World'; + +CREATE VIEW vista AS SELECT text 'Hello World' AS hello; + +CREATE VIEW comedies AS + SELECT * + FROM films + WHERE kind = 'Comedy'; + +CREATE VIEW universal_comedies AS + SELECT * + FROM comedies + WHERE classification = 'U' + WITH LOCAL CHECK OPTION; + +CREATE VIEW pg_comedies AS + SELECT * + FROM comedies + WHERE classification = 'PG' + WITH CASCADED CHECK OPTION; + +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'; + +CREATE RECURSIVE VIEW public.nums_1_100 (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums_1_100 WHERE n < 100; + +-- complete_syntax +create or replace temp recursive view foo (a, b, c) +with (foo = bar, buzz) +as select 1, 2, 3; + +create temporary view foo +as select 1, 2, 3 +with local check option; + diff --git a/crates/squawk_parser/test_data/ok/deallocate.sql b/crates/squawk_parser/test_data/ok/deallocate.sql new file mode 100644 index 00000000..5339a06a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/deallocate.sql @@ -0,0 +1,7 @@ +-- pg_docs +deallocate prepare all; + +deallocate all; + +deallocate foo; + diff --git a/crates/squawk_parser/test_data/ok/declare.sql b/crates/squawk_parser/test_data/ok/declare.sql new file mode 100644 index 00000000..6a468d17 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/declare.sql @@ -0,0 +1,16 @@ +-- pg_docs +DECLARE cursor_name CURSOR FOR SELECT * FROM t; + +-- full +declare c binary insensitive no scroll cursor without hold for select 1; + +declare c +binary +asensitive +scroll +cursor + with hold + for select 2; + +declare c cursor for select 1; + diff --git a/crates/squawk_parser/test_data/ok/delete.sql b/crates/squawk_parser/test_data/ok/delete.sql new file mode 100644 index 00000000..a19656fa --- /dev/null +++ b/crates/squawk_parser/test_data/ok/delete.sql @@ -0,0 +1,110 @@ +-- delete +-- with where +delete from products where price = 10; + +-- no where +delete from products; + +-- only +delete from only t; + +-- * +delete from t *; + +-- alias +delete from t as a; +delete from t a; + +-- using, where, return +delete from only t as a + using foo, bar + where x > 10 + returning *; + +-- using +delete from t +using foo f, b a; + +delete from t +using order_items oi + left join orders o on oi.order_id = o.id; + +delete from user_sessions us +using users u, + (select user_id, max(login_time) as last_login + from login_history + group by user_id) lh; + +-- where return +delete from t + where x > 10 + returning *; + +-- returning +delete from employees e +where e.department_id in ( + select department_id + from departments + where budget < 50000 +) +returning e.employee_id, e.name, e.department_id; + +-- cursor +delete from invoices +where current of invoice_cursor; + +-- returning +delete from t +returning *, foo + bar, foo.*; + + +-- with +with q as ( + select 1 +) +delete from t as a + using q as d + where a.id = d.id; + +with recursive q as ( + select 1 +) +delete from t as a + using q as d + where a.id = d.id; + +-- nested +with t2 as ( + with t as ( + select 1 + ) + select * from t +) +delete from t using t2; + +-- pg_docs +DELETE FROM films USING producers + WHERE producer_id = producers.id AND producers.name = 'foo'; + +DELETE FROM films + WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo'); + +DELETE FROM films WHERE kind <> 'Musical'; + +DELETE FROM films; + +DELETE FROM tasks WHERE status = 'DONE' RETURNING *; + +DELETE FROM tasks WHERE CURRENT OF c_tasks; + +WITH delete_batch AS ( + SELECT l.ctid FROM user_logs AS l + WHERE l.status = 'archived' + ORDER BY l.creation_date + FOR UPDATE + LIMIT 10000 +) +DELETE FROM user_logs AS dl + USING delete_batch AS del + WHERE dl.ctid = del.ctid; + diff --git a/crates/squawk_parser/test_data/ok/discard.sql b/crates/squawk_parser/test_data/ok/discard.sql new file mode 100644 index 00000000..02660c4e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/discard.sql @@ -0,0 +1,7 @@ +-- pg_docs +DISCARD ALL; +DISCARD PLANS; +DISCARD SEQUENCES; +DISCARD TEMPORARY; +DISCARD TEMP; + diff --git a/crates/squawk_parser/test_data/ok/do.sql b/crates/squawk_parser/test_data/ok/do.sql new file mode 100644 index 00000000..e250da70 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/do.sql @@ -0,0 +1,13 @@ +-- pg_docs +DO $$DECLARE r record; +BEGIN + FOR r IN SELECT table_schema, table_name FROM information_schema.tables + WHERE table_type = 'VIEW' AND table_schema = 'public' + LOOP + EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'; + END LOOP; +END$$; + +-- do_with_language +do language plpgsql 'select 1'; + diff --git a/crates/squawk_parser/test_data/ok/drop_access_method.sql b/crates/squawk_parser/test_data/ok/drop_access_method.sql new file mode 100644 index 00000000..c87ace5f --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_access_method.sql @@ -0,0 +1,7 @@ +-- simple +drop access method s; + +-- full +drop access method if exists a cascade; +drop access method if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_aggregate.sql b/crates/squawk_parser/test_data/ok/drop_aggregate.sql new file mode 100644 index 00000000..c36e84da --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_aggregate.sql @@ -0,0 +1,34 @@ +-- simple +drop aggregate a(*); + +-- full +drop aggregate + if exists + a(*), + foo.bar(*), + foo.bar( + in foo integer, + bar integer, + text + ), + c(*) + cascade; + +-- aggregate +drop aggregate a( + integer, + text, + numeric + order by + in a timestamp, + b numeric, + text +) restrict; + +drop aggregate foo.bar( + order by + in a timestamp, + b numeric, + text +); + diff --git a/crates/squawk_parser/test_data/ok/drop_cast.sql b/crates/squawk_parser/test_data/ok/drop_cast.sql new file mode 100644 index 00000000..4bbe9806 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_cast.sql @@ -0,0 +1,7 @@ +-- simple +drop cast (text as int); + +-- full +drop cast if exists (a as b) cascade; +drop cast if exists (foo.a as bar.b) restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_collation.sql b/crates/squawk_parser/test_data/ok/drop_collation.sql new file mode 100644 index 00000000..9b2108d6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_collation.sql @@ -0,0 +1,7 @@ +-- simple +drop collation s; + +-- full +drop collation if exists foo.b cascade; +drop collation if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_conversion.sql b/crates/squawk_parser/test_data/ok/drop_conversion.sql new file mode 100644 index 00000000..43ff3efb --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_conversion.sql @@ -0,0 +1,7 @@ +-- simple +drop conversion s; + +-- full +drop conversion if exists foo.b cascade; +drop conversion if exists buzz.b restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_database.sql b/crates/squawk_parser/test_data/ok/drop_database.sql new file mode 100644 index 00000000..11ab0659 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_database.sql @@ -0,0 +1,12 @@ +-- drop_database +drop database d; + +drop database d ( force); +drop database d with ( force, force ); + +drop database "table_name"; + +drop database if exists "table_name"; + +drop database if exists "table_name" + diff --git a/crates/squawk_parser/test_data/ok/drop_domain.sql b/crates/squawk_parser/test_data/ok/drop_domain.sql new file mode 100644 index 00000000..6a643fff --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_domain.sql @@ -0,0 +1,7 @@ +-- simple +drop domain s; + +-- full +drop domain if exists a, foo.b, c cascade; +drop domain if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_event_trigger.sql b/crates/squawk_parser/test_data/ok/drop_event_trigger.sql new file mode 100644 index 00000000..3cc17f72 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_event_trigger.sql @@ -0,0 +1,7 @@ +-- simple +drop event trigger s; + +-- full +drop event trigger if exists a cascade; +drop event trigger if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_extension.sql b/crates/squawk_parser/test_data/ok/drop_extension.sql new file mode 100644 index 00000000..ce2b218b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_extension.sql @@ -0,0 +1,7 @@ +-- simple +drop extension s; + +-- full +drop extension if exists a, b, c cascade; +drop extension if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_foreign_data.sql b/crates/squawk_parser/test_data/ok/drop_foreign_data.sql new file mode 100644 index 00000000..60092d24 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_foreign_data.sql @@ -0,0 +1,7 @@ +-- simple +drop foreign data wrapper s; + +-- full +drop foreign data wrapper if exists a, b, c cascade; +drop foreign data wrapper if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_foreign_table.sql b/crates/squawk_parser/test_data/ok/drop_foreign_table.sql new file mode 100644 index 00000000..0b1b0435 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_foreign_table.sql @@ -0,0 +1,7 @@ +-- simple +drop foreign table s; + +-- full +drop foreign table if exists a, foo.b, c cascade; +drop foreign table if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_function.sql b/crates/squawk_parser/test_data/ok/drop_function.sql new file mode 100644 index 00000000..beef8357 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_function.sql @@ -0,0 +1,7 @@ +-- simple +drop function s; + +-- full +drop function if exists a, b(text), foo.c(in f int), b(out text) cascade; +drop function if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_group.sql b/crates/squawk_parser/test_data/ok/drop_group.sql new file mode 100644 index 00000000..2c6bb872 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_group.sql @@ -0,0 +1,6 @@ +-- simple +drop group s; + +-- full +drop group if exists a, b, c; + diff --git a/crates/squawk_parser/test_data/ok/drop_index.sql b/crates/squawk_parser/test_data/ok/drop_index.sql new file mode 100644 index 00000000..b21ab813 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_index.sql @@ -0,0 +1,13 @@ +-- drop_index +drop index i; + +drop index foo.i; + +drop index concurrently if exists a, b, c cascade; + +drop index if exists d restrict; + +drop index if exists "field_name_idx"; + +drop index concurrently if exists "field_name_idx"; + diff --git a/crates/squawk_parser/test_data/ok/drop_language.sql b/crates/squawk_parser/test_data/ok/drop_language.sql new file mode 100644 index 00000000..3f7edfae --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_language.sql @@ -0,0 +1,7 @@ +-- simple +drop language s; + +-- full +drop language if exists a cascade; +drop procedural language if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_materialized_view.sql b/crates/squawk_parser/test_data/ok/drop_materialized_view.sql new file mode 100644 index 00000000..c7f4e304 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_materialized_view.sql @@ -0,0 +1,7 @@ +-- simple +drop materialized view s; + +-- full +drop materialized view if exists a, foo.b, c cascade; +drop materialized view if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_operator.sql b/crates/squawk_parser/test_data/ok/drop_operator.sql new file mode 100644 index 00000000..54aae355 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_operator.sql @@ -0,0 +1,21 @@ +-- simple +drop operator ^ (integer, integer); + +-- schema +drop operator foo.foo.^ (f.smallint, bar.smallint); + +-- unary +drop operator ~ (none, bit); + +-- multiple +drop operator ~ (none, bit), ^ (integer, integer); + +-- full +drop operator if exists # (NONE, bigint), @ (text, text), ## (none, integer) cascade; +drop operator if exists ! (int, int) restrict; + +-- non_default_operator +drop operator if exists !!!!!!!!!!!!!!!!!!! (int, int) restrict; + +drop operator bar.bar.@@@@@@@@@@@@@@@@@ (int, int) restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_operator_class.sql b/crates/squawk_parser/test_data/ok/drop_operator_class.sql new file mode 100644 index 00000000..4fc77c60 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_operator_class.sql @@ -0,0 +1,7 @@ +-- simple +drop operator class n using i; + +-- full +drop operator class if exists foo.f using i cascade; +drop operator class if exists bar.b using i restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_operator_family.sql b/crates/squawk_parser/test_data/ok/drop_operator_family.sql new file mode 100644 index 00000000..89fa10a3 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_operator_family.sql @@ -0,0 +1,7 @@ +-- simple +drop operator family n using i; + +-- full +drop operator family if exists foo.f using i cascade; +drop operator family if exists bar.b using i restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_owned.sql b/crates/squawk_parser/test_data/ok/drop_owned.sql new file mode 100644 index 00000000..2d6c4881 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_owned.sql @@ -0,0 +1,7 @@ +-- simple +drop owned by s; + +-- full +drop owned by a, current_role, c cascade; +drop owned by session_user, current_user restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_policy.sql b/crates/squawk_parser/test_data/ok/drop_policy.sql new file mode 100644 index 00000000..7558b4cf --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_policy.sql @@ -0,0 +1,7 @@ +-- simple +drop policy s on t; + +-- full +drop policy if exists r on foo.t_name cascade; +drop policy if exists r on a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_procedure.sql b/crates/squawk_parser/test_data/ok/drop_procedure.sql new file mode 100644 index 00000000..60500b47 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_procedure.sql @@ -0,0 +1,7 @@ +-- simple +drop procedure s; + +-- full +drop procedure if exists a, b(text), foo.c(in f int), b(out text) cascade; +drop procedure if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_publication.sql b/crates/squawk_parser/test_data/ok/drop_publication.sql new file mode 100644 index 00000000..df3f3f39 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_publication.sql @@ -0,0 +1,7 @@ +-- simple +drop publication s; + +-- full +drop publication if exists a, b, c cascade; +drop publication if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_role.sql b/crates/squawk_parser/test_data/ok/drop_role.sql new file mode 100644 index 00000000..78012d3c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_role.sql @@ -0,0 +1,7 @@ +-- simple +drop role s; + +-- full +drop role if exists a, b, c; +drop role if exists a, b, c; + diff --git a/crates/squawk_parser/test_data/ok/drop_routine.sql b/crates/squawk_parser/test_data/ok/drop_routine.sql new file mode 100644 index 00000000..f4668f67 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_routine.sql @@ -0,0 +1,7 @@ +-- simple +drop routine s; + +-- full +drop routine if exists a, b(text), foo.c(in f int), b(out text) cascade; +drop routine if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_rule.sql b/crates/squawk_parser/test_data/ok/drop_rule.sql new file mode 100644 index 00000000..54395f35 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_rule.sql @@ -0,0 +1,7 @@ +-- simple +drop rule s on t;; + +-- full +drop rule if exists r on foo.t_name cascade; +drop rule if exists r on a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_sequence.sql b/crates/squawk_parser/test_data/ok/drop_sequence.sql new file mode 100644 index 00000000..6986ddca --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_sequence.sql @@ -0,0 +1,7 @@ +-- simple +drop sequence s; + +-- full +drop sequence if exists a, foo.b, c cascade; +drop sequence if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_server.sql b/crates/squawk_parser/test_data/ok/drop_server.sql new file mode 100644 index 00000000..d6e809d1 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_server.sql @@ -0,0 +1,7 @@ +-- simple +drop server s; + +-- full +drop server if exists a, b, c cascade; +drop server if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_statistics.sql b/crates/squawk_parser/test_data/ok/drop_statistics.sql new file mode 100644 index 00000000..585b47a1 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_statistics.sql @@ -0,0 +1,8 @@ +-- simple +drop statistics s; + +-- full +drop statistics if exists a, foo.b, c cascade; + +drop statistics if exists a, b, c restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_subscription.sql b/crates/squawk_parser/test_data/ok/drop_subscription.sql new file mode 100644 index 00000000..3bd9d457 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_subscription.sql @@ -0,0 +1,7 @@ +-- simple +drop subscription s; + +-- full +drop subscription if exists a cascade; +drop subscription if exists a restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_table.sql b/crates/squawk_parser/test_data/ok/drop_table.sql new file mode 100644 index 00000000..052105b1 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_table.sql @@ -0,0 +1,22 @@ +drop table if exists some_table; + +-- schema +drop table if exists foo.some_table; + +-- simple +drop table t; + +-- duo +drop table a, b; + +-- schema +drop table foo.t; + +-- if exists +drop table if exists t; + +-- cascade +drop table foo, bar cascade; + +-- restrict +drop table t restrict; diff --git a/crates/squawk_parser/test_data/ok/drop_tablespace.sql b/crates/squawk_parser/test_data/ok/drop_tablespace.sql new file mode 100644 index 00000000..ede91eb5 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_tablespace.sql @@ -0,0 +1,6 @@ +-- simple +drop tablespace foo; + +-- full +drop tablespace if exists t; + diff --git a/crates/squawk_parser/test_data/ok/drop_text_search_config.sql b/crates/squawk_parser/test_data/ok/drop_text_search_config.sql new file mode 100644 index 00000000..d901503b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_text_search_config.sql @@ -0,0 +1,9 @@ +-- simple +drop text search configuration foo; + +-- full +drop text search configuration if exists bar cascade; + +-- restrict +drop text search configuration bar restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_text_search_dict.sql b/crates/squawk_parser/test_data/ok/drop_text_search_dict.sql new file mode 100644 index 00000000..f09c0955 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_text_search_dict.sql @@ -0,0 +1,9 @@ +-- simple +drop text search dictionary foo; + +-- full +drop text search dictionary if exists bar cascade; + +-- restrict +drop text search dictionary bar restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_text_search_parser.sql b/crates/squawk_parser/test_data/ok/drop_text_search_parser.sql new file mode 100644 index 00000000..21f94497 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_text_search_parser.sql @@ -0,0 +1,9 @@ +-- simple +drop text search parser foo; + +-- full +drop text search parser if exists bar cascade; + +-- restrict +drop text search parser bar restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_text_search_template.sql b/crates/squawk_parser/test_data/ok/drop_text_search_template.sql new file mode 100644 index 00000000..4e8965dc --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_text_search_template.sql @@ -0,0 +1,9 @@ +-- simple +drop text search template foo; + +-- full +drop text search template if exists bar cascade; + +-- restrict +drop text search template bar restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_transform.sql b/crates/squawk_parser/test_data/ok/drop_transform.sql new file mode 100644 index 00000000..a3ddcb21 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_transform.sql @@ -0,0 +1,9 @@ +-- simple +drop transform for text language foo; + +-- full +drop transform if exists for t language l cascade; + +-- type_args +drop transform for varchar(100) language l restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_trigger.sql b/crates/squawk_parser/test_data/ok/drop_trigger.sql new file mode 100644 index 00000000..bf4f1883 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_trigger.sql @@ -0,0 +1,10 @@ +drop trigger tr on t; + +drop trigger tr on bar.t; + +drop trigger if exists tr on t; + +drop trigger if exists tr on t cascade; + +drop trigger tr on t restrict; + diff --git a/crates/squawk_parser/test_data/ok/drop_type.sql b/crates/squawk_parser/test_data/ok/drop_type.sql new file mode 100644 index 00000000..2f97e498 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_type.sql @@ -0,0 +1,12 @@ +-- drop_type +drop type t; +drop type foo.t; +drop type a, b, c; +drop type if exists a, b, c; + +drop type if exists a cascade; +drop type a restrict; + +drop type if exists foo; + + diff --git a/crates/squawk_parser/test_data/ok/drop_user.sql b/crates/squawk_parser/test_data/ok/drop_user.sql new file mode 100644 index 00000000..1019d629 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_user.sql @@ -0,0 +1,6 @@ +-- simple +drop user foo; + +-- full +drop user if exists a, b, c; + diff --git a/crates/squawk_parser/test_data/ok/drop_user_mapping.sql b/crates/squawk_parser/test_data/ok/drop_user_mapping.sql new file mode 100644 index 00000000..c1d4ea82 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_user_mapping.sql @@ -0,0 +1,6 @@ +-- simple +drop user mapping for user server s; + +-- full +drop user mapping if exists for current_role server some_server_name; + diff --git a/crates/squawk_parser/test_data/ok/drop_view.sql b/crates/squawk_parser/test_data/ok/drop_view.sql new file mode 100644 index 00000000..dc081c43 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/drop_view.sql @@ -0,0 +1,8 @@ +-- pg_docs +DROP VIEW kinds; + +-- full +drop view if exists foo, bar, buzz cascade; + +drop view foo restrict; + diff --git a/crates/squawk_parser/test_data/ok/execute.sql b/crates/squawk_parser/test_data/ok/execute.sql new file mode 100644 index 00000000..f8454610 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/execute.sql @@ -0,0 +1,7 @@ +-- execute +EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00); + +EXECUTE usrrptplan(1, current_date); + +EXECUTE foo; + diff --git a/crates/squawk_parser/test_data/ok/explain.sql b/crates/squawk_parser/test_data/ok/explain.sql new file mode 100644 index 00000000..c66ed1e4 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/explain.sql @@ -0,0 +1,71 @@ +-- simple +explain select * from t; + +-- explain_analyze +explain analyze select a from t; + +-- all_options +explain ( + analyze, + verbose, + costs, + costs true, + costs false, + settings, + generic_plan, + buffers, + serialize, + serialize none, + serialize text, + serialize binary, + wal, + timing, + summary, + memory, + format text, + format xml, + format json, + format yaml +) +select 1; + +-- doc_example_1 +EXPLAIN (FORMAT JSON) SELECT * FROM foo; + +-- doc_example_2 +EXPLAIN SELECT * FROM foo WHERE i = 4; + +-- doc_example_3 +EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4'; + +-- doc_example_4 +EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4; + +-- doc_example_5 +EXPLAIN SELECT sum(i) FROM foo WHERE i < 10; + +-- doc_example_6 +PREPARE query(int, int) AS SELECT sum(bar) FROM test + WHERE id > $1 AND id < $2 + GROUP BY foo; + +EXPLAIN ANALYZE EXECUTE query(100, 200); + +-- doc_example_7 +EXPLAIN (GENERIC_PLAN) + SELECT sum(bar) FROM test + WHERE id > $1 AND id < $2 + GROUP BY foo; + +-- doc_example_8 +EXPLAIN (GENERIC_PLAN) + SELECT sum(bar) FROM test + WHERE id > $1::integer AND id < $2::integer + GROUP BY foo; + +-- parens_select +explain analyze (((((select 1))))); + +-- parens_values +explain analyze (((((values (1)))))); + diff --git a/crates/squawk_parser/test_data/ok/fetch.sql b/crates/squawk_parser/test_data/ok/fetch.sql new file mode 100644 index 00000000..80ec2c1a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/fetch.sql @@ -0,0 +1,21 @@ +-- pg_docs +fetch next from cursor_name; +fetch prior from cursor_name; +fetch prior in cursor_name; +fetch prior cursor_name; + +FETCH NEXT FROM cursor_name; +FETCH PRIOR FROM cursor_name; +FETCH FIRST FROM cursor_name; +FETCH LAST FROM cursor_name; +FETCH ABSOLUTE 10 FROM cursor_name; +FETCH RELATIVE 10 FROM cursor_name; +FETCH 10 FROM cursor_name; +FETCH ALL FROM cursor_name; +FETCH FORWARD FROM cursor_name; +FETCH FORWARD 10 FROM cursor_name; +FETCH FORWARD ALL FROM cursor_name; +FETCH BACKWARD FROM cursor_name; +FETCH BACKWARD 10 FROM cursor_name; +FETCH BACKWARD ALL FROM cursor_name; + diff --git a/crates/squawk_parser/test_data/ok/grant.sql b/crates/squawk_parser/test_data/ok/grant.sql new file mode 100644 index 00000000..2954edab --- /dev/null +++ b/crates/squawk_parser/test_data/ok/grant.sql @@ -0,0 +1,235 @@ +-- simple +grant select, insert, update, delete, truncate, references, trigger, maintain + on t + to current_user; + +-- on_table +grant all privileges + on table t, b, c + to current_user, current_role + with grant option + granted by public; + +grant all privileges + on t + to current_user; + +-- on_all_tables +grant all privileges + on all tables in schema foo, bar + to current_role + with grant option; + +-- columns +grant select(a, b, c) + on t + to current_user; + +grant insert(a, b, c) + on t + to current_user; + +grant update(a, b, c) + on t + to current_user; + +grant references(a, b, c) + on t + to current_user; + +grant all privileges(a) + on t + to current_user; + +grant all(a) + on t + to current_user; + +-- sequence +grant select on sequence s + to current_user; + +grant usage on sequence a, b, c + to current_user; + +grant update on sequence x + to current_user; + +grant all on all sequences in schema s + to current_user; + +grant all privileges on all sequences in schema a, b, c + to current_user; + +-- database +grant create + on database a, b, c + to current_user + with grant option; + +grant create, connect, temporary, temp + on database a + to current_user; + +grant all + on database a + to current_user; + +-- domain +grant usage + on domain a, b, c + to current_user + with grant option; + +grant all privileges + on domain d + to current_user; + +-- foreign_data +grant usage + on foreign data wrapper a, b, c + to current_user + with grant option; + +grant all privileges + on foreign data wrapper d + to current_user; + +-- foreign_server +grant usage + on foreign server a, b, c + to current_user + with grant option; + +grant all privileges + on foreign server d + to current_user; + +-- function +grant execute + on function foo, bar + to current_user + with grant option; + +grant execute + on procedure foo(in a text, out b numeric, bigint), bar(), z(int) + to current_user; + +grant all + on routine r + to current_user; + +grant all + on all functions in schema a, b, c + to current_user; + +grant all + on all procedures in schema s + to current_user; + +grant all + on all routines in schema s + to current_user; + +grant all privileges + on procedure foo(in a text, out b numeric, bigint), bar + to current_user; + +-- language +grant usage + on language foo, bar, buzz + to current_user; + +grant all + on language foo, bar, buzz + to current_user; + +grant all privileges + on language foo, bar, buzz + to current_user; + +-- large_object +grant select, update + on large object 1012, 1231 + to current_user; + +grant all privileges + on large object 1012, 1231 + to current_user; + +-- param +grant set, alter system + on parameter foo, bar, buzz + to current_user; + +grant alter system + on parameter begin + to current_user; + +grant all + on parameter begin + to current_user; + +-- edge_case +grant set, set, set + to current_user + with set option; + +grant set, set, set + to current_user; + +-- schema +grant create + on schema s + to current_user; + +grant create, usage + on schema a, b, c + to current_user, public, group foo, current_role, session_user; + +grant all + on schema a, b, c + to current_user; + +-- tablespace +grant create + on tablespace foo, bar, buzz + to current_user; + +grant all + on tablespace foo, bar, buzz + to current_user; + +-- type_ +grant usage + on type a, b, c + to current_user; + +grant all + on type t + to current_user; + +-- option +grant public + to current_user + with admin option; + +grant public + to current_user + with inherit option; + +grant public + to current_user + with inherit true; + +grant public + to current_user + with set false; + +grant public, t(a, b) + to current_user + with set option; + +grant public + to current_user; + diff --git a/crates/squawk_parser/test_data/ok/import_foreign_schema.sql b/crates/squawk_parser/test_data/ok/import_foreign_schema.sql new file mode 100644 index 00000000..e1eb178a --- /dev/null +++ b/crates/squawk_parser/test_data/ok/import_foreign_schema.sql @@ -0,0 +1,31 @@ +-- simple +import foreign schema s + from server a + into b; + +-- except +import foreign schema some_schema_name + EXCEPT (t1, t2) + FROM SERVER server_name + INTO local_schema; + +-- options +import foreign schema a + from server b + into c + options (foo 'bar'); + +-- options_multi +import foreign schema a + from server b + into c + options (foo 'bar', a 'b'); + +-- doc_example_1 +IMPORT FOREIGN SCHEMA foreign_films + FROM SERVER film_server INTO films; + +-- doc_example_2 +IMPORT FOREIGN SCHEMA foreign_films LIMIT TO (actors, directors) + FROM SERVER film_server INTO films; + diff --git a/crates/squawk_parser/test_data/ok/insert.sql b/crates/squawk_parser/test_data/ok/insert.sql new file mode 100644 index 00000000..846093a4 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/insert.sql @@ -0,0 +1,90 @@ +-- insert +insert into products values (1, 'Cheese', 9.99); + +insert into products (product_no, name, price) values (1, 'Cheese', 9.99); + +insert into products (name, price, product_no) values ('Cheese', 9.99, 1); + +insert into products default values; + +insert into products (product_no, name, price) values + (1, 'Cheese', 9.99), + (2, 'Bread', 1.99), + (3, 'Milk', 2.99); + + +insert into products (product_no, name, price) + select product_no, name, price from new_products + where release_date = 'today'; + + +-- schema_from_docs +with recursive t as ( + select * +) +insert into t as foo(a, b, c) +overriding system value select 1; + +-- pg_docs_examples +INSERT INTO films VALUES + ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes'); + +INSERT INTO films (code, title, did, date_prod, kind) + VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama'); + +INSERT INTO films VALUES + ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'); +INSERT INTO films (code, title, did, date_prod, kind) + VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama'); + +INSERT INTO films DEFAULT VALUES; + +INSERT INTO films (code, title, did, date_prod, kind) VALUES + ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'), + ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy'); + +INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07'; + +-- Create an empty 3x3 gameboard for noughts-and-crosses +INSERT INTO tictactoe (game, board[1:3][1:3]) + VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}'); +-- The subscripts in the above example aren't really needed +INSERT INTO tictactoe (game, board) + VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}'); + +INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') + RETURNING did; + +WITH upd AS ( + UPDATE employees SET sales_count = sales_count + 1 WHERE id = + (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation') + RETURNING * +) +INSERT INTO employees_log SELECT *, current_timestamp FROM upd; + +INSERT INTO distributors (did, dname) + VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') + ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname; + +INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH') + ON CONFLICT (did) DO NOTHING; + +-- Don't update existing distributors based in a certain ZIP code +INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution') + ON CONFLICT (did) DO UPDATE + SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')' + WHERE d.zipcode <> '21201'; + +-- Name a constraint directly in the statement (uses associated +-- index to arbitrate taking the DO NOTHING action) +INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design') + ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING; + +-- This statement could infer a partial unique index on "did" +-- with a predicate of "WHERE is_active", but it could also +-- just use a regular unique constraint on "did" +INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International') + ON CONFLICT (did) WHERE is_active DO NOTHING; + +-- with schema +insert into s.t (c) values (1); diff --git a/crates/squawk_parser/test_data/ok/listen.sql b/crates/squawk_parser/test_data/ok/listen.sql new file mode 100644 index 00000000..7710638d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/listen.sql @@ -0,0 +1,5 @@ +-- pg_docs +listen foo; + +LISTEN virtual; + diff --git a/crates/squawk_parser/test_data/ok/load.sql b/crates/squawk_parser/test_data/ok/load.sql new file mode 100644 index 00000000..cd8cc88d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/load.sql @@ -0,0 +1,3 @@ +-- pg_docs +load 'foo'; + diff --git a/crates/squawk_parser/test_data/ok/lock.sql b/crates/squawk_parser/test_data/ok/lock.sql new file mode 100644 index 00000000..e1187515 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/lock.sql @@ -0,0 +1,19 @@ +-- simple +lock t; + +-- table_names +lock table t, only b, c *; + +-- lock_mode +lock t in access share mode; +lock t in row share mode; +lock t in row exclusive mode; +lock t in share update exclusive mode; +lock t in share mode; +lock t in share row exclusive mode; +lock t in exclusive mode; +lock t in access exclusive mode; + +-- all +lock table t, a *, only c in row exclusive mode nowait; + diff --git a/crates/squawk_parser/test_data/ok/merge.sql b/crates/squawk_parser/test_data/ok/merge.sql new file mode 100644 index 00000000..3d7ca328 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/merge.sql @@ -0,0 +1,69 @@ +-- simple +merge into t + using u + on t.id = u.id + when matched then + do nothing; + +-- aliases_with_as +merge into foo as f + using bar as b + on f.id = b.id + when matched then + do nothing; + +-- using_rows_from +merge into t + using rows from (f(1, 2)) + on true + when matched then + do nothing; + +-- aliases_no_as +merge into foo f + using bar b + on f.id = b.id + when matched then + do nothing; + +-- table_with_star +merge into t * + using u + on t.id = u.id + when matched then + do nothing; + +-- table_with_only +merge into only t + using u + on t.id = u.id + when matched then + do nothing; + +-- paren_query +merge into only t + using (select id from bar) + on t.id = u.id + when matched then + do nothing; + +merge into only t + using (select id from bar join foo as f on f.id = bar.id) as u + on t.id = u.id + when matched then + do nothing; + +merge into only t + using (select id from bar) u + on t.id = u.id + when matched then + do nothing; + +-- when_clauses_dupe +merge into t + using u + on t.id = u.id + when matched then + do nothing + when matched then + do nothing; diff --git a/crates/squawk_parser/test_data/ok/merge_pg17.sql b/crates/squawk_parser/test_data/ok/merge_pg17.sql new file mode 100644 index 00000000..3630ff5d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/merge_pg17.sql @@ -0,0 +1,147 @@ + +-- when_clauses_all +merge into t + using u + on t.id = u.id + when not matched then + do nothing + when matched then + do nothing + when not matched by source then + do nothing; + +-- when_clauses_all_with_conditions +merge into t + using u on true + when matched and foo = bar then + do nothing + when not matched by source and bar = foo then + do nothing + when not matched and buzz = bar then + do nothing; + +-- returning_all +merge into t + using u + on t.id = u.id + when not matched then + do nothing + when matched then + do nothing + when not matched by source then + do nothing + returning *; + +-- returning_many +merge into t + using u + on t.id = u.id + when not matched then + do nothing + when matched then + do nothing + when not matched by source then + do nothing + returning *, u as bar, t b, merge_action(), t.*; + +-- merge_insert_simple +merge into t + using u + on t.id = u.id + when not matched then + insert + default values; + +-- merge_insert_default +merge into t + using u + on t.id = u.id + when not matched then + insert (a, b, c) + overriding user value + default values; + +-- merge_insert_values +merge into t + using u + on t.id = u.id + when not matched then + insert + overriding system value + values (1, 2, default, 3, 10 * 10 + 2); + +-- merge_update +merge into t + using u + on t.id = u.id + when matched then + update set + a = default, + b = 1, + c = d, + e = (select 1), + f = row(1, 2, default), + g = (1, 2, default), + h = (default) + when not matched by source then + update set foo = bar; + +-- merge_delete +merge into t + using u + on t.id = u.id + when matched then + delete + when not matched by source then + delete; + +-- with_select +with t as (select 1, 2, 3) +merge into u + using t + on t.id = u.id + when matched then + do nothing; + +-- doc_example_1 +MERGE INTO customer_account ca +USING recent_transactions t +ON t.customer_id = ca.customer_id +WHEN MATCHED THEN + UPDATE SET balance = balance + transaction_value +WHEN NOT MATCHED THEN + INSERT (customer_id, balance) + VALUES (t.customer_id, t.transaction_value); + +-- doc_example_2 +MERGE INTO customer_account ca +USING (SELECT customer_id, transaction_value FROM recent_transactions) AS t +ON t.customer_id = ca.customer_id +WHEN MATCHED THEN + UPDATE SET balance = balance + transaction_value +WHEN NOT MATCHED THEN + INSERT (customer_id, balance) + VALUES (t.customer_id, t.transaction_value); + +-- doc_example_3 +MERGE INTO wines w +USING wine_stock_changes s +ON s.winename = w.winename +WHEN NOT MATCHED AND s.stock_delta > 0 THEN + INSERT VALUES(s.winename, s.stock_delta) +WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN + UPDATE SET stock = w.stock + s.stock_delta +WHEN MATCHED THEN + DELETE +RETURNING merge_action(), w.*; + +-- doc_example_4 +MERGE INTO wines w +USING new_wine_list s +ON s.winename = w.winename +WHEN NOT MATCHED BY TARGET THEN + INSERT VALUES(s.winename, s.stock) +WHEN MATCHED AND w.stock != s.stock THEN + UPDATE SET stock = s.stock +WHEN NOT MATCHED BY SOURCE THEN + DELETE; diff --git a/crates/squawk_parser/test_data/ok/misc.sql b/crates/squawk_parser/test_data/ok/misc.sql new file mode 100644 index 00000000..8f2cf2e7 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/misc.sql @@ -0,0 +1,759 @@ +-- https://www.timescale.com/blog/boosting-postgres-insert-performance/ +CREATE TABLE sensors ( + sensorid TEXT, + ts TIMESTAMPTZ, + value FLOAT8 +); +INSERT INTO sensors (ts, sensorid, value) + SELECT * + FROM unnest( + $1::timestamptz[], + $2::text[], + $3::float8[] +); +INSERT INTO sensors (sensorid, ts, value) +VALUES + ($1, $2, $3), + ($4, $5, $6), + -- ..., + ($2998, $2999, $3000); + + +-- https://www.timescale.com/blog/combining-semantic-search-and-full-text-search-in-postgresql-with-cohere-pgvector-and-pgai/ +UPDATE movies +SET embedding = ai.cohere_embed( + 'embed-english-v3.0' + , CONCAT_WS('. ', + title, + COALESCE(overview, '') + ) + , input_type=>'search_document' + -- , api_key=>%s + , api_key=>$1 +) where embedding is null; + +SELECT title, overview +FROM movies, plainto_tsquery('english', $1) query +WHERE to_tsvector('english', title || ' ' || COALESCE(overview, '')) @@ query +ORDER BY ts_rank_cd(to_tsvector('english', title || ' ' || COALESCE(overview, '')), query) DESC +LIMIT 5; + +WITH query_embedding AS ( + SELECT cohere_embed( + 'embed-english-v3.0' + , $1 + , _input_type=>'search_query' + -- , _api_key=>%s + , _api_key=>$2 + ) AS embedding +) +SELECT title, overview +FROM movies, query_embedding +ORDER BY movies.embedding <=> query_embedding.embedding +LIMIT 5; + +SELECT + x."index", + x.document->>'text' as "text", + x.relevance_score +FROM jsonb_to_recordset( + ai.cohere_rerank( + 'rerank-english-v3.0', + -- %s, + $1, + -- %s::jsonb, + $2::jsonb, + return_documents => true, + -- api_key=>%s + api_key=>$3 + )->'results' +) AS x("index" int, "document" jsonb, relevance_score float8) +ORDER BY relevance_score DESC +LIMIT 5; + + +-- https://www.depesz.com/2024/11/15/grouping-data-into-array-of-sums-fun-with-custom-aggregates/ +CREATE FUNCTION sum_per_hour( INOUT p_state int8[], IN p_hour int4, IN p_count int4 ) RETURNS int8[] LANGUAGE plpgsql AS $$ +DECLARE +BEGIN + -- sanity checks + IF p_hour < 0 THEN + raise exception 'Hour can''t be < 0 : %', p_hour; + END IF; + IF p_hour > 23 THEN + raise exception 'Hour can''t be > 23 : %', p_hour; + END IF; + + -- actual count modification + p_state[ p_hour ] := p_state[ p_hour ] + p_count; + + RETURN; +END; +$$; + +SELECT sum_per_hour( '[0:23]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}', 1, 15 ); + +CREATE aggregate sum_per_hour( int4, int4 ) ( + sfunc = sum_per_hour, + stype = int8[], + initcond = '[0:23]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}' +); + +SELECT + category_id, + object_id, + date_trunc( 'day', interaction_ts ) AS interaction_date, + sum_per_hour( EXTRACT( 'hour' FROM interaction_ts)::int4, interaction_count ) FILTER (WHERE interaction_type = 'a') AS a_counts, + sum_per_hour( EXTRACT( 'hour' FROM interaction_ts)::int4, interaction_count ) FILTER (WHERE interaction_type = 'b') AS b_counts +FROM + input_data +GROUP BY 1, 2, 3 +ORDER BY 1, 2, 3; + +CREATE FUNCTION sum_hour_arrays( IN p_left int8[], IN p_right int8[] ) RETURNS int8[] AS $$ +DECLARE + i int4; + v_result int8[]; +BEGIN + FOR i IN 0..23 LOOP + v_result[i] := p_left[i] + p_right[i]; + END LOOP; + RETURN v_result; +END; +$$ LANGUAGE plpgsql; + + +-- https://www.crunchydata.com/blog/postgres-partitioning-with-a-default-partition + +INSERT INTO partman_test.time_taptest_table (col3) VALUES ('2024-12-25'::date); + +CREATE TABLE partman_test.time_taptest_table_default PARTITION OF partman_test.time_taptest_table DEFAULT; + +INSERT INTO partman_test.time_taptest_table (col3) VALUES ('2024-12-25'::date); + +SELECT * FROM partman_test.time_taptest_table_default; + +Table "partman_test.time_taptest_table_p20241124"; + +Table "partman_test.time_taptest_table_default"; + +CREATE TABLE partman_test.time_taptest_table_p20241225 PARTITION OF partman_test.time_taptest_table FOR VALUES FROM ('2024-12-25') TO ('2024-12-26'); + +BEGIN; + +CREATE TEMP TABLE clean_default_temp (LIKE partman_test.time_taptest_table_default); + +WITH partition_data AS ( + DELETE FROM partman_test.time_taptest_table_default RETURNING * +) +INSERT INTO clean_default_temp (col1, col2, col3) SELECT col1, col2, col3 FROM partition_data; + +CREATE TABLE partman_test.time_taptest_table_p20241225 PARTITION OF partman_test.time_taptest_table FOR VALUES FROM ('2024-12-25') TO ('2024-12-26'); + +WITH partition_data AS ( + DELETE FROM clean_default_temp RETURNING * +) +INSERT INTO partman_test.time_taptest_table (col1, col2, col3) SELECT col1, col2, col3 FROM partition_data; + +DROP TABLE clean_default_temp; + +COMMIT; + +SELECT * FROM partman_test.time_taptest_table_default ; + +SELECT * FROM partman_test.time_taptest_table; + +SELECT * FROM partman_test.time_taptest_table_p20241225 ; + +SELECT * FROM partman.check_default(); + +SELECT * FROM partman.check_default(false); + +select * from partman_test.time_taptest_table_default; + +CALL partman.partition_data_proc('partman_test.time_taptest_table'); + +VACUUM ANALYZE partman_test.time_taptest_table; + +SELECT * FROM partman.partition_gap_fill('partman_test.time_taptest_table'); + + +-- https://www.crunchydata.com/blog/smarter-postgres-llm-with-retrieval-augmented-generation +SELECT openai.prompt( + 'You are a science fiction expert!', + 'What is the Star Trek episode where Deanna and her + mother are kidnapped?' +); + +CREATE TABLE tng ( + title text, + plot text + ); + +COPY tng (title, plot) + FROM PROGRAM 'curl https://raw.githubusercontent.com/pramsey/pgsql-openai/refs/heads/main/examples/rag/tng.txt' + WITH ( + FORMAT csv, + DELIMITER E'\t' + ); + +-- Enable pgvector +CREATE EXTENSION pgvector; + +-- Add an emedding column to the table +ALTER TABLE tng + ADD COLUMN vec vector; + +-- Populate the column with embeddings from an LLM model +UPDATE tng + SET vec = openai.vector(title || ' -- ' || plot)::vector; + +SELECT title +FROM tng +ORDER BY vec <-> (SELECT openai.vector('What is the Star Trek episode where Deanna and her mother are kidnapped?')::vector) +LIMIT 5; + +CREATE OR REPLACE FUNCTION trektrivia(query_text TEXT) + RETURNS TEXT + LANGUAGE 'plpgsql' AS $$ +DECLARE + query_embedding VECTOR; + context_chunks TEXT; +BEGIN + -- Step 1: Get the embedding vector for the query text + query_embedding := openai.vector(query_text)::VECTOR; + + -- Step 2: Find the 5 closest plot summaries to the query embedding + -- Step 3: Lump together results into a context lump + SELECT string_agg('Episode: { Title: ' || title || ' } Summary: {' || plot, E'}}\n\n\n') INTO context_chunks + FROM ( + SELECT plot, title + FROM tng + ORDER BY vec <-> query_embedding + LIMIT 5 + ) AS similar_plots; + + -- Step 4: Run the query against the LLM with the augmented context + RETURN openai.prompt(context_chunks, query_text); +END; +$$; + +SELECT trektrivia('What is the Star Trek episode where Deanna and her mother are kidnapped?'); + + +-- https://www.crunchydata.com/blog/pg_incremental-incremental-data-processing-in-postgres + +/* define the raw data and summary table */ +create table events (event_id bigserial, event_time timestamptz, user_id bigint, response_time double precision); +create table view_counts (day timestamptz, user_id bigint, count bigint, primary key (day, user_id)); + +/* enable fast range scans on the sequence column */ +create index on events using brin (event_id); + +/* for demo: generate some random data */ +insert into events (event_time, user_id, response_time) +select now(), random() * 100, random() from generate_series(1,1000000) s; + +/* define a sequence pipeline that periodically upserts view counts */ +select incremental.create_sequence_pipeline('view-count-pipeline', 'events', + $$ + insert into view_counts + select date_trunc('day', event_time), user_id, count(*) + from events where event_id between $1 and $2 + group by 1, 2 + on conflict (day, user_id) do update set count = view_counts.count + EXCLUDED.count; + $$ +); + +/* get the most active users of today */ +select user_id, sum(count) from view_counts where day = now()::date group by 1 order by 2 desc limit 3; + + +/* create a table with a single JSONB column and a sequence to track new objects */ +create table events_json (id bigint generated by default as identity, payload jsonb); +create index on events_json using brin (id); + +/* load some data from a local newline-delimited JSON file */ +-- \copy events_json (payload) from '2024-12-15-00.json' with (format 'csv', quote e'\x01', delimiter e'\x02', escape e'\x01') + + +/* periodically unpack the new JSON objects into the events table */ +select incremental.create_sequence_pipeline('unpack-json-pipeline', 'events_json', + $$ + insert into events (event_id, event_time, user_id, response_time) + select + nextval('events_event_id_seq'), + (payload->>'created_at')::timestamptz, + (payload->'actor'->>'id')::bigint, + (payload->>'response_time')::double precision + from events_json + where id between $1 and $2 + $$ +); + + +/* create a table for number of active users per hour */ +create table user_counts (hour timestamptz, user_count bigint, primary key (hour)); + +/* enable fast range scans on the event_time column */ +create index on events using brin (event_time); + +/* aggregates a range of 1 hour intervals after an hour has passed */ +select incremental.create_time_interval_pipeline('distinct-user-count', '1 hour', + $$ + insert into view_counts + select date_trunc('hour', event_time), count(distinct user_id) + from events where event_time >= $1 and event_time < $2 + group by 1 + $$ +); + +/* get number of active users per hour */ +select hour, user_count from user_counts order by 1; + +/* define a function that wraps a COPY TO command to export data */ +create or replace function export_events(start_time timestamptz, end_time timestamptz) +returns void language plpgsql as $function$ begin + + /* select all rows in a time range and export them to a Parquet file */ + execute format( + 'copy (select * from events where event_time >= %L and event_time < %L) to %L', + start_time, end_time, format('s3://mybucket/events/%s.parquet', start_time::date) + ); + +end; $function$; + +/* export data as 1 file per day, starting at Jan 1st */ +select incremental.create_time_interval_pipeline( + 'export-events', + '1 day', + 'select export_events($1, $2)', + + source_table_name := 'events', /* wait for writes on events to finish */ + batched := false, /* separate execution for each day */ + start_time := '2024-01-01' /* export all days from Jan 1st now */ +); + + +/* define function that wraps a COPY FROM command to import data */ +create or replace function import_events(path text) +returns void language plpgsql as $function$ begin + + /* load a file into the events table */ + execute format('copy events from %L', path); + +end; $function$; + +/* load all the files under a prefix, and automatically load new files, one at a time */ +select incremental.create_file_list_pipeline( + 'import-events', + 's3://mybucket/events/*.csv', + 'select import_events($1)' +); + +select jobname, start_time, status, return_message +from cron.job_run_details join cron.job using (jobid) +where jobname like 'pipeline:event-import%' order by 1 desc limit 3; + +-- https://supabase.com/blog/calendars-in-postgres-using-foreign-data-wrappers + +create foreign data wrapper wasm_wrapper + handler wasm_fdw_handler + validator wasm_fdw_validator; + +create server cal_server + foreign data wrapper wasm_wrapper + options ( + fdw_package_url 'https://github.com/supabase/wrappers/releases/download/wasm_cal_fdw_v0.1.0/cal_fdw.wasm', + fdw_package_name 'supabase:cal-fdw', + fdw_package_version '0.1.0', + fdw_package_checksum '4afe4fac8c51f2caa1de8483b3817d2cec3a14cd8a65a3942c8b4ff6c430f08a', + api_key '' + ); + +create schema if not exists cal; + +create foreign table cal.event_types ( + attrs jsonb +) + server cal_server + options ( + object 'event-types' + ); + +create foreign table cal.bookings ( + attrs jsonb +) + server cal_server + options ( + object 'bookings', + rowid_column 'attrs' + ); + +-- extract event types +select + etg->'profile'->>'name' as profile, + et->>'id' as id, + et->>'title' as title +from cal.event_types t + cross join json_array_elements((attrs->'eventTypeGroups')::json) etg + cross join json_array_elements((etg->'eventTypes')::json) et; + +-- extract bookings +select + bk->>'id' as id, + bk->>'title' as title, + bk->'responses'->>'name' as name, + bk->>'startTime' as start_time +from cal.bookings t + cross join json_array_elements((attrs->'bookings')::json) bk; + +-- make a 15 minutes meeting with Elon Musk +insert into cal.bookings(attrs) +values ( + '{ + "start": "2025-01-01T23:30:00.000Z", + "eventTypeId": 1398027, + "attendee": { + "name": "Elon Musk", + "email": "elon.musk@x.com", + "timeZone": "America/New_York" + } + }'::jsonb +); + + +-- https://www.tinybird.co/blog-posts/outgrowing-postgres-how-to-run-olap-workloads-on-postgres + +CREATE MATERIALIZED VIEW hourly_stats AS +SELECT + date_trunc('hour', event_time) as hour, + count(*) as events, + count(distinct user_id) as users +FROM events GROUP BY 1; +CREATE UNIQUE INDEX ON hourly_stats(hour); + +CREATE TABLE events ( + event_time timestamptz, + user_id int, + event_type text +) PARTITION BY RANGE (event_time); + +CREATE TABLE events ( + -- Frequently queried columns + event_time timestamptz, + user_id int, + event_type text, + -- Rarely queried metadata + user_agent text, + ip_address inet, + -- Large payload rarely used in aggregations + event_data jsonb +); + +CREATE TABLE events_core ( + event_id bigserial PRIMARY KEY, + event_time timestamptz, + user_id int, + event_type text); + +CREATE TABLE events_metadata ( + event_id bigint PRIMARY KEY REFERENCES events_core, + user_agent text, + ip_address inet +); + +CREATE TABLE events_payload ( + event_id bigint PRIMARY KEY REFERENCES events_core, + event_data jsonb +); + +-- -- Instead of one simple insert +-- INSERT INTO events VALUES (...); + +-- -- You now need transaction-wrapped multi-table inserts +-- BEGIN; +-- INSERT INTO events_core (...) RETURNING event_id; +-- INSERT INTO events_metadata (...); +-- INSERT INTO events_payload (...); +-- COMMIT; + +-- Simple query becomes a three-way join +SELECT e.event_time, e.event_type, m.user_agent, p.event_data +FROM events_core e +LEFT JOIN events_metadata m + ON e.event_id = m.event_id +LEFT JOIN events_payload p + ON e.event_id = p.event_id +WHERE e.event_time >= now() - interval '1 day'; + +CREATE EXTENSION cstore_fdw; + +CREATE SERVER cstore_server FOREIGN DATA WRAPPER cstore_fdw; + +CREATE FOREIGN TABLE metrics_columnar ( + day date, + metric_name text, + value numeric) SERVER cstore_server +OPTIONS(compression 'pglz'); + +CREATE EXTENSION pg_analytics; + +CREATE FOREIGN TABLE metrics ( + day date, + metric_name text, + value numeric +) SERVER parquet_server +OPTIONS (files 's3://bucket/metrics/*.parquet'); + +CREATE EXTENSION pg_duckdb; + +CREATE TABLE metrics ( + day date, + metric_name text, + value numeric +) USING duckdb; + +CREATE EXTENSION pg_mooncake; + +CREATE TABLE metrics ( + day date, + metric_name text, + value numeric +) USING columnstore; + +-- Instead of this complex self-join +SELECT + month, + revenue, + ( + SELECT AVG(revenue) + FROM monthly_revenues m2 + WHERE m2.month <= m1.month + AND m2.month > m1.month - interval '3 months' + ) as rolling_avg +FROM monthly_revenues m1; + +-- Use this cleaner window function +SELECT + month, + revenue, + AVG(revenue) OVER ( + ORDER BY month + ROWS BETWEEN 2 PRECEDING AND CURRENT ROW + ) as rolling_avg +FROM monthly_revenues; + +SELECT + date_trunc('month', timestamp) as month, + customer_segment, + SUM(revenue) as revenue, + SUM(SUM(revenue)) OVER ( + PARTITION BY customer_segment + ORDER BY date_trunc('month', timestamp) + ) as running_total +FROM transactions +GROUP BY 1, 2; + +-- Use CTEs to break down complex analytics +WITH monthly_stats AS ( + SELECT + date_trunc('month', timestamp) as month, + COUNT(DISTINCT user_id) as users, + SUM(revenue) as revenue + FROM events + WHERE timestamp >= NOW() - interval '12 months' + GROUP BY 1 +), +user_segments AS ( + SELECT + user_id, + CASE + WHEN lifetime_value > 1000 THEN 'high' + WHEN lifetime_value > 100 THEN 'medium' + ELSE 'low' + END as segment + FROM users +) +SELECT + month, + segment, + COUNT(DISTINCT e.user_id) as users, + SUM(revenue) as revenue +FROM events e +JOIN user_segments s + ON e.user_id = s.user_id +GROUP BY 1, 2; + +EXPLAIN ANALYZE +SELECT + date_trunc('month', timestamp) as month, + COUNT(*) as events, + COUNT(DISTINCT user_id) as users +FROM events +GROUP BY 1; + +-- Key settings for parallel queries +SET max_parallel_workers_per_gather = 4; -- Workers per query +SET parallel_setup_cost = 10; -- Lower = more parallelism +SET parallel_tuple_cost = 0.001; -- Lower = more parallelism +SET min_parallel_table_scan_size = '8MB'; -- Table size threshold + +-- Get detailed buffering info +EXPLAIN (ANALYZE, BUFFERS) +SELECT /* your query */; + +-- Look for: +-- "Parallel Seq Scan" - Is parallelism being used? +-- "Hash Join" vs "Nested Loop" - Right join strategy? +-- "Sort Method: quicksort" vs "external sort" - Enough work_mem? +-- "Rows Removed by Filter" - Could an index help? + +-- Sorts intermediate results unnecessarily +SELECT user_id, COUNT(*) +FROM ( + SELECT DISTINCT user_id + FROM events + ORDER BY timestamp +) t +GROUP BY 1; + +-- Remove unnecessary ORDER BY +SELECT user_id, COUNT(*) +FROM ( + SELECT DISTINCT user_id + FROM events +) t +GROUP BY 1; + +-- Gets all rows then filters +SELECT user_id, status +FROM user_status +WHERE (user_id, timestamp) IN ( + SELECT user_id, MAX(timestamp) + FROM user_status + GROUP BY user_id +); + +-- Uses DISTINCT ON +SELECT DISTINCT ON (user_id) + user_id, status +FROM user_status +ORDER BY user_id, timestamp DESC; + +CREATE INDEX idx_events_month ON events ( + date_trunc('month', timestamp) +); + +CREATE INDEX event_logs_ts_brin ON event_logs +USING brin(timestamp) WITH (pages_per_range = 128); + +SELECT corr(ctid::text::float8, timestamp::text::float8) FROM event_logs; + +-- https://www.crunchydata.com/blog/indexing-materialized-views-in-postgres +CREATE MATERIALIZED VIEW recent_product_sales AS +SELECT + p.sku, + SUM(po.qty) AS total_quantity +FROM + products p + JOIN product_orders po ON p.sku = po.sku + JOIN orders o ON po.order_id = o.order_id +WHERE + o.status = 'Shipped' +GROUP BY + p.sku +ORDER BY + 2 DESC; + +CREATE INDEX sku_index ON recent_product_sales (sku); + +REFRESH MATERIALIZED VIEW recent_product_sales; + +CREATE UNIQUE INDEX unique_idx_recent_product_sales ON recent_product_sales(sku); + +DROP INDEX sku_index; + +REFRESH MATERIALIZED VIEW CONCURRENTLY recent_product_sales; + + +-- https://www.timescale.com/blog/iot-renewable-energy-models-building-the-future-with-time-series-data +-- Example time series data structure for a solar panel +CREATE TABLE solar_panel_metrics ( + time TIMESTAMPTZ NOT NULL, + panel_id TEXT, + voltage DOUBLE PRECISION, + current DOUBLE PRECISION, + temperature DOUBLE PRECISION, + irradiance DOUBLE PRECISION +); + +-- Create a hypertable for efficient time series operations +SELECT create_hypertable('solar_panel_metrics', 'time'); + +-- Calculate daily energy production and compare with expected output +SELECT + time_bucket('1 day', time) AS day, + panel_id, + avg(voltage * current) AS actual_power, + expected_power, + ((avg(voltage * current) / expected_power) * 100) AS performance_ratio +FROM solar_panel_metrics +JOIN panel_specifications ON panel_id = specs_id +WHERE time > now() - INTERVAL '30 days' +GROUP BY day, panel_id, expected_power +HAVING performance_ratio < 90; + +-- Detect abnormal vibration patterns in wind turbines +WITH baseline_stats AS ( + SELECT + turbine_id, + avg(vibration_level) as avg_vibration, + stddev(vibration_level) as stddev_vibration + FROM turbine_metrics + WHERE time > now() - INTERVAL '90 days' + GROUP BY turbine_id +) +SELECT + time_bucket('5 minutes', time) AS bucket, + turbine_id, + vibration_level, + (vibration_level - avg_vibration) / stddev_vibration AS z_score +FROM turbine_metrics t +JOIN baseline_stats b USING (turbine_id) +WHERE + time > now() - INTERVAL '1 day' + AND abs((vibration_level - avg_vibration) / stddev_vibration) > 2; + +-- Monitor aggregate power availability across resources +SELECT + time_bucket('5 minutes', time) AS interval, + resource_type, + sum(available_power) AS total_power, + sum(storage_capacity) AS total_storage +FROM vpp_resources +WHERE time > now() - INTERVAL '1 hour' +GROUP BY interval, resource_type +ORDER BY interval DESC; + +-- Identify optimal trading windows +WITH price_analysis AS ( + SELECT + time_bucket('1 hour', time) AS hour, + avg(price) AS avg_price, + percentile_cont(0.75) WITHIN GROUP (ORDER BY price) AS price_75th + FROM energy_prices + WHERE time > now() - INTERVAL '30 days' + GROUP BY hour +) +SELECT + hour, + avg_price, + price_75th, + CASE + WHEN avg_price > price_75th THEN 'SELL' + WHEN avg_price < price_75th THEN 'BUY' + ELSE 'HOLD' + END AS trading_signal +FROM price_analysis +ORDER BY hour; diff --git a/crates/squawk_parser/test_data/ok/move.sql b/crates/squawk_parser/test_data/ok/move.sql new file mode 100644 index 00000000..3a4c534d --- /dev/null +++ b/crates/squawk_parser/test_data/ok/move.sql @@ -0,0 +1,21 @@ +-- pg_docs +move next from cursor_name; +move prior from cursor_name; +move prior in cursor_name; +move prior cursor_name; + +move NEXT FROM cursor_name; +move PRIOR FROM cursor_name; +move FIRST FROM cursor_name; +move LAST FROM cursor_name; +move ABSOLUTE 10 FROM cursor_name; +move RELATIVE 10 FROM cursor_name; +move 10 FROM cursor_name; +move ALL FROM cursor_name; +move FORWARD FROM cursor_name; +move FORWARD 10 FROM cursor_name; +move FORWARD ALL FROM cursor_name; +move BACKWARD FROM cursor_name; +move BACKWARD 10 FROM cursor_name; +move BACKWARD ALL FROM cursor_name; + diff --git a/crates/squawk_parser/test_data/ok/notify.sql b/crates/squawk_parser/test_data/ok/notify.sql new file mode 100644 index 00000000..0beddaa3 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/notify.sql @@ -0,0 +1,4 @@ +-- notify_stmt +NOTIFY foo; +NOTIFY virtual, 'This is the payload'; + diff --git a/crates/squawk_parser/test_data/ok/precedence.sql b/crates/squawk_parser/test_data/ok/precedence.sql new file mode 100644 index 00000000..c115d1f4 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/precedence.sql @@ -0,0 +1,9 @@ +-- see: https://github.com/postgres/postgres/blob/028b4b21df26fee67b3ce75c6f14fcfd3c7cf2ee/src/backend/parser/gram.y#L12699 +SELECT (((SELECT 2)) + 3); +SELECT (((SELECT 2)) UNION SELECT 2); + + +-- TODO! +SELECT foo UNION SELECT bar ORDER BY baz; +-- equal to: +(SELECT foo UNION SELECT bar) ORDER BY baz; diff --git a/crates/squawk_parser/test_data/ok/prepare.sql b/crates/squawk_parser/test_data/ok/prepare.sql new file mode 100644 index 00000000..8866a8d6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/prepare.sql @@ -0,0 +1,35 @@ +-- insert +PREPARE fooplan (int, text, bool, numeric) AS + INSERT INTO foo VALUES($1, $2, $3, $4); + + + +-- select +PREPARE usrrptplan (int) AS + SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid + AND l.date = $2; + +PREPARE foo AS + with t as (select 1) + select * from t; + +-- update +prepare foo as + update foo set x = 1 where x > 10; + +-- delete +prepare foo as + delete from foo where x = 1; + +-- merge +prepare foo as + merge into t1 + using t2 on t2.id = t1.id + when matched then do nothing + when not matched by source then do nothing + when not matched then do nothing; + +-- values +prepare foo as + values (1, 'one'), (2, 'two'); + diff --git a/crates/squawk_parser/test_data/ok/reassign.sql b/crates/squawk_parser/test_data/ok/reassign.sql new file mode 100644 index 00000000..ef0ccebb --- /dev/null +++ b/crates/squawk_parser/test_data/ok/reassign.sql @@ -0,0 +1,5 @@ +-- simple +reassign owned by set, current_role, current_user, foo to session_user; + +reassign owned by current_user to current_role; + diff --git a/crates/squawk_parser/test_data/ok/refresh.sql b/crates/squawk_parser/test_data/ok/refresh.sql new file mode 100644 index 00000000..91a8df2b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/refresh.sql @@ -0,0 +1,7 @@ +-- simple +REFRESH MATERIALIZED VIEW order_summary; + +REFRESH MATERIALIZED VIEW annual_statistics_basis WITH NO DATA; + +refresh materialized view concurrently v with data; + diff --git a/crates/squawk_parser/test_data/ok/reindex.sql b/crates/squawk_parser/test_data/ok/reindex.sql new file mode 100644 index 00000000..234a8acd --- /dev/null +++ b/crates/squawk_parser/test_data/ok/reindex.sql @@ -0,0 +1,16 @@ +-- pg_docs +REINDEX INDEX my_index; + +REINDEX TABLE my_table; + +REINDEX TABLE CONCURRENTLY my_broken_table; + +-- complete_syntax +reindex (concurrently true, tablespace fooo, verbose false) database concurrently foo; + +reindex system foo; + +reindex index foo; +reindex table foo; +reindex schema foo; + diff --git a/crates/squawk_parser/test_data/ok/reset.sql b/crates/squawk_parser/test_data/ok/reset.sql new file mode 100644 index 00000000..cddd5555 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/reset.sql @@ -0,0 +1,4 @@ +-- pg_docs +reset some_config_param; +reset all; + diff --git a/crates/squawk_parser/test_data/ok/revoke.sql b/crates/squawk_parser/test_data/ok/revoke.sql new file mode 100644 index 00000000..06c1fc3b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/revoke.sql @@ -0,0 +1,222 @@ +-- simple +revoke select, insert, update, delete, truncate, references, trigger, maintain + on t + from current_user; + +-- on_table +revoke grant option for + all privileges + on table t, b, c + from current_user, current_role + granted by public + cascade; + +revoke grant option for all privileges + on t + from current_user; + +-- on_all_tables +revoke grant option for + all privileges + on all tables in schema foo, bar + from current_role + restrict; + +-- columns +revoke select(a, b, c) + on t + from current_user; + +revoke insert(a, b, c) + on t + from current_user; + +revoke update(a, b, c) + on t + from current_user; + +revoke references(a, b, c) + on t + from current_user; + +revoke all privileges(a) + on t + from current_user; + +revoke all(a) + on t + from current_user; + +-- sequence +revoke select on sequence s + from current_user; + +revoke usage on sequence a, b, c + from current_user; + +revoke update on sequence x + from current_user; + +revoke all on all sequences in schema s + from current_user; + +revoke all privileges on all sequences in schema a, b, c + from current_user; + +-- database +revoke grant option for create + on database a, b, c + from current_user; + +revoke create, connect, temporary, temp + on database a + from current_user; + +revoke all + on database a + from current_user; + +-- domain +revoke grant option for usage + on domain a, b, c + from current_user; + +revoke all privileges + on domain d + from current_user; + +-- foreign_data +revoke grant option for usage + on foreign data wrapper a, b, c + from current_user; + +revoke all privileges + on foreign data wrapper d + from current_user; + +-- foreign_server +revoke grant option for usage + on foreign server a, b, c + from current_user; + +revoke all privileges + on foreign server d + from current_user; + +-- function +revoke grant option for execute + on function foo, bar + from current_user; + +revoke execute + on procedure foo(in a text, out b numeric, bigint), bar(), z(int) + from current_user; + +revoke all + on routine r + from current_user; + +revoke all + on all functions in schema a, b, c + from current_user; + +revoke all + on all procedures in schema s + from current_user; + +revoke all + on all routines in schema s + from current_user; + +revoke all privileges + on procedure foo(in a text, out b numeric, bigint), bar + from current_user; + +-- language +revoke usage + on language foo, bar, buzz + from current_user; + +revoke all + on language foo, bar, buzz + from current_user; + +revoke all privileges + on language foo, bar, buzz + from current_user; + +-- large_object +revoke select, update + on large object 1012, 1231 + from current_user; + +revoke all privileges + on large object 1012, 1231 + from current_user; + +-- param +revoke set, alter system + on parameter foo, bar, buzz + from current_user; + +revoke alter system + on parameter begin + from current_user; + +revoke all + on parameter begin + from current_user; + +-- edge_case +revoke set option for + set, set, set from current_user; + +revoke set, set, set from current_user; + +-- schema +revoke create + on schema s + from current_user; + +revoke create, usage + on schema a, b, c + from current_user; + +revoke all + on schema a, b, c + from current_user; + +-- tablespace +revoke create + on tablespace foo, bar, buzz + from current_user; + +revoke all + on tablespace foo, bar, buzz + from current_user; + +-- type_ +revoke usage + on type a, b, c + from current_user; + +revoke all + on type t + from current_user; + +-- option +revoke admin option for + public + from current_user; + +revoke inherit option for + public + from current_user; + +revoke set option for + public + from current_user; + +revoke public + from current_user; + diff --git a/crates/squawk_parser/test_data/ok/schemas.sql b/crates/squawk_parser/test_data/ok/schemas.sql new file mode 100644 index 00000000..d83fc195 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/schemas.sql @@ -0,0 +1,67 @@ +-- create_schema +create schema myschema; +create schema s authorization foo; +create schema s authorization current_role; +create schema s authorization current_user; +create schema s authorization session_user; + +create schema authorization foo; + +create schema if not exists s; +create schema if not exists s authorization bar; +create schema if not exists authorization bar; + +create schema s + create table t (a int, b text) + create table t1 (z int8); + +table schema.table; +table database.schema.table; + +drop schema myschema; +drop schema myschema cascade; +drop schema if exists myschema restrict; +drop schema if exists a, b, c; + +create schema schema_name authorization user_name; + +-- create_schema_with_sequence +create schema s + create sequence s; + +-- create_schema_with_trigger +create schema s + create trigger t after insert + on u + execute function f(); + +-- search_path +show search_path; + +set search_path to myschema,public; + +set search_path to myschema; + +set foo = bar; + +set time zone 'America/Los_Angeles'; +set time zone default; +set time zone local; + +set foo = default; +set foo to a, 10.0, 1, 'foo', true, false; + +-- operator +-- binary +select 3 operator(pg_catalog.+) 4; + +select 3 operator(+) 4; + +select 1 operator(a.&&) 2; + +-- unary +select operator(pg_catalog.-) 4; +select operator(-) 4; + +select operator(a.b.-) 4; + diff --git a/crates/squawk_parser/test_data/ok/security_label.sql b/crates/squawk_parser/test_data/ok/security_label.sql new file mode 100644 index 00000000..77723775 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/security_label.sql @@ -0,0 +1,116 @@ +-- table +SECURITY LABEL FOR selinux ON TABLE mytable IS 'system_u:object_r:sepgsql_table_t:s0'; + +SECURITY LABEL FOR selinux ON TABLE mytable IS NULL; + +-- column +security label on column foo.bar is null; + +-- on_aggregate_star +security label on aggregate foo.bar(*) is ''; + +-- on_aggregate_args +security label on aggregate foo.bar( + in foo integer, + bar integer, + text +) is ''; + +-- on_aggregate_args_with_order_by +security label on aggregate foo.bar( + integer, + text, + numeric + order by + in a timestamp, + b numeric, + text +) is ''; + +security label on aggregate foo.bar( + order by + in a timestamp, + b numeric, + text +) is ''; + +-- database +security label on database foo is null; + +-- domain +security label on domain bar.foo is null; + +security label on domain foo is null; + +-- event_trigger +security label on event trigger foo is null; + +-- foreign_table +security label on foreign table bar is null; + +-- function +security label on function foo.bar.buzz is null; + +security label on function foo () is null; + +security label on function foo ( + in a text, + out b numeric, + bigint +) is null; + +-- large_object +security label on large object 1234 is null; + +-- materialized_view +security label on materialized view foo.bar is null; + +-- language +security label on procedural language bar is null; + +security label on language bar is null; + +-- procedure +security label on procedure foo.bar is null; + +security label on procedure foo.bar() is null; + +security label on procedure bar( + in foo text, + numeric +) is null; + +-- publication +security label on publication bar is null; + +-- role +security label on role bar is null; + +-- routine +security label on routine foo.bar is null; + +security label on routine foo.bar() is null; + +security label on routine foo.bar( + in foo text, + numeric +) is null; + +-- schema +security label on schema bar is null; + +-- sequence +security label on sequence foo.bar is null; + +-- subscription +security label on subscription bar is null; + +-- tablespace +security label on tablespace bar is null; + +-- type_ +security label on type foo.bar is null; + +-- view +security label on view foo.bar is null; + diff --git a/crates/squawk_parser/test_data/ok/select.sql b/crates/squawk_parser/test_data/ok/select.sql new file mode 100644 index 00000000..185bd980 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select.sql @@ -0,0 +1,497 @@ +-- parens_and_unions +(select 1); + +((select 2)); + +select (((select 1)) + 3); + +SELECT NULL UNION SELECT NULL UNION SELECT 1; + +(SELECT NULL UNION SELECT NULL) UNION SELECT 1; + +-- alias_clause +-- simple +select * from (select 1, 2, 3) as t(a, b, c); +-- from alias +select foo from bar as t; + +-- non-ident column and table names +select * from (select 1, 2, 3) as target(target, function); +-- from column aliases +select col1 from bar as t(col1, col2); + +-- w/o as +select * from (select 1, 2, 3) target(target, function); +-- from alias shorthand +select t.* from bar t; + +-- date_funcs +-- current_date +select current_date; + +-- current_time +select current_time; +select current_time(10); + +-- current_timestamp +select current_timestamp; +select current_timestamp(5); + +-- localtime +select localtime; +select localtime(5); + +-- localtimestamp +select localtimestamp; +select localtimestamp(5); + +-- array_select +-- array with subquery +select array(select oid from pg_proc where proname like 'bytea%'); + +-- positional_param +select $1; + +select * from t where c = $1; + +-- any_and_all +-- all +select * from t where c = all(c); + +-- any +select * from t where c = any(c); + +select * from t where c = any(array['a', 'b', 'c']); + +select 1 = any(select 1); + +select 1 = any(with t as (select 1) select * from t); + +select 1 = any(values (1), (3)); + +-- some +select 1 > some(select 1); + +-- all +select 1 = all(select 1); + +-- all with array +select * from t +where not (tag = all(array['a', 'b', 'c'])); + +-- some, an alias for any +select * from t where c = some(c); + +-- any_values +select a = any(values (1, 2), (b, 3), (c, d)); + +-- field_exprs +select mytable.mycolumn; +select $1.somecolumn; +select (rowfunction(a,b)).col3; + +select (compositecol).somefield; +select (mytable.compositecol).somefield; + +select (compositecol).*; + +-- case_expr +-- simple +select case when $1 then 1 when $2 then 2 end from t; + +-- generic conditional case +select a, + case when a = 1 then 'one' + when a = 2 then 'two' + else 'other' + end +from test; + +-- ommitted else +select a, + case when a = 1 then 'one' + when a = 2 then 'two' + end +from test; + +-- switch style case +select a, + case a when 1 then 'one' + when 2 then 'two' + else 'other' + end +from test; + +-- col_labels +select foo as bar from t; + +select foo bar from t; + +select foo bar, b, x y from t; + +-- select +-- ident +select foo; + +-- all +select all; + +-- multi columns +select 1, 2; + +-- select_with_quoted_ident +select t."b.c" from t; + +-- select_with_from_clause +-- from tablename +select foo from bar; + +-- from only +select a from only t; + +-- from field expr +select a from foo.bar; + +-- from with everything +select * from t * as r(a, b, c) tablesample sample_method (10, 23, 50) repeatable (42); + +-- from select stmt +select * from (select 1); +select * from lateral (select 1) as t(a, b, c); + +-- function call complex +select a, b from foo(bar, buzz) with ordinality as t(a, b); +select a, b from foo(bar, buzz) with ordinality t(a, b); + +-- function with alias +select * from foo(bar, buzz) as t; +select * from foo(bar, buzz) t; +select * from foo(bar, buzz) as t(a, b); +select * from foo(bar, buzz) t(a, b); + +-- function with column def +select * from json_to_record('{"a": 1, "b": "c"}') t(a int, b text); +select * from f() as t(a int, b text); +select * from f() as (a int, b text); + +-- function with collate +select * from f() as (a int, b text collate foo.bar.buzz); +select * from f() as (a int, b text collate "bar"); + +-- multiple tables +select * from a, b; +select * from bar x, buzz y; +select * from foo as f, boo as b; + +-- from_item + +-- table_name from_item +select * from only t as z(a, b, c); +select * from t * as z(a, b, c); +select * from t z(a, b, c); +select * from t z; +select * from foo.t z; +select * from t; + +-- with_query_name +select * from t; +select * from t as b(x, y, z); +select * from t as b; +select * from t b; + +-- lateral select +select * from lateral (select 1) as t(a, b, c); +select * from (select 1) as t(a, b, c); +select * from (select 1) t; +select * from (select 1); + +-- lateral function_name + +select * from lateral f(); +select * from f() t; +select * from f() with ordinality as t(a, b, c); +select * from f() as t(a, b, c); +select * from f() t(a, b, c); +select * from lateral f(a, b); +select * from f() as t(a int, b text); +select * from f() t(a int, b text); + + +-- lateral rows from( +select * from lateral rows from(f(a, b)) as (x int, y text, z int8); +select * from rows from(f(a, b)); +select * from rows from(f()); +select * from rows from(f()) with ordinality; +select * from rows from(f()) with ordinality as t; +select * from rows from(f()) as t(a, b, c); +select * from rows from(f()) t(a, b, c); + +-- select_with_where_clause +-- simple +select 1 where 1; + +-- select_with_limit_clause +-- simple +select 1 limit 1; + +-- select_with_orderby_clause +-- simple +select 1 order by 1; + + +-- nulls +select 1 order by 1 nulls first; +select 1 order by 1 nulls last; + + +select 1 order by 1 using > nulls last; + +-- select_window_clause +-- simple +select 1 window w as (); + +-- with window def order by +select 1 window w as (order by 1); + +-- with window def frame_start, frame_end +select 1 window w as (range 1 preceding); +select 1 window w as (rows 1 preceding); +select 1 window w as (groups 1 preceding); + +-- with window def frame_exclusion +select 1 window w as (rows 1 preceding exclude current row); +select 1 window w as (rows 1 preceding exclude group); +select 1 window w as (rows 1 preceding exclude ties); +select 1 window w as (rows 1 preceding exclude no others); + + +-- select_having_clause +-- simple +select 1 having true; + + +-- select_with_group_by_clause +-- parens +select 1 group by (); + +-- simple expr +select 1 group by 1; + +-- multi expr +select 1, 2 group by 1, 2; + +-- all +select 1 group by all 1; + +-- distinct +select 1 group by distinct 1; + +-- rollup +select 1 group by rollup (1, 2); + +-- rollup multi +select 1 group by rollup (1, 2), rollup (3); + +-- cube +select 1 group by distinct cube (1, 2, 3); + +-- grouping sets +select 1 group by grouping sets ( + (1, 2, 3), + (1, 2), + (1), + () +); + +-- select_with_offset_clause +-- simple +select 1 offset 1; + +-- rows +select 1 offset 1 row; +select 1 offset 1 rows; + + +-- select_with_fetch_clause +-- first +select 1 fetch first 3 rows only; + +-- next +select 1 order by 1 fetch next 1 row with ties; + +-- simple_expr +-- simple nested select +select (select 1) + (select 2); + +select -(select 1); + +-- select_with_locking_clause +-- nowait +select 1 for share of a, b, c; + +-- multiple clauses +select 1 for update nowait for update skip locked; + +-- select from +select * from t where x not in (1, 2, 3); + +-- composite_types +select row('fuzzy dice', 42, 1.99); +select ('fuzzy dice', 42, 1.99); + +-- join +-- simple join +select * from t join t2 as tb on tb.id = t.id; + +-- left +select * from t left join t2 using (id); +select * from t left join t2 using (id, foo); + +-- right +select * from t right join t2 using (id); + +-- full +select * from t full join t2 using (id); + +-- multi conditions +select * from t join t2 on t2.team_id = t.team_id and t2.id = t.org_id; + +-- using w/ join alias +SELECT * from t join t2 using (id) as foo; + +-- cross join +SELECT c.color_name, s.size_name FROM colors c CROSS JOIN sizes s; + +-- inner join on true +select f.fruit_name, c.color_name from fruits f inner join colors c on (true); + +-- multiple join clauses +select 1 from t +left join u using (id) +left join k using (event); + +-- natural +SELECT * FROM employees NATURAL JOIN departments; + +-- pg docs + +-- using +SELECT f.title, f.did, d.name, f.date_prod, f.kind + FROM distributors d JOIN films f USING (did); + +select * from t join t2 using (a_id); + +-- lateral +SELECT m.name AS mname, pname +FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true; + +-- table +-- simple +table t; + +-- only +table only t; + +-- star +table t *; + +-- nested +select (table t); + +-- union +-- simple +select 1 union select 2; + +-- all +select 1 union all select 2; + +-- distinct +select 1 union distinct select 2; + +-- multi +select 1 union select 2 union select 3; + + +-- intersect +-- simple +select 1 intersect select 2; + +-- all +select 1 intersect all select 2; + +-- distinct +select 1 intersect distinct select 2; + + +-- except +-- simple +select 1 except select 2; + +-- all +select 1 except all select 2; + +-- distinct +select 1 except distinct select 2; + +-- ident_edge_cases +-- select keywords +select 1 as select; +select 1 as from; +select 1 as where; + +select 1 all; + +-- column labels that are also operators +select 1 is; + +select 1 and; + +select 1 or; + +select 1 collate; + +select foo.bar null; +select foo.bar default; + +select default; +select c default; +select null; +select c null; + +-- select_special_funcs +-- collation +select collation for ( b + c ); + +-- current_role +select current_role; + +-- current_user +select current_user; + +-- session_user +select session_user; + +-- system_user +select system_user; + +-- user +select user; + +-- current_catalog +select current_catalog; + +-- current_schema +select current_schema; + +-- order_by_with_custom_op +select * from t order by a using >>>; + +-- order_by_regression +SELECT sensor_id, DATE_TRUNC('day', ts) AS day, MAX(value) AS max_value, MIN(value) AS min_value +FROM sensors_uncompressed +WHERE ts >= DATE '2023-12-21' AND ts < DATE '2023-12-22' +GROUP BY sensor_id, DATE_TRUNC('day', ts) +ORDER BY sensor_id, day; + +-- select_from_user_table +select * from user; diff --git a/crates/squawk_parser/test_data/ok/select_casts.sql b/crates/squawk_parser/test_data/ok/select_casts.sql new file mode 100644 index 00000000..da273c94 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_casts.sql @@ -0,0 +1,211 @@ +-- type_casts +select numeric '1234'; +select '1234'::numeric; +select cast('1234' as numeric); +select int8('1234'); + +select 44::bit(3); +select cast(-44 as bit(12)); +select '1110'::bit(4)::integer; + +select '{1,2,3}'::int[]; +select foo::int; +select foo::numeric[]; + +select '{}' :: int[] :: int8[] :: numeric[1]; + +select '{}'::int[]::int8[]::numeric[1]; + +-- based on postgres' gram.y + +-- Bit +select '1001'::bit varying; + +select '1001'::bit varying(4); + +-- Character + +select 'abc'::character; +select 'abc'::character varying; + +select 'abc'::char; +select 'abc'::char varying; + +select 'abc'::varchar; + +select 'abc'::national character; +select 'abc'::national character varying; + +select 'abc'::national char; +select 'abc'::national char varying; + +select 'abc'::nchar; +select 'abc'::nchar varying; +select 'abc'::nchar varying[]; + +-- ConstDatetime + +select '2024-01-01 12:34:56.123456'::timestamp(2); +select '2024-01-01 12:34:56.123456'::timestamp(2) with time zone; +select '2024-01-01 12:34:56.123456'::timestamp(2) without time zone; + +select '2024-01-01 12:34:56.123456'::timestamp; +select '2024-01-01 12:34:56.123456'::timestamp with time zone; +select '2024-01-01 12:34:56.123456'::timestamp without time zone; + +select '2024-01-01 12:34:56.123456'::time(2); +select '2024-01-01 12:34:56.123456'::time(2) with time zone; +select '2024-01-01 12:34:56.123456'::time(2) without time zone; + +select '2024-01-01 12:34:56.123456'::time; +select '2024-01-01 12:34:56.123456'::time with time zone; +select '2024-01-01 12:34:56.123456'::time without time zone; + +-- timestamp with time zone cast +select timestamp with time zone '2005-04-02 12:00:00-07'; + +-- cast w/ at time zone operator +select timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'america/denver'; + +-- timestamp cast w/ at time zone operator +select timestamp '2001-02-16 20:38:40' at time zone 'america/denver'; + +-- multiple at time zone +select timestamp '2001-02-16 20:38:40' at time zone 'asia/tokyo' at time zone 'america/chicago'; + +-- cast and at local +select time with time zone '20:38:40-05' at local; + +select c at local; +select timestamp with time zone '2001-02-16 20:38:40-05' at local; + +-- ConstInterval + +select '10 days'::interval; + +select '10 days'::interval year; + +select '10 days'::interval month; + +select '10 days'::interval day; + +select '10 days'::interval hour; + +select '10 days'::interval minute; + +select '10 days'::interval second; +select '10 days'::interval second(100); + +select '10 days'::interval year to month; + +select '10 days'::interval day to hour; + +select '10 days'::interval day to minute; + +select '10 days'::interval day to second; +select '10 days'::interval day to second(10); + +select '10 days'::interval hour to minute; + +select '10 days'::interval hour to second; +select '10 days'::interval hour to second(10); + +select '10 days'::interval minute to second; +select '10 days'::interval minute to second(10); + +select '10 days'::interval(10); + +-- JsonType +select '{}'::json; + +-- jsonb type cast +select '"foo"'::jsonb @> '"foo"'::jsonb; + +-- GenericType +select ''::foo.bar; + +select ''::foo.bar(buzz, bizz); + +select 'abc'::varchar; +select 'abc'::varchar(5); +select ''::varchar(255)[]; +select ''::varchar[5]; + +select ''::t(255)[]; +select ''::foo.buzz(5); +select ''::bar.foo.buzz[5]; +select ''::bar.foo.buzz(255)[]; + +-- Numeric +select ''::int; +select ''::integer; +select ''::smallint; +select ''::bigint; +select ''::float; +select ''::float(1); +select ''::double precision; +select ''::decimal; +select ''::decimal(1, 2, 3); +select ''::dec; +select ''::dec(1, 2, 3); +select ''::numeric; +select ''::numeric(1, 2); +select ''::boolean; +select ''::numeric(10,2)[10]; + + +-- interval_cast_trailing +select interval '1' year; +select interval '1' month; +select interval '1' day; +select interval '1' hour; +select interval '1' minute; +select interval '1' second; +select interval '1' year to month; +select interval '1' day to hour; +select interval '1' day to minute; +select interval '1' day to second; +select interval '1' day to second(10); +select interval '1' hour to minute; +select interval '1' hour to second; +select interval '1' hour to second(10); +select interval '1' minute to second; +select interval '1' minute to second(10); + +-- pgdoc_char +select ''::char(1) collate "C"; + +SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2); + +select cast(x as b) collate "C" > b; + +-- cast_array +select cast('{1}' as integer ARRAY[4]); + +select cast('{1}' as int8 ARRAY); + +select cast('{1}' as int[4]); + +select cast('{1}' as integer[3][3]); + +select '{1}'::integer[1][2][3][][][1000]; + +select array[]::integer[]; + +-- casts +select 44::bit(10); -- 0000101100 +select 44::bit(3); -- 100 +select cast(-44 as bit(12)); -- 111111010100 +select '1110'::bit(4)::integer; -- 14 + +select '1'::pg_catalog.int8; +select '{1}'::pg_catalog.int8[]; + + +-- cast +select cast(a as foo.bar); + +-- treat +select treat(a as foo.b); +select treat('1231' as numeric); + diff --git a/crates/squawk_parser/test_data/ok/select_cte.sql b/crates/squawk_parser/test_data/ok/select_cte.sql new file mode 100644 index 00000000..5cf01a6f --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_cte.sql @@ -0,0 +1,119 @@ +-- with_merge +with t as ( + merge into t + using u on true + when matched then + do nothing +) +select * from t; + +-- with_values +with t as ( + values (1) +) +select * from t; + +-- with +-- simple +with t as ( + select 1 +) +select * from t; + +-- column names +with t(a, b) as ( + select 1, 2 +) +select * from t; + +-- materialized +with t as materialized ( + select 1 +) +select * from t; + +-- not materialized +with t as not materialized ( + select 1 +) +select * from t; + +-- nested +select 1, ( + with t as ( + select 1, 2, 3 + ) + select count(*) + from t +); + +-- search depth first (from pg docs) +WITH RECURSIVE search_tree(id, link, data) AS ( + SELECT t.id, t.link, t.data + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data + FROM tree t, search_tree st + WHERE t.id = st.link +) SEARCH DEPTH FIRST BY id SET ordercol +SELECT * FROM search_tree ORDER BY ordercol; + +-- search breadth first (from pg docs) +WITH RECURSIVE search_tree(id, link, data) AS ( + SELECT t.id, t.link, t.data + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data + FROM tree t, search_tree st + WHERE t.id = st.link +) SEARCH BREADTH FIRST BY id SET ordercol +SELECT * FROM search_tree ORDER BY ordercol; + + +-- search cycle (from pg docs) +WITH RECURSIVE search_graph(id, link, data, depth) AS ( + SELECT g.id, g.link, g.data, 1 + FROM graph g + UNION ALL + SELECT g.id, g.link, g.data, sg.depth + 1 + FROM graph g, search_graph sg + WHERE g.id = sg.link +) CYCLE id SET is_cycle USING path +SELECT * FROM search_graph; + +-- search cycle with to and default values +WITH RECURSIVE search_graph(id, link, data, depth, path) AS ( + select 1 +) CYCLE id SET is_cycle TO true DEFAULT false USING path +SELECT * FROM search_graph; + +-- multi +with t as ( + select 1 +), +b as ( + select 2 +) +select * from t, b; + +-- recursive +with recursive t as ( + select 1 +) +select * from t; + +with t2 as ( + with t as ( + select 1 + ) + select * from t +) +select * from t2; + +-- timestamp_edge_cases +with t(timestamp) as (select 1) +select timestamp from t; + +with t(time) as (select 1) +select time from t; + diff --git a/crates/squawk_parser/test_data/ok/select_funcs.sql b/crates/squawk_parser/test_data/ok/select_funcs.sql new file mode 100644 index 00000000..b24fc738 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_funcs.sql @@ -0,0 +1,248 @@ +-- normalize +select normalize('a' + 'b'); +select normalize('a' || 'b', nfc); +select normalize('c', nfd); +select normalize('d', nfkc); +select normalize('e', nfkd); + +-- nullif +select nullif(a, b); + +-- coalesce +select coalesce(a, 1); +select coalesce(a, b, c, d, 'foo'); + +-- greater +select greater(a, 1); +select greater(a, b, c, d, 0); + +-- least +select least(a, 1); +select least(a, b, c, d, 0); + +-- merge_action +select merge_action(); + + + +-- overlay +select overlay(a placing b from c for d); +select overlay(a placing b from c); +select overlay(); +select overlay(1, 2, 3, a => 4); + +-- position +select position('foo' in 'bar'); +select position('f' || 'b' in 'fb' || ' '); +select position('c' in a); + +-- trim +select trim(both a from a); +select trim(both from a); +select trim(both a); +select trim(leading a); +select trim(trailing a); +select trim(a); + +-- substring_fn +select substring(a from b for c); +select substring(a for b from c); +select substring(a from b); +select substring(a for b); +select substring(a similar b escape c); + +select substring(a || '', b * 2, c - 1); +select substring('hello world', 1, 5); + +-- xmlconcat +select xmlconcat(a, b); + +-- xmlelement +select xmlelement(name b); +select xmlelement(name c, xmlattributes(foo, bar as b)); +select xmlelement(name d, e, f, g); +select xmlelement(name d, xmlattributes(buzz, foo as c), f, g); + +-- xmlexists +select xmlexists('foo' passing 'bar'); +select xmlexists('foo' passing bar by ref); +select xmlexists('foo' passing by ref bar); +select xmlexists('foo' passing by ref foo by value); + +-- xmlforest +select xmlforest(foo, bar, buzz); + +-- xmlparse +select xmlparse(document x preserve whitespace); +select xmlparse(content x strip whitespace); + +-- xmlpi +select xmlpi(name foo); +select xmlpi(name foo, bar); + +-- xml_root +select xmlroot(a, version foo); +select xmlroot(a, version no value); +select xmlroot(a, version foo, standalone yes); +select xmlroot(a, version foo, standalone no); +select xmlroot(a, version foo, standalone no value); + +-- xml_serialize +select xmlserialize(document x as foo indent); +select xmlserialize(document x as foo no indent); + +-- json_object +select json_object(); +select json_object('{a, 1, b, "def", c, 3.5}'); +select json_object('{foo}', '{bar}'); +select json_object(array['a', 'b'], array['foo', 'bar']); +select json_object('foo' value 'bar', 'a' value 'b'); +select json_object('foo': 'bar', 'a': 'b'); + +select json_object('foo': 'bar' format json encoding utf8); +select json_object('foo': 'bar' format json); + +select json_object('foo': 'bar' null on null); +select json_object('foo': 'bar' absent on null); +select json_object('a': 1, 'b': '1' format json, 'c' value 'c'); + +select json_object('foo': 'bar' null on null with unique keys); +select json_object('foo': 'bar' null on null with unique); +select json_object('foo': 'bar' null on null without unique keys); +select json_object('foo': 'bar' null on null without unique); + +select json_object('foo': 'bar' returning foo); +select json_object('foo': 'bar' returning foo format json); + +-- json_array +-- value_expression +select json_array(a); +select json_array(1, 2, 3, 4); +select json_array(((1))); +select json_array(a format json encoding utf8); +select json_array(a format json); +select json_array(a format json null on null); +select json_array(1 returning text format json); +select json_array(a absent on null); +select json_array(a absent on null returning foo format json); +select json_array(1, true, json '{"a":null}'); +select json_array(1, b, '3' format json, 4); + +-- query_expression +select json_array(select 1); +select json_array(select 1 format json); +select json_array(select 'true' format json returning text format json); +select json_array(select 'true' returning text format json); +select json_array(((select 1))); +select json_array(returning text); +select json_array(returning text format json); + +-- json_scalar +select json_scalar(1); + +-- exists +select exists(select 1 from t where a = b); + +select exists(with t as (select 1) select * from t); + +-- exists_values +select exists(values (1)); + +-- exists_where +select * from t where exists(select null); + +-- not_exists +select not exists(select 1); + +-- function_call +-- position notation +select buzz('x', 'y'); + +-- named notation +select f(a => 'foo', b => 'bar'); + +-- mixed notation +select foo('bar', 'buzz', boo => true); + +-- colon equals +select f('b', a := true); + +-- extract +select extract(foo from bar || 'buzz'); +select extract(year from a); +select extract(month from a); +select extract(day from a); +select extract(hour from a); +select extract(minute from a); +select extract(second from a); +select extract('minute' from a); +select extract(epoch from timestamptz '2013-07-01 12:00:00'); +select extract(century from timestamp '2000-12-16 12:21:13'); +select extract(isodow from timestamp '2001-02-18 20:38:40'); +select extract(isoyear from date '2006-01-01'); +select extract(julian from date '2006-01-01'); +select extract(microseconds from time '17:12:28.5'); +select extract(millennium from timestamp '2001-02-16 20:38:40'); +select extract(quarter from timestamp '2001-02-16 20:38:40'); + +select transaction_timestamp(); +select statement_timestamp(); +select clock_timestamp(); +select timeofday(); +select now(); + +select pg_sleep(1.5); +select pg_sleep_for('5 minutes'); +select pg_sleep_until('tomorrow 03:00'); + +-- aggs +-- order by one param +select array_agg(v order by v desc) from vals; + +-- order by param 2 +select jsonb_object_agg(k, v order by v) from vals; + +-- order by param 2 const +select string_agg(a, ',' order by a) from t; + +-- order by param 1 +select string_agg(a order by a, ',') from "table"; + +-- within group +select foo(0.5) within group (order by c) from t; + +-- filter expr simple +select count(*) filter (where i < 5) from t; + +-- filter expr +select + count(*) as unfiltered, + count(*) filter (where i < 5) as filtered +from generate_series(1, 10) as s(i); + +select f(all c); + +select f(distinct b); + +-- variadic_func_calls +-- simple +select f(variadic foo); + +select f(variadic array[1, 2, 3]); + +-- array +select b(variadic array[]::numeric[]); + +-- named +select c(variadic arr => array[1, 2, 3]); + +-- last param +select f(a, b, c, variadic array[1, 2, 3]); + + +-- window_func_calls +-- over partition +select max(a) over (partition by b) as c from t; + +-- window name +select max(a) over w_name from t; diff --git a/crates/squawk_parser/test_data/ok/select_funcs_pg17.sql b/crates/squawk_parser/test_data/ok/select_funcs_pg17.sql new file mode 100644 index 00000000..d5b63315 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_funcs_pg17.sql @@ -0,0 +1,110 @@ + +-- json_table +SELECT jt.* FROM + my_films, + JSON_TABLE (js, '$.favorites[*]' COLUMNS ( + id FOR ORDINALITY, + kind text PATH '$.kind', + title text PATH '$.films[*].title' WITH WRAPPER, + director text PATH '$.films[*].director' WITH WRAPPER)) AS jt; + +-- json_table_nested_path +SELECT jt.* FROM + my_films, + JSON_TABLE ( js, '$.favorites[*] ? (@.films[*].director == $filter)' + PASSING 'Alfred Hitchcock' AS filter + COLUMNS ( + id FOR ORDINALITY, + kind text PATH '$.kind', + NESTED PATH '$.films[*]' COLUMNS ( + title text FORMAT JSON PATH '$.title' OMIT QUOTES, + director text PATH '$.director' KEEP QUOTES))) AS jt; + +-- json_table_without_filter +SELECT jt.* FROM + my_films, + JSON_TABLE ( js, '$.favorites[*]' + COLUMNS ( + id FOR ORDINALITY, + kind text PATH '$.kind', + NESTED PATH '$.films[*]' COLUMNS ( + title text FORMAT JSON PATH '$.title' OMIT QUOTES, + director text PATH '$.director' KEEP QUOTES))) AS jt; + +-- json_table_union +SELECT * FROM JSON_TABLE ( +'{"favorites": + {"movies": + [{"name": "One", "director": "John Doe"}, + {"name": "Two", "director": "Don Joe"}], + "books": + [{"name": "Mystery", "authors": [{"name": "Brown Dan"}]}, + {"name": "Wonder", "authors": [{"name": "Jun Murakami"}, {"name":"Craig Doe"}]}] +}}'::json, '$.favorites[*]' +COLUMNS ( + user_id FOR ORDINALITY, + NESTED '$.movies[*]' + COLUMNS ( + movie_id FOR ORDINALITY, + mname text PATH '$.name', + director text), + NESTED '$.books[*]' + COLUMNS ( + book_id FOR ORDINALITY, + bname text PATH '$.name', + NESTED '$.authors[*]' + COLUMNS ( + author_id FOR ORDINALITY, + author_name text PATH '$.name')))); + +-- json +select json(a format json); +select json(a format json with unique keys); +select json(a format json with unique); +select json(a format json without unique keys); +select json(a format json without unique); + +-- json_serialize +select json_serialize(a); +select json_serialize(a format json); +select json_serialize(a returning foo); +select json_serialize(a format json returning foo format json); + +-- json_query +select json_query(a, b with wrapper); +select json_query( + a format json, + b passing c as foo, + d as bar + returning text + format json + with unconditional array wrapper + keep quotes on scalar string + unknown on empty + empty array on error +); + + +-- json_exists +select json_exists(a, b); +select json_exists( + a format json, + b passing c as d + default z on error +); + +-- doc examples +select JSON_EXISTS(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > $x)' PASSING 2 AS x); +select JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR); +select JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR); + +-- json_value +select json_value(a, b); +select json_value( + a format json, + b passing c as d + returning foo format json + unknown on empty + default z on error +); + diff --git a/crates/squawk_parser/test_data/ok/select_into.sql b/crates/squawk_parser/test_data/ok/select_into.sql new file mode 100644 index 00000000..127febfc --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_into.sql @@ -0,0 +1,6 @@ +-- docs +SELECT * INTO films_recent FROM films WHERE date_prod >= '2002-01-01'; + +-- more_schema +select a, b, c into t from t2; + diff --git a/crates/squawk_parser/test_data/ok/select_operators.sql b/crates/squawk_parser/test_data/ok/select_operators.sql new file mode 100644 index 00000000..57e42c7e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/select_operators.sql @@ -0,0 +1,537 @@ +-- logical_operators +-- and +select true and false; + +-- or +select true or false; + +-- not +select not true; + +-- not is null +select not x is null; +select not x isnull; + +-- geo_operators + +-- add +select box '(1,1),(0,0)' + point '(2,0)'; + +-- concat +select path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'; + +-- subtract +select box '(1,1),(0,0)' - point '(2,0)'; + +-- multiply +select path '((0,0),(1,0),(1,1))' * point '(3.0,0)'; +select path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45)); + +-- divide +select path '((0,0),(1,0),(1,1))' / point '(2.0,0)'; +select path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45)); + +-- length +select @-@ path '[(0,0),(1,0),(1,1)]'; + +-- center point +select @@ box '(2,2),(0,0)'; + +-- number of points +select # path '((1,0),(0,1),(-1,0))'; + +-- point intersection +select lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'; + +-- box intersection +select box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'; + +-- closest point +select point '(0,0)' ## lseg '[(2,0),(0,2)]'; + +-- distance between +select circle '<(0,0),1>' <-> circle '<(5,0),1>'; + +-- first contains +select circle '<(0,0),2>' @> point '(1,1)'; + +-- first contained in second +select point '(1,1)' <@ circle '<(0,0),2>'; + +-- objects overlap +select box '(1,1),(0,0)' && box '(2,2),(0,0)'; + +-- object strictly left +select circle '<(0,0),1>' << circle '<(5,0),1>'; + +-- object strictly right +select circle '<(5,0),1>' >> circle '<(0,0),1>'; + +-- first extended to right of second +select box '(1,1),(0,0)' &< box '(2,2),(0,0)'; + +-- first extends to left of second +select box '(3,3),(0,0)' &> box '(2,2),(0,0)'; + +-- first strictly below second +select box '(3,3),(0,0)' <<| box '(5,5),(3,4)'; + +-- first strictly above second +select box '(3,3),(0,0)' |>> box '(5,5),(3,4)'; + +-- first doesn't extend above second +select box '(1,1),(0,0)' &<| box '(2,2),(0,0)'; + +-- first doesn't extend below second +select box '(3,3),(0,0)' |&> box '(2,2),(0,0)'; + +-- first below second +select box '((1,1),(0,0))' <^ box '((2,2),(1,1))'; + +-- first above second +select box '((2,2),(1,1))' >^ box '((1,1),(0,0))'; + +-- objects intersect +select lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)'; + +-- line horizontal +select ?- lseg '[(-1,0),(1,0)]'; + +-- points horizontally aligned +select point '(1,0)' ?- point '(0,0)'; + +-- line vertical +select ?| lseg '[(-1,0),(1,0)]'; + +-- points vertically aligned +select point '(0,1)' ?| point '(0,0)'; + +-- lines perpendicular +select lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'; + +-- lines parallel +select lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'; + +-- objects the same +select polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'; + + +-- network_operators + +-- subnet contained by or equal +select inet '192.168.1/24' <<= inet '192.168.1/24'; + +-- subnet contain or equal subnet +select inet '192.168.1/24' >>= inet '192.168.1/24'; + + +-- fts_operators + +-- negative tsquery +select !! 'cat'::tsquery; + +-- subnet contain or equal subnet +select inet '192.168.1/24' >>= inet '192.168.1/24'; + + +-- array_operators +-- first array (as a set) contain the second (as a set)? +select array[1,4,3] @> array[3,1,3]; + +-- first array (as a set) contained by the second (as a set)? +select array[2,2,7] <@ array[1,7,4,2,6]; + +-- is there any overlap +select array[1,4,3] && array[2,1]; + +-- concat +select ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]; + +-- starts with +select 'alphabet' ^@ 'alph'; + +-- array_access +-- first index +select a[0]; + +-- slicing +select b[1:2][1:1]; + +-- omitted bounds +select c[:2][2:]; + +-- omitted part 2 +select schedule[:][1:1]; + + +-- string_operators +-- concatenate +select 'Post' || 'greSQL'; +select 'Value: ' || 42; + +-- normalization check +select U&'\0061\0308bc' is normalized; +select U&'\0061\0308bc' is nfc normalized; +select U&'\0061\0308bc' is nfd normalized; +select U&'\0061\0308bc' is nfkc normalized; +select U&'\0061\0308bc' is nfkd normalized; +select U&'\0061\0308bc' is not nfd normalized; + +-- pattern_matching +-- like +select 'foo' like 'bar'; + +-- not like +select 'foo' not like 'bar'; + +-- ~~ +select 'a' ~~ 'b'; + +-- !~~ +select 'a' !~~ 'b'; + +-- similar to +select 'abc' similar to 'abc'; + +-- posix regex +-- string matches regex case sensitive +select 'foo' ~ 'f.*'; + +-- string matches regex case insensitive +select 'a' ~* 'b'; + +-- string does not match regex case sensitive +select 'a' !~ 'b'; + +-- string does not match regex case insensitive +select 'a' !~* 'b'; + + +-- compare_operators +-- less than +select 1 < 2; + +-- greater than +select 5 > 3; + +-- less than or equal to +select 8 <= 4; + +-- greater than or equal to +select 9 >= 7; + +-- equal +select 5 = 0; + +-- not equal +select 1 <> 3; +select 1 != 3; + +-- between (inclusive of the range endpoints) +select 2 between 1 and 3; +select 2 between foo() and bar(); + +-- not between (the negation of between) +select 2 not between 1 and 3; +select 2 not between foo() and bar(); + +-- between symmetric (between, after sorting the two endpoint values) +select 2 between symmetric 3 and 1; + +-- not between symmetric (not between, after sorting the two endpoint values) +select 2 not between symmetric 3 and 1; + +-- is distinct from (not equal, treating null as a comparable value) +select 1 is distinct from null; + +-- is not distinct from (equal, treating null as a comparable value) +select 1 is not distinct from null; + +-- at time zone +select '2024-01-01 12:00:00' at time zone 'UTC'; + +-- is null +select 1.5 is null; + +-- is not null +select 'null' is not null; + +-- isnull (non-standard syntax) +select 1 isnull; + +-- notnull (non-standard syntax) +select 'foo' isnull; + +-- is true +select true is true; + +-- is not true +select true is not true; + +-- is false +select true is false; + +-- is not false +select true is not false; + +-- is unknown +select true is unknown; + +-- is not unknown +select true is not unknown; + +-- math_operators +-- addition +select 2 + 3; + +-- unary plus +select + 3.5; + +-- subtraction +select 2 - 3; + +-- negation +select - (-4); + +-- multiplication +select 2 * 3; + +-- division +select 5.0 / 2; +select 5 / 2; +select (-5) / 2; + +-- modulo +select 5 % 4; + +-- exponentiation +select 2 ^ 3; +select 2 ^ (3 ^ 3); + +-- square root +select |/ 25.0; + +-- cube root +select ||/ 64.0; + +-- absolute value +select @ -5.0; + +-- bitwise and +select 91 & 15; + +-- bitwise or +select 32 | 3; + +-- bitwise exclusive OR +select 17 # 5; + +-- bitwise NOT +select ~1; + +-- bitwise shift left +select 1 << 4; + +-- bitwise shift right +select 8 >> 2; + +-- bitstring_operators +-- bitwise and +select B'10001' & B'01101'; + +-- bitwise or +select B'10001' | B'01101'; + +-- bitwise xor +select B'10001' # B'01101'; + +-- bitwise not +select ~ B'10001'; + +-- bitshift left +select B'10001' << 3; + +-- bitshift right +select B'10001' >> 2; + +-- range +select int4range(2, 4) <@ int4range(1, 7); + +-- json_ops +-- extract +select '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2; +select '{"a": {"b":"foo"}}'::json -> 'a'; + +-- extract as text +select '[1,2,3]'::json ->> 2; +select '{"a":1,"b":2}'::json ->> 'b'; + +-- extract path as json +select '{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'; + +-- extract path as text +select '{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'; + +-- contains +select '"foo"'::jsonb @> '"foo"'::jsonb; + +select '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb; + +-- existence +select '{"a":1, "b":2}'::jsonb ? 'b'; +select '["a", "b", "c"]'::jsonb ? 'b'; + +-- any keys exist +select '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd']; + +-- all keys exist +select '["a", "b", "c"]'::jsonb ?& array['a', 'b']; + +-- concat +select '["a", "b"]'::jsonb || '["a", "d"]'::jsonb; +select '{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb; +select '[1, 2]'::jsonb || '3'::jsonb; +select '{"a": "b"}'::jsonb || '42'::jsonb; +select '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb); + +-- delete +select '{"a": "b", "c": "d"}'::jsonb - 'a'; +select '["a", "b", "c", "b"]'::jsonb - 'b'; +select '{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]; +select '["a", "b"]'::jsonb - 1; + +-- delete at path +select '["a", {"b":1}]'::jsonb #- '{1,b}'; + +-- json path find +select '{"items": [1, 2, 3]}'::jsonb @? '$.items[*] ? (@ > 2)'; + +-- json path predicate check +select '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2'; + +-- subscripting +select foo[1]; +select bar['a']; +select ('[1, "2", null]'::jsonb)[1]; +select ('{"a": 1}'::jsonb)['a']; +select ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c']; + +select mytable.arraycolumn[4]; +select mytable.two_d_column[17][34]; +select $1[10:42]; +select (arrayfunction(a,b))[42]; + +-- select_with_collate +select a < ('foo' collate "fr_FR") from t; + +select a < b collate "de_DE" from t; + +select 'Å' = 'A' collate ignore_accent_case; + +select a collate "de_DE" < b from t; + +select a collate "C" < b collate "POSIX" from t; + +select * from t order by a || b collate "fr_FR"; + +select !!a collate "C"; + +select -a collate "C"; + +select +a collate "C"; + +select -t.a[0] collate "C"; +select -t.b::c collate "C"; + +-- cube_operators +select a && b; + +select a @> b; + +select a <@ b; + +select a -> b; + +select a ~> b; + +select a <-> b; + +select a <#> b; + +select a <=> b; + +-- more_ops +select a <+> b; + +-- prefix operators +select ** a; + +-- range_operators +-- contains +select int4range(2, 4) @> int4range(2, 3); + +-- contains element +select '[2011-01-01,2011-03-01)'::tsrange @> '2011-01-10'::timestamp; + +-- first contained by second +select int4range(2, 4) <@ int4range(1, 7); + +-- element contained in range +select 42 <@ int4range(1, 7); + +-- range overlap +select int8range(3, 7) && int8range(4, 12); + +-- first range strictly left +select int8range(1, 10) << int8range(100, 110); + +-- first range strictly right +select int8range(50, 60) >> int8range(20, 30); + +-- first range not extend right of second +select int8range(1, 20) &< int8range(18, 20); + +-- first range not extend left of second +select int8range(7, 20) &> int8range(5, 10); + +-- ranges adjacent +select numrange(1.1, 2.2) -|- numrange(2.2, 3.3); + +-- union +select numrange(5, 15) + numrange(10, 20); + +-- intersection +select int8range(5, 15) * int8range(10, 20); + +-- difference +select int8range(5, 15) - int8range(10, 20); + +-- OVERLAPS +select (date '2001-02-16', date '2001-12-21') overlaps (date '2001-10-30', date '2002-10-30'); + +-- postfix operators +select a is not null; + +select a is not unknown; + +-- single tuple +select 1 in (1); + +-- multi tuple +select 1 in (2, 3, 4); + +-- not_in +-- select +select 1 not in (1); + +-- single char operators that are okay in the prefix position +select +a; +select -b; +select ~h; +select !i; +select @j; +select #k; +select &n; +select |o; +select ?q; +select `p; diff --git a/crates/squawk_parser/test_data/ok/set_constraints.sql b/crates/squawk_parser/test_data/ok/set_constraints.sql new file mode 100644 index 00000000..1577c52f --- /dev/null +++ b/crates/squawk_parser/test_data/ok/set_constraints.sql @@ -0,0 +1,9 @@ +-- docs +set constraints all deferred; + +set constraints all immediate; + +set constraints foo, bar, a.b immediate; + +set constraints bar immediate; + diff --git a/crates/squawk_parser/test_data/ok/set_role.sql b/crates/squawk_parser/test_data/ok/set_role.sql new file mode 100644 index 00000000..8254898e --- /dev/null +++ b/crates/squawk_parser/test_data/ok/set_role.sql @@ -0,0 +1,11 @@ +-- docs +SET ROLE 'paul'; + +SET ROLE NONE; + +SET LOCAL ROLE NONE; + +SET SESSION ROLE foo; + +RESET ROLE; + diff --git a/crates/squawk_parser/test_data/ok/set_session_auth.sql b/crates/squawk_parser/test_data/ok/set_session_auth.sql new file mode 100644 index 00000000..48c1790c --- /dev/null +++ b/crates/squawk_parser/test_data/ok/set_session_auth.sql @@ -0,0 +1,6 @@ +-- docs +SET SESSION AUTHORIZATION decimal; +SET SESSION SESSION AUTHORIZATION 'foo'; +SET LOCAL SESSION AUTHORIZATION DEFAULT; +RESET SESSION AUTHORIZATION; + diff --git a/crates/squawk_parser/test_data/ok/set_transaction.sql b/crates/squawk_parser/test_data/ok/set_transaction.sql new file mode 100644 index 00000000..4c1b3bb0 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/set_transaction.sql @@ -0,0 +1,7 @@ +-- docs +SET TRANSACTION SNAPSHOT '00000003-0000001B-1'; + +SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED, read write; + +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE + diff --git a/crates/squawk_parser/test_data/ok/transaction.sql b/crates/squawk_parser/test_data/ok/transaction.sql new file mode 100644 index 00000000..4cfdb5fd --- /dev/null +++ b/crates/squawk_parser/test_data/ok/transaction.sql @@ -0,0 +1,80 @@ +-- begin_commit_abort_rollback +-- https://www.postgresql.org/docs/17/sql-commit.html +commit; +commit work; +commit transaction; +commit and chain; +commit and no chain; +commit prepared 'bar'; + +-- https://www.postgresql.org/docs/17/sql-begin.html +begin; +begin transaction; +begin work; +begin + isolation level read committed + read only + read write + deferrable + not deferrable; + +begin + isolation level read committed, + isolation level read uncommitted, + isolation level repeatable read, + isolation level serializable, + read only, + read write, + deferrable, + not deferrable; + +start transaction + isolation level read committed + read only + read write + deferrable + not deferrable; + +start transaction + isolation level read committed, + isolation level read uncommitted, + isolation level repeatable read, + isolation level serializable, + read only, + read write, + deferrable, + not deferrable; + +prepare transaction 'f'; + +savepoint foo; + +release savepoint foo; +release foo; + +rollback to savepoint foo; +rollback work to savepoint foo; +rollback transaction to savepoint foo; +rollback to foo; +rollback work to foo; +rollback transaction to foo; + +end; +end work; +end transaction; +end and chain; +end and no chain; + +abort; +abort work; +abort transaction; +abort and chain; +abort and no chain; + +rollback; +rollback work; +rollback transaction; +rollback and chain; +rollback and no chain; +rollback prepared 'foo'; + diff --git a/crates/squawk_parser/test_data/ok/truncate.sql b/crates/squawk_parser/test_data/ok/truncate.sql new file mode 100644 index 00000000..5ea4dcdb --- /dev/null +++ b/crates/squawk_parser/test_data/ok/truncate.sql @@ -0,0 +1,13 @@ +-- pg_grammar +truncate table only t +restart identity +cascade; + +-- multiple_tables +TRUNCATE only a, b *, c; + +-- rest +truncate t; +truncate a continue identity; +truncate a continue identity restrict; + diff --git a/crates/squawk_parser/test_data/ok/unlisten.sql b/crates/squawk_parser/test_data/ok/unlisten.sql new file mode 100644 index 00000000..a83be2af --- /dev/null +++ b/crates/squawk_parser/test_data/ok/unlisten.sql @@ -0,0 +1,5 @@ +-- pg_docs +unlisten virtual; + +unlisten *; + diff --git a/crates/squawk_parser/test_data/ok/update.sql b/crates/squawk_parser/test_data/ok/update.sql new file mode 100644 index 00000000..6f6bddb9 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/update.sql @@ -0,0 +1,91 @@ +-- update +-- update where +update products set price = 10 where price = 5; + +-- no where +UPDATE products SET price = price * 1.10; + +-- set muliple +update mytable set a = 5, b = 3, c = 1 where a > 0; + +-- sub_select +update t set (z) = (select 1); + + +-- with_stmt +with t1 as ( + select 1 +) +update t2 set + foo = default +from t1 where t2.foo_id = t1.foo_id; + +-- based_on_schema +-- all options +update only t as t2 +set + bar = a * 2, + foo = default, + (a) = row(default), + (b, c) = (2, 3), + (z) = (select 1) +from a, b +where t2 = t +returning *, foo * 2 as bar; + +-- pg_docs +UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama'; + +UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT + WHERE city = 'San Francisco' AND date = '2003-07-03'; + +UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT + WHERE city = 'San Francisco' AND date = '2003-07-03' + RETURNING temp_lo, temp_hi, prcp; + +UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT) + WHERE city = 'San Francisco' AND date = '2003-07-03'; + +UPDATE employees SET sales_count = sales_count + 1 FROM accounts + WHERE accounts.name = 'Acme Corporation' + AND employees.id = accounts.sales_person; + +UPDATE employees SET sales_count = sales_count + 1 WHERE id = + (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation'); + +UPDATE accounts SET (contact_first_name, contact_last_name) = + (SELECT first_name, last_name FROM employees + WHERE employees.id = accounts.sales_person); + +UPDATE accounts SET contact_first_name = first_name, + contact_last_name = last_name + FROM employees WHERE employees.id = accounts.sales_person; + +UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) = + (SELECT sum(x), sum(y), avg(x), avg(y) FROM data d + WHERE d.group_id = s.group_id); + +BEGIN; +-- other operations +SAVEPOINT sp1; +INSERT INTO wines VALUES('Chateau Lafite 2003', '24'); +-- Assume the above fails because of a unique key violation, +-- so now we issue these commands: +ROLLBACK TO sp1; +UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003'; +-- continue with other operations, and eventually +COMMIT; + +UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films; + +WITH exceeded_max_retries AS ( + SELECT w.ctid FROM work_item AS w + WHERE w.status = 'active' AND w.num_retries > 10 + ORDER BY w.retry_timestamp + FOR UPDATE + LIMIT 5000 +) +UPDATE work_item SET status = 'failed' + FROM exceeded_max_retries AS emr + WHERE work_item.ctid = emr.ctid; + diff --git a/crates/squawk_parser/test_data/ok/vacuum.sql b/crates/squawk_parser/test_data/ok/vacuum.sql new file mode 100644 index 00000000..3c98f9d6 --- /dev/null +++ b/crates/squawk_parser/test_data/ok/vacuum.sql @@ -0,0 +1,43 @@ +-- simple +vacuum; + +-- pg_docs +VACUUM (VERBOSE, ANALYZE) onek; + +-- full +VACUUM ( + full, + full true, + full false, + analyze, + analyze true, + analyze false, + disable_page_skipping, + disable_page_skipping true, + disable_page_skipping false, + skip_locked, + skip_locked true, + skip_locked false, + index_cleanup auto, + index_cleanup on, + index_cleanup off, + process_main, + process_main true, + process_main false, + truncate, + truncate true, + truncate false, + parallel 100, + skip_database_stats, + skip_database_stats true, + skip_database_stats false, + only_database_stats, + only_database_stats true, + only_database_stats false, + buffer_usage_limit 10, + buffer_usage_limit '10 TB' +) t1; + +-- pre_pg_9_syntax +vacuum full freeze verbose analyze foo, bar(a, b), c; + diff --git a/crates/squawk_parser/test_data/ok/values.sql b/crates/squawk_parser/test_data/ok/values.sql new file mode 100644 index 00000000..2704276b --- /dev/null +++ b/crates/squawk_parser/test_data/ok/values.sql @@ -0,0 +1,40 @@ +-- pg_docs +VALUES (1, 'one'), (2, 'two'), (3, 'three'); + +-- union_with_select +SELECT 1 AS column1, 'one' AS column2 +UNION ALL +SELECT 2, 'two' +UNION ALL +SELECT 3, 'three'; + + + + +-- insert_values +INSERT INTO films VALUES + ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'), + ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama', DEFAULT); + +-- in_select_from_position +SELECT f.* + FROM films f, (VALUES('MGM', 'Horror'), ('UA', 'Sci-Fi')) AS t (studio, kind) + WHERE f.studio = t.studio AND f.kind = t.kind; + +-- update_from +UPDATE employees SET salary = salary * v.increase +FROM (VALUES(1, 200000, 1.2), (2, 400000, 1.4)) AS v (depno, target, increase) +WHERE employees.depno = v.depno AND employees.sales >= v.target; + +-- select_from_in +SELECT * FROM machines +WHERE ip_address IN (VALUES('192.168.0.1'::inet), ('192.168.0.10'), ('192.168.1.43')); + +-- union +values (1, 2) union values (3, 4); + +-- union_select_values +values (1) union values (2) union select 3; + +select (1) union values (2) union select 3; +