From a3a10ffe4e18060708f240efd44745e3d94df4a5 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 16 Jul 2026 16:46:27 -0700 Subject: [PATCH 1/5] feat: moar tests --- build.rs | 4 + tests/common/mod.rs | 28 ++ tests/test_alter_aggregate.rs | 8 + tests/test_alter_collation.rs | 8 + tests/test_alter_conversion.rs | 8 + tests/test_alter_database.rs | 8 + tests/test_alter_default_privileges.rs | 8 + tests/test_alter_domain.rs | 8 + tests/test_alter_event_trigger.rs | 8 + tests/test_alter_extension.rs | 8 + tests/test_alter_foreign_data_wrapper.rs | 8 + tests/test_alter_foreign_table.rs | 8 + tests/test_alter_function.rs | 8 + tests/test_alter_group.rs | 8 + tests/test_alter_index.rs | 8 + tests/test_alter_language.rs | 8 + tests/test_alter_large_object.rs | 8 + tests/test_alter_materialized_view.rs | 8 + tests/test_alter_operator.rs | 8 + tests/test_alter_operator_class.rs | 8 + tests/test_alter_operator_family.rs | 8 + tests/test_alter_policy.rs | 8 + tests/test_alter_procedure.rs | 8 + tests/test_alter_publication.rs | 8 + tests/test_alter_role.rs | 8 + tests/test_alter_routine.rs | 8 + tests/test_alter_rule.rs | 8 + tests/test_alter_schema.rs | 8 + tests/test_alter_sequence.rs | 8 + tests/test_alter_server.rs | 8 + tests/test_alter_statistics.rs | 8 + tests/test_alter_subscription.rs | 8 + tests/test_alter_system.rs | 8 + tests/test_alter_table.rs | 8 + tests/test_alter_tablespace.rs | 8 + tests/test_alter_text_search_configuration.rs | 8 + tests/test_alter_text_search_dictionary.rs | 8 + tests/test_alter_text_search_parser.rs | 8 + tests/test_alter_text_search_template.rs | 8 + tests/test_alter_trigger.rs | 8 + tests/test_alter_type.rs | 8 + tests/test_alter_user.rs | 8 + tests/test_alter_user_mapping.rs | 10 + tests/test_alter_view.rs | 8 + tests/test_comment.rs | 8 + tests/test_create_access_method.rs | 8 + tests/test_create_aggregate.rs | 8 + tests/test_create_cast.rs | 8 + tests/test_create_collation.rs | 8 + tests/test_create_conversion.rs | 10 + tests/test_create_database.rs | 8 + tests/test_create_domain.rs | 8 + tests/test_create_event_trigger.rs | 10 + tests/test_create_extension.rs | 8 + tests/test_create_foreign_data_wrapper.rs | 8 + tests/test_create_foreign_table.rs | 8 + tests/test_create_function.rs | 32 ++ tests/test_create_group.rs | 8 + tests/test_create_index.rs | 8 + tests/test_create_language.rs | 8 + tests/test_create_materialized_view.rs | 8 + tests/test_create_operator.rs | 8 + tests/test_create_operator_class.rs | 10 + tests/test_create_operator_family.rs | 8 + tests/test_create_policy.rs | 8 + tests/test_create_procedure.rs | 8 + tests/test_create_publication.rs | 8 + tests/test_create_role.rs | 8 + tests/test_create_rule.rs | 8 + tests/test_create_schema.rs | 8 + tests/test_create_sequence.rs | 8 + tests/test_create_server.rs | 8 + tests/test_create_statistics.rs | 8 + tests/test_create_subscription.rs | 10 + tests/test_create_table.rs | 328 ++++++++++++++++++ tests/test_create_table_as.rs | 8 + tests/test_create_tablespace.rs | 8 + .../test_create_text_search_configuration.rs | 8 + tests/test_create_text_search_dictionary.rs | 8 + tests/test_create_text_search_parser.rs | 10 + tests/test_create_text_search_template.rs | 8 + tests/test_create_transform.rs | 10 + tests/test_create_trigger.rs | 10 + tests/test_create_type.rs | 8 + tests/test_create_user.rs | 8 + tests/test_create_user_mapping.rs | 8 + tests/test_create_view.rs | 8 + tests/test_delete_grammar.rs | 63 ++++ tests/test_drop.rs | 13 + tests/test_drop_access_method.rs | 8 + tests/test_drop_aggregate.rs | 8 + tests/test_drop_cast.rs | 8 + tests/test_drop_collation.rs | 8 + tests/test_drop_conversion.rs | 8 + tests/test_drop_database.rs | 8 + tests/test_drop_domain.rs | 8 + tests/test_drop_event_trigger.rs | 8 + tests/test_drop_extension.rs | 8 + tests/test_drop_foreign_data_wrapper.rs | 8 + tests/test_drop_foreign_table.rs | 8 + tests/test_drop_function.rs | 8 + tests/test_drop_group.rs | 8 + tests/test_drop_index.rs | 8 + tests/test_drop_language.rs | 8 + tests/test_drop_materialized_view.rs | 8 + tests/test_drop_operator.rs | 8 + tests/test_drop_operator_class.rs | 8 + tests/test_drop_operator_family.rs | 8 + tests/test_drop_owned.rs | 8 + tests/test_drop_policy.rs | 8 + tests/test_drop_procedure.rs | 8 + tests/test_drop_publication.rs | 8 + tests/test_drop_role.rs | 8 + tests/test_drop_routine.rs | 8 + tests/test_drop_rule.rs | 8 + tests/test_drop_schema.rs | 8 + tests/test_drop_sequence.rs | 8 + tests/test_drop_server.rs | 8 + tests/test_drop_statistics.rs | 8 + tests/test_drop_subscription.rs | 8 + tests/test_drop_table.rs | 8 + tests/test_drop_tablespace.rs | 8 + tests/test_drop_text_search_configuration.rs | 8 + tests/test_drop_text_search_dictionary.rs | 8 + tests/test_drop_text_search_parser.rs | 8 + tests/test_drop_text_search_template.rs | 8 + tests/test_drop_transform.rs | 8 + tests/test_drop_trigger.rs | 8 + tests/test_drop_type.rs | 8 + tests/test_drop_user.rs | 8 + tests/test_drop_user_mapping.rs | 8 + tests/test_drop_view.rs | 8 + tests/test_import_foreign_schema.rs | 10 + tests/test_insert_grammar.rs | 103 ++++++ tests/test_refresh_materialized_view.rs | 8 + tests/test_reindex.rs | 8 + tests/test_security_label.rs | 8 + tests/test_select_grammar.rs | 229 ++++++++++++ tests/test_select_into.rs | 8 + tests/test_truncate.rs | 8 + tests/test_update_grammar.rs | 79 +++++ 141 files changed, 1953 insertions(+) create mode 100644 tests/common/mod.rs create mode 100644 tests/test_alter_aggregate.rs create mode 100644 tests/test_alter_collation.rs create mode 100644 tests/test_alter_conversion.rs create mode 100644 tests/test_alter_database.rs create mode 100644 tests/test_alter_default_privileges.rs create mode 100644 tests/test_alter_domain.rs create mode 100644 tests/test_alter_event_trigger.rs create mode 100644 tests/test_alter_extension.rs create mode 100644 tests/test_alter_foreign_data_wrapper.rs create mode 100644 tests/test_alter_foreign_table.rs create mode 100644 tests/test_alter_function.rs create mode 100644 tests/test_alter_group.rs create mode 100644 tests/test_alter_index.rs create mode 100644 tests/test_alter_language.rs create mode 100644 tests/test_alter_large_object.rs create mode 100644 tests/test_alter_materialized_view.rs create mode 100644 tests/test_alter_operator.rs create mode 100644 tests/test_alter_operator_class.rs create mode 100644 tests/test_alter_operator_family.rs create mode 100644 tests/test_alter_policy.rs create mode 100644 tests/test_alter_procedure.rs create mode 100644 tests/test_alter_publication.rs create mode 100644 tests/test_alter_role.rs create mode 100644 tests/test_alter_routine.rs create mode 100644 tests/test_alter_rule.rs create mode 100644 tests/test_alter_schema.rs create mode 100644 tests/test_alter_sequence.rs create mode 100644 tests/test_alter_server.rs create mode 100644 tests/test_alter_statistics.rs create mode 100644 tests/test_alter_subscription.rs create mode 100644 tests/test_alter_system.rs create mode 100644 tests/test_alter_table.rs create mode 100644 tests/test_alter_tablespace.rs create mode 100644 tests/test_alter_text_search_configuration.rs create mode 100644 tests/test_alter_text_search_dictionary.rs create mode 100644 tests/test_alter_text_search_parser.rs create mode 100644 tests/test_alter_text_search_template.rs create mode 100644 tests/test_alter_trigger.rs create mode 100644 tests/test_alter_type.rs create mode 100644 tests/test_alter_user.rs create mode 100644 tests/test_alter_user_mapping.rs create mode 100644 tests/test_alter_view.rs create mode 100644 tests/test_comment.rs create mode 100644 tests/test_create_access_method.rs create mode 100644 tests/test_create_aggregate.rs create mode 100644 tests/test_create_cast.rs create mode 100644 tests/test_create_collation.rs create mode 100644 tests/test_create_conversion.rs create mode 100644 tests/test_create_database.rs create mode 100644 tests/test_create_domain.rs create mode 100644 tests/test_create_event_trigger.rs create mode 100644 tests/test_create_extension.rs create mode 100644 tests/test_create_foreign_data_wrapper.rs create mode 100644 tests/test_create_foreign_table.rs create mode 100644 tests/test_create_function.rs create mode 100644 tests/test_create_group.rs create mode 100644 tests/test_create_index.rs create mode 100644 tests/test_create_language.rs create mode 100644 tests/test_create_materialized_view.rs create mode 100644 tests/test_create_operator.rs create mode 100644 tests/test_create_operator_class.rs create mode 100644 tests/test_create_operator_family.rs create mode 100644 tests/test_create_policy.rs create mode 100644 tests/test_create_procedure.rs create mode 100644 tests/test_create_publication.rs create mode 100644 tests/test_create_role.rs create mode 100644 tests/test_create_rule.rs create mode 100644 tests/test_create_schema.rs create mode 100644 tests/test_create_sequence.rs create mode 100644 tests/test_create_server.rs create mode 100644 tests/test_create_statistics.rs create mode 100644 tests/test_create_subscription.rs create mode 100644 tests/test_create_table.rs create mode 100644 tests/test_create_table_as.rs create mode 100644 tests/test_create_tablespace.rs create mode 100644 tests/test_create_text_search_configuration.rs create mode 100644 tests/test_create_text_search_dictionary.rs create mode 100644 tests/test_create_text_search_parser.rs create mode 100644 tests/test_create_text_search_template.rs create mode 100644 tests/test_create_transform.rs create mode 100644 tests/test_create_trigger.rs create mode 100644 tests/test_create_type.rs create mode 100644 tests/test_create_user.rs create mode 100644 tests/test_create_user_mapping.rs create mode 100644 tests/test_create_view.rs create mode 100644 tests/test_delete_grammar.rs create mode 100644 tests/test_drop.rs create mode 100644 tests/test_drop_access_method.rs create mode 100644 tests/test_drop_aggregate.rs create mode 100644 tests/test_drop_cast.rs create mode 100644 tests/test_drop_collation.rs create mode 100644 tests/test_drop_conversion.rs create mode 100644 tests/test_drop_database.rs create mode 100644 tests/test_drop_domain.rs create mode 100644 tests/test_drop_event_trigger.rs create mode 100644 tests/test_drop_extension.rs create mode 100644 tests/test_drop_foreign_data_wrapper.rs create mode 100644 tests/test_drop_foreign_table.rs create mode 100644 tests/test_drop_function.rs create mode 100644 tests/test_drop_group.rs create mode 100644 tests/test_drop_index.rs create mode 100644 tests/test_drop_language.rs create mode 100644 tests/test_drop_materialized_view.rs create mode 100644 tests/test_drop_operator.rs create mode 100644 tests/test_drop_operator_class.rs create mode 100644 tests/test_drop_operator_family.rs create mode 100644 tests/test_drop_owned.rs create mode 100644 tests/test_drop_policy.rs create mode 100644 tests/test_drop_procedure.rs create mode 100644 tests/test_drop_publication.rs create mode 100644 tests/test_drop_role.rs create mode 100644 tests/test_drop_routine.rs create mode 100644 tests/test_drop_rule.rs create mode 100644 tests/test_drop_schema.rs create mode 100644 tests/test_drop_sequence.rs create mode 100644 tests/test_drop_server.rs create mode 100644 tests/test_drop_statistics.rs create mode 100644 tests/test_drop_subscription.rs create mode 100644 tests/test_drop_table.rs create mode 100644 tests/test_drop_tablespace.rs create mode 100644 tests/test_drop_text_search_configuration.rs create mode 100644 tests/test_drop_text_search_dictionary.rs create mode 100644 tests/test_drop_text_search_parser.rs create mode 100644 tests/test_drop_text_search_template.rs create mode 100644 tests/test_drop_transform.rs create mode 100644 tests/test_drop_trigger.rs create mode 100644 tests/test_drop_type.rs create mode 100644 tests/test_drop_user.rs create mode 100644 tests/test_drop_user_mapping.rs create mode 100644 tests/test_drop_view.rs create mode 100644 tests/test_import_foreign_schema.rs create mode 100644 tests/test_insert_grammar.rs create mode 100644 tests/test_refresh_materialized_view.rs create mode 100644 tests/test_reindex.rs create mode 100644 tests/test_security_label.rs create mode 100644 tests/test_select_grammar.rs create mode 100644 tests/test_select_into.rs create mode 100644 tests/test_truncate.rs create mode 100644 tests/test_update_grammar.rs diff --git a/build.rs b/build.rs index 1fc3cd6..3422879 100644 --- a/build.rs +++ b/build.rs @@ -1312,6 +1312,10 @@ fn build_node_struct(s: &syn::ItemStruct, type_comment_regex: &Regex) -> NodeStr // Comment claims args is A_Const, but that isn't the case for // `SET TRANSACTION ...` (("VariableSetStmt", "args"), NodeFieldType::List), + // Raw range partition bounds can contain A_Const for concrete values + // and ColumnRef for MINVALUE/MAXVALUE, not only PartitionRangeDatum. + (("PartitionBoundSpec", "lowerdatums"), NodeFieldType::List), + (("PartitionBoundSpec", "upperdatums"), NodeFieldType::List), ]; let attrs = clean_doc_comments(&s.attrs); diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 0000000..a343576 --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,28 @@ +#![allow(dead_code)] + +use pg_raw_parse::{parse, walk::walk}; + +pub fn run_parse_debug_case(query: &str) { + let ast = parse(query).unwrap_or_else(|err| panic!("failed to parse `{query}`: {err:?}")); + assert!(!format!("{:?}", ast).is_empty()) +} + +pub fn run_parse_debug_cases(cases: &[&str]) { + for query in cases { + run_parse_debug_case(query); + } +} + +pub fn run_parse_walk_case(query: &str) { + let ast = parse(query).unwrap_or_else(|err| panic!("failed to parse `{query}`: {err:?}")); + walk(ast.stmts().next().unwrap(), |node| { + assert!(!format!("{:?}", node).is_empty()); + }); + assert!(!format!("{:?}", ast).is_empty()) +} + +pub fn run_parse_walk_cases(cases: &[&str]) { + for query in cases { + run_parse_walk_case(query); + } +} diff --git a/tests/test_alter_aggregate.rs b/tests/test_alter_aggregate.rs new file mode 100644 index 0000000..f37f9ce --- /dev/null +++ b/tests/test_alter_aggregate.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_aggregate_parses() { + run_cases(&["ALTER AGGREGATE my_sum(integer) RENAME TO my_sum2"]); +} diff --git a/tests/test_alter_collation.rs b/tests/test_alter_collation.rs new file mode 100644 index 0000000..6e3a20d --- /dev/null +++ b/tests/test_alter_collation.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_collation_parses() { + run_cases(&["ALTER COLLATION my_collation RENAME TO my_collation2"]); +} diff --git a/tests/test_alter_conversion.rs b/tests/test_alter_conversion.rs new file mode 100644 index 0000000..353ce93 --- /dev/null +++ b/tests/test_alter_conversion.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_conversion_parses() { + run_cases(&["ALTER CONVERSION my_conversion RENAME TO my_conversion2"]); +} diff --git a/tests/test_alter_database.rs b/tests/test_alter_database.rs new file mode 100644 index 0000000..d3b8c16 --- /dev/null +++ b/tests/test_alter_database.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_database_parses() { + run_cases(&["ALTER DATABASE mydb SET work_mem TO '64MB'"]); +} diff --git a/tests/test_alter_default_privileges.rs b/tests/test_alter_default_privileges.rs new file mode 100644 index 0000000..962f781 --- /dev/null +++ b/tests/test_alter_default_privileges.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_default_privileges_parses() { + run_cases(&["ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO public"]); +} diff --git a/tests/test_alter_domain.rs b/tests/test_alter_domain.rs new file mode 100644 index 0000000..834b23b --- /dev/null +++ b/tests/test_alter_domain.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_domain_parses() { + run_cases(&["ALTER DOMAIN my_domain SET NOT NULL"]); +} diff --git a/tests/test_alter_event_trigger.rs b/tests/test_alter_event_trigger.rs new file mode 100644 index 0000000..bd0e9c3 --- /dev/null +++ b/tests/test_alter_event_trigger.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_event_trigger_parses() { + run_cases(&["ALTER EVENT TRIGGER my_event_trigger RENAME TO my_event_trigger2"]); +} diff --git a/tests/test_alter_extension.rs b/tests/test_alter_extension.rs new file mode 100644 index 0000000..0e016d9 --- /dev/null +++ b/tests/test_alter_extension.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_extension_parses() { + run_cases(&["ALTER EXTENSION hstore UPDATE"]); +} diff --git a/tests/test_alter_foreign_data_wrapper.rs b/tests/test_alter_foreign_data_wrapper.rs new file mode 100644 index 0000000..2cdcafa --- /dev/null +++ b/tests/test_alter_foreign_data_wrapper.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_foreign_data_wrapper_parses() { + run_cases(&["ALTER FOREIGN DATA WRAPPER my_fdw RENAME TO my_fdw2"]); +} diff --git a/tests/test_alter_foreign_table.rs b/tests/test_alter_foreign_table.rs new file mode 100644 index 0000000..62c6bfb --- /dev/null +++ b/tests/test_alter_foreign_table.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_foreign_table_parses() { + run_cases(&["ALTER FOREIGN TABLE my_foreign_table RENAME TO my_foreign_table2"]); +} diff --git a/tests/test_alter_function.rs b/tests/test_alter_function.rs new file mode 100644 index 0000000..cd9c4cc --- /dev/null +++ b/tests/test_alter_function.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_function_parses() { + run_cases(&["ALTER FUNCTION my_function(integer) RENAME TO my_function2"]); +} diff --git a/tests/test_alter_group.rs b/tests/test_alter_group.rs new file mode 100644 index 0000000..120c6b5 --- /dev/null +++ b/tests/test_alter_group.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_group_parses() { + run_cases(&["ALTER GROUP my_group ADD USER my_user"]); +} diff --git a/tests/test_alter_index.rs b/tests/test_alter_index.rs new file mode 100644 index 0000000..ec63b69 --- /dev/null +++ b/tests/test_alter_index.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_index_parses() { + run_cases(&["ALTER INDEX my_index RENAME TO my_index2"]); +} diff --git a/tests/test_alter_language.rs b/tests/test_alter_language.rs new file mode 100644 index 0000000..4b51e8b --- /dev/null +++ b/tests/test_alter_language.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_language_parses() { + run_cases(&["ALTER LANGUAGE my_language RENAME TO my_language2"]); +} diff --git a/tests/test_alter_large_object.rs b/tests/test_alter_large_object.rs new file mode 100644 index 0000000..5defb12 --- /dev/null +++ b/tests/test_alter_large_object.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_large_object_parses() { + run_cases(&["ALTER LARGE OBJECT 123 OWNER TO current_user"]); +} diff --git a/tests/test_alter_materialized_view.rs b/tests/test_alter_materialized_view.rs new file mode 100644 index 0000000..78420c9 --- /dev/null +++ b/tests/test_alter_materialized_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_materialized_view_parses() { + run_cases(&["ALTER MATERIALIZED VIEW my_matview RENAME TO my_matview2"]); +} diff --git a/tests/test_alter_operator.rs b/tests/test_alter_operator.rs new file mode 100644 index 0000000..d564547 --- /dev/null +++ b/tests/test_alter_operator.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_operator_parses() { + run_cases(&["ALTER OPERATOR + (integer, integer) OWNER TO current_user"]); +} diff --git a/tests/test_alter_operator_class.rs b/tests/test_alter_operator_class.rs new file mode 100644 index 0000000..5ecaba3 --- /dev/null +++ b/tests/test_alter_operator_class.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_operator_class_parses() { + run_cases(&["ALTER OPERATOR CLASS my_opclass USING btree RENAME TO my_opclass2"]); +} diff --git a/tests/test_alter_operator_family.rs b/tests/test_alter_operator_family.rs new file mode 100644 index 0000000..83edc58 --- /dev/null +++ b/tests/test_alter_operator_family.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_operator_family_parses() { + run_cases(&["ALTER OPERATOR FAMILY my_opfamily USING btree RENAME TO my_opfamily2"]); +} diff --git a/tests/test_alter_policy.rs b/tests/test_alter_policy.rs new file mode 100644 index 0000000..03bc3ec --- /dev/null +++ b/tests/test_alter_policy.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_policy_parses() { + run_cases(&["ALTER POLICY my_policy ON my_table RENAME TO my_policy2"]); +} diff --git a/tests/test_alter_procedure.rs b/tests/test_alter_procedure.rs new file mode 100644 index 0000000..78f0bc5 --- /dev/null +++ b/tests/test_alter_procedure.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_procedure_parses() { + run_cases(&["ALTER PROCEDURE my_procedure(integer) RENAME TO my_procedure2"]); +} diff --git a/tests/test_alter_publication.rs b/tests/test_alter_publication.rs new file mode 100644 index 0000000..39c10ed --- /dev/null +++ b/tests/test_alter_publication.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_publication_parses() { + run_cases(&["ALTER PUBLICATION my_publication RENAME TO my_publication2"]); +} diff --git a/tests/test_alter_role.rs b/tests/test_alter_role.rs new file mode 100644 index 0000000..692887d --- /dev/null +++ b/tests/test_alter_role.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_role_parses() { + run_cases(&["ALTER ROLE my_role SET work_mem TO '64MB'"]); +} diff --git a/tests/test_alter_routine.rs b/tests/test_alter_routine.rs new file mode 100644 index 0000000..1d4a991 --- /dev/null +++ b/tests/test_alter_routine.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_routine_parses() { + run_cases(&["ALTER ROUTINE my_routine(integer) RENAME TO my_routine2"]); +} diff --git a/tests/test_alter_rule.rs b/tests/test_alter_rule.rs new file mode 100644 index 0000000..56f9e4d --- /dev/null +++ b/tests/test_alter_rule.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_rule_parses() { + run_cases(&["ALTER RULE my_rule ON my_table RENAME TO my_rule2"]); +} diff --git a/tests/test_alter_schema.rs b/tests/test_alter_schema.rs new file mode 100644 index 0000000..9d8be59 --- /dev/null +++ b/tests/test_alter_schema.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_schema_parses() { + run_cases(&["ALTER SCHEMA my_schema RENAME TO my_schema2"]); +} diff --git a/tests/test_alter_sequence.rs b/tests/test_alter_sequence.rs new file mode 100644 index 0000000..3abc62d --- /dev/null +++ b/tests/test_alter_sequence.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_sequence_parses() { + run_cases(&["ALTER SEQUENCE my_sequence RESTART WITH 1"]); +} diff --git a/tests/test_alter_server.rs b/tests/test_alter_server.rs new file mode 100644 index 0000000..397d42a --- /dev/null +++ b/tests/test_alter_server.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_server_parses() { + run_cases(&["ALTER SERVER my_server RENAME TO my_server2"]); +} diff --git a/tests/test_alter_statistics.rs b/tests/test_alter_statistics.rs new file mode 100644 index 0000000..cb9c789 --- /dev/null +++ b/tests/test_alter_statistics.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_statistics_parses() { + run_cases(&["ALTER STATISTICS my_statistics SET STATISTICS 100"]); +} diff --git a/tests/test_alter_subscription.rs b/tests/test_alter_subscription.rs new file mode 100644 index 0000000..ab1a62d --- /dev/null +++ b/tests/test_alter_subscription.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_subscription_parses() { + run_cases(&["ALTER SUBSCRIPTION my_subscription ENABLE"]); +} diff --git a/tests/test_alter_system.rs b/tests/test_alter_system.rs new file mode 100644 index 0000000..bf48f62 --- /dev/null +++ b/tests/test_alter_system.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_system_parses() { + run_cases(&["ALTER SYSTEM SET work_mem TO '64MB'"]); +} diff --git a/tests/test_alter_table.rs b/tests/test_alter_table.rs new file mode 100644 index 0000000..35ba51f --- /dev/null +++ b/tests/test_alter_table.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_table_parses() { + run_cases(&["ALTER TABLE my_table ADD COLUMN new_column integer"]); +} diff --git a/tests/test_alter_tablespace.rs b/tests/test_alter_tablespace.rs new file mode 100644 index 0000000..8d7cae9 --- /dev/null +++ b/tests/test_alter_tablespace.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_tablespace_parses() { + run_cases(&["ALTER TABLESPACE my_tablespace RENAME TO my_tablespace2"]); +} diff --git a/tests/test_alter_text_search_configuration.rs b/tests/test_alter_text_search_configuration.rs new file mode 100644 index 0000000..f0982f4 --- /dev/null +++ b/tests/test_alter_text_search_configuration.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_text_search_configuration_parses() { + run_cases(&["ALTER TEXT SEARCH CONFIGURATION my_config RENAME TO my_config2"]); +} diff --git a/tests/test_alter_text_search_dictionary.rs b/tests/test_alter_text_search_dictionary.rs new file mode 100644 index 0000000..47fc266 --- /dev/null +++ b/tests/test_alter_text_search_dictionary.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_text_search_dictionary_parses() { + run_cases(&["ALTER TEXT SEARCH DICTIONARY my_dictionary RENAME TO my_dictionary2"]); +} diff --git a/tests/test_alter_text_search_parser.rs b/tests/test_alter_text_search_parser.rs new file mode 100644 index 0000000..c6bf5b9 --- /dev/null +++ b/tests/test_alter_text_search_parser.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_text_search_parser_parses() { + run_cases(&["ALTER TEXT SEARCH PARSER my_parser RENAME TO my_parser2"]); +} diff --git a/tests/test_alter_text_search_template.rs b/tests/test_alter_text_search_template.rs new file mode 100644 index 0000000..da8cb34 --- /dev/null +++ b/tests/test_alter_text_search_template.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_text_search_template_parses() { + run_cases(&["ALTER TEXT SEARCH TEMPLATE my_template RENAME TO my_template2"]); +} diff --git a/tests/test_alter_trigger.rs b/tests/test_alter_trigger.rs new file mode 100644 index 0000000..84645e8 --- /dev/null +++ b/tests/test_alter_trigger.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_trigger_parses() { + run_cases(&["ALTER TRIGGER my_trigger ON my_table RENAME TO my_trigger2"]); +} diff --git a/tests/test_alter_type.rs b/tests/test_alter_type.rs new file mode 100644 index 0000000..373f2a9 --- /dev/null +++ b/tests/test_alter_type.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_type_parses() { + run_cases(&["ALTER TYPE my_type RENAME TO my_type2"]); +} diff --git a/tests/test_alter_user.rs b/tests/test_alter_user.rs new file mode 100644 index 0000000..f1ba8de --- /dev/null +++ b/tests/test_alter_user.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_user_parses() { + run_cases(&["ALTER USER my_user SET work_mem TO '64MB'"]); +} diff --git a/tests/test_alter_user_mapping.rs b/tests/test_alter_user_mapping.rs new file mode 100644 index 0000000..b227c24 --- /dev/null +++ b/tests/test_alter_user_mapping.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_user_mapping_parses() { + run_cases(&[ + "ALTER USER MAPPING FOR my_user SERVER my_server OPTIONS (SET user 'remote_user')", + ]); +} diff --git a/tests/test_alter_view.rs b/tests/test_alter_view.rs new file mode 100644 index 0000000..7a4fc4c --- /dev/null +++ b/tests/test_alter_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn alter_view_parses() { + run_cases(&["ALTER VIEW my_view RENAME TO my_view2"]); +} diff --git a/tests/test_comment.rs b/tests/test_comment.rs new file mode 100644 index 0000000..f7c69d0 --- /dev/null +++ b/tests/test_comment.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn comment_parses() { + run_cases(&["COMMENT ON TABLE my_table IS 'comment'"]); +} diff --git a/tests/test_create_access_method.rs b/tests/test_create_access_method.rs new file mode 100644 index 0000000..dabb88c --- /dev/null +++ b/tests/test_create_access_method.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_access_method_parses() { + run_cases(&["CREATE ACCESS METHOD my_am TYPE INDEX HANDLER my_handler"]); +} diff --git a/tests/test_create_aggregate.rs b/tests/test_create_aggregate.rs new file mode 100644 index 0000000..9caeb3e --- /dev/null +++ b/tests/test_create_aggregate.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_aggregate_parses() { + run_cases(&["CREATE AGGREGATE my_aggregate(integer) (SFUNC = int4pl, STYPE = integer)"]); +} diff --git a/tests/test_create_cast.rs b/tests/test_create_cast.rs new file mode 100644 index 0000000..5b33279 --- /dev/null +++ b/tests/test_create_cast.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_cast_parses() { + run_cases(&["CREATE CAST (integer AS bigint) WITHOUT FUNCTION AS IMPLICIT"]); +} diff --git a/tests/test_create_collation.rs b/tests/test_create_collation.rs new file mode 100644 index 0000000..e39de90 --- /dev/null +++ b/tests/test_create_collation.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_collation_parses() { + run_cases(&["CREATE COLLATION my_collation (provider = libc, locale = 'C')"]); +} diff --git a/tests/test_create_conversion.rs b/tests/test_create_conversion.rs new file mode 100644 index 0000000..4aece4c --- /dev/null +++ b/tests/test_create_conversion.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_conversion_parses() { + run_cases(&[ + "CREATE DEFAULT CONVERSION my_conversion FOR 'UTF8' TO 'LATIN1' FROM utf8_to_latin1", + ]); +} diff --git a/tests/test_create_database.rs b/tests/test_create_database.rs new file mode 100644 index 0000000..648d4c4 --- /dev/null +++ b/tests/test_create_database.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_database_parses() { + run_cases(&["CREATE DATABASE my_database"]); +} diff --git a/tests/test_create_domain.rs b/tests/test_create_domain.rs new file mode 100644 index 0000000..bfb1985 --- /dev/null +++ b/tests/test_create_domain.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_domain_parses() { + run_cases(&["CREATE DOMAIN my_domain AS integer CHECK (VALUE > 0)"]); +} diff --git a/tests/test_create_event_trigger.rs b/tests/test_create_event_trigger.rs new file mode 100644 index 0000000..e9e74e3 --- /dev/null +++ b/tests/test_create_event_trigger.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_event_trigger_parses() { + run_cases(&[ + "CREATE EVENT TRIGGER my_event_trigger ON ddl_command_start EXECUTE FUNCTION my_function()", + ]); +} diff --git a/tests/test_create_extension.rs b/tests/test_create_extension.rs new file mode 100644 index 0000000..9113f69 --- /dev/null +++ b/tests/test_create_extension.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_extension_parses() { + run_cases(&["CREATE EXTENSION IF NOT EXISTS hstore"]); +} diff --git a/tests/test_create_foreign_data_wrapper.rs b/tests/test_create_foreign_data_wrapper.rs new file mode 100644 index 0000000..47e18a5 --- /dev/null +++ b/tests/test_create_foreign_data_wrapper.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_foreign_data_wrapper_parses() { + run_cases(&["CREATE FOREIGN DATA WRAPPER my_fdw HANDLER my_fdw_handler"]); +} diff --git a/tests/test_create_foreign_table.rs b/tests/test_create_foreign_table.rs new file mode 100644 index 0000000..7ad1ca8 --- /dev/null +++ b/tests/test_create_foreign_table.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_foreign_table_parses() { + run_cases(&["CREATE FOREIGN TABLE my_foreign_table (id integer) SERVER my_server"]); +} diff --git a/tests/test_create_function.rs b/tests/test_create_function.rs new file mode 100644 index 0000000..616a9c6 --- /dev/null +++ b/tests/test_create_function.rs @@ -0,0 +1,32 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_function_parses() { + run_cases(&[ + "CREATE FUNCTION my_function() RETURNS integer LANGUAGE SQL AS 'SELECT 1'", + "CREATE OR REPLACE FUNCTION my_function(arg integer DEFAULT 1) RETURNS TABLE (value integer) LANGUAGE SQL STABLE AS 'SELECT arg'", + ]); +} + +// 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 +// } ... diff --git a/tests/test_create_group.rs b/tests/test_create_group.rs new file mode 100644 index 0000000..22be07e --- /dev/null +++ b/tests/test_create_group.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_group_parses() { + run_cases(&["CREATE GROUP my_group"]); +} diff --git a/tests/test_create_index.rs b/tests/test_create_index.rs new file mode 100644 index 0000000..7b5ff48 --- /dev/null +++ b/tests/test_create_index.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_index_parses() { + run_cases(&["CREATE INDEX my_index ON my_table (id)"]); +} diff --git a/tests/test_create_language.rs b/tests/test_create_language.rs new file mode 100644 index 0000000..8bd51ec --- /dev/null +++ b/tests/test_create_language.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_language_parses() { + run_cases(&["CREATE LANGUAGE my_language"]); +} diff --git a/tests/test_create_materialized_view.rs b/tests/test_create_materialized_view.rs new file mode 100644 index 0000000..44b3f53 --- /dev/null +++ b/tests/test_create_materialized_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_materialized_view_parses() { + run_cases(&["CREATE MATERIALIZED VIEW my_matview AS SELECT 1 AS id"]); +} diff --git a/tests/test_create_operator.rs b/tests/test_create_operator.rs new file mode 100644 index 0000000..5eff8b0 --- /dev/null +++ b/tests/test_create_operator.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_operator_parses() { + run_cases(&["CREATE OPERATOR === (FUNCTION = int4eq, LEFTARG = integer, RIGHTARG = integer)"]); +} diff --git a/tests/test_create_operator_class.rs b/tests/test_create_operator_class.rs new file mode 100644 index 0000000..11fb0cf --- /dev/null +++ b/tests/test_create_operator_class.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_operator_class_parses() { + run_cases(&[ + "CREATE OPERATOR CLASS my_opclass DEFAULT FOR TYPE integer USING btree AS OPERATOR 1 < (integer, integer), FUNCTION 1 btint4cmp(integer, integer)", + ]); +} diff --git a/tests/test_create_operator_family.rs b/tests/test_create_operator_family.rs new file mode 100644 index 0000000..530b18f --- /dev/null +++ b/tests/test_create_operator_family.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_operator_family_parses() { + run_cases(&["CREATE OPERATOR FAMILY my_opfamily USING btree"]); +} diff --git a/tests/test_create_policy.rs b/tests/test_create_policy.rs new file mode 100644 index 0000000..001724b --- /dev/null +++ b/tests/test_create_policy.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_policy_parses() { + run_cases(&["CREATE POLICY my_policy ON my_table USING (true)"]); +} diff --git a/tests/test_create_procedure.rs b/tests/test_create_procedure.rs new file mode 100644 index 0000000..b7083af --- /dev/null +++ b/tests/test_create_procedure.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_procedure_parses() { + run_cases(&["CREATE PROCEDURE my_procedure() LANGUAGE SQL AS 'SELECT 1'"]); +} diff --git a/tests/test_create_publication.rs b/tests/test_create_publication.rs new file mode 100644 index 0000000..22236ca --- /dev/null +++ b/tests/test_create_publication.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_publication_parses() { + run_cases(&["CREATE PUBLICATION my_publication FOR TABLE my_table"]); +} diff --git a/tests/test_create_role.rs b/tests/test_create_role.rs new file mode 100644 index 0000000..3bae714 --- /dev/null +++ b/tests/test_create_role.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_role_parses() { + run_cases(&["CREATE ROLE my_role"]); +} diff --git a/tests/test_create_rule.rs b/tests/test_create_rule.rs new file mode 100644 index 0000000..1a5376c --- /dev/null +++ b/tests/test_create_rule.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_rule_parses() { + run_cases(&["CREATE RULE my_rule AS ON SELECT TO my_table DO INSTEAD SELECT * FROM my_table"]); +} diff --git a/tests/test_create_schema.rs b/tests/test_create_schema.rs new file mode 100644 index 0000000..83e681b --- /dev/null +++ b/tests/test_create_schema.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_schema_parses() { + run_cases(&["CREATE SCHEMA my_schema"]); +} diff --git a/tests/test_create_sequence.rs b/tests/test_create_sequence.rs new file mode 100644 index 0000000..a0f210f --- /dev/null +++ b/tests/test_create_sequence.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_sequence_parses() { + run_cases(&["CREATE SEQUENCE my_sequence"]); +} diff --git a/tests/test_create_server.rs b/tests/test_create_server.rs new file mode 100644 index 0000000..d14c5b4 --- /dev/null +++ b/tests/test_create_server.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_server_parses() { + run_cases(&["CREATE SERVER my_server FOREIGN DATA WRAPPER my_fdw"]); +} diff --git a/tests/test_create_statistics.rs b/tests/test_create_statistics.rs new file mode 100644 index 0000000..24a9955 --- /dev/null +++ b/tests/test_create_statistics.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_statistics_parses() { + run_cases(&["CREATE STATISTICS my_statistics ON a, b FROM my_table"]); +} diff --git a/tests/test_create_subscription.rs b/tests/test_create_subscription.rs new file mode 100644 index 0000000..0c418a2 --- /dev/null +++ b/tests/test_create_subscription.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_subscription_parses() { + run_cases(&[ + "CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost' PUBLICATION my_publication", + ]); +} diff --git a/tests/test_create_table.rs b/tests/test_create_table.rs new file mode 100644 index 0000000..44a0369 --- /dev/null +++ b/tests/test_create_table.rs @@ -0,0 +1,328 @@ +mod common; + +use common::{run_parse_debug_case as run_test, run_parse_debug_cases as run_cases}; +use pg_raw_parse::{Node, parse}; + +#[test] +fn create_table_prefix_variations() { + run_cases(&[ + "CREATE TABLE users ()", + "CREATE TABLE public.users ()", + "CREATE TEMP TABLE users ()", + "CREATE TEMPORARY TABLE users ()", + "CREATE LOCAL TEMP TABLE users ()", + "CREATE LOCAL TEMPORARY TABLE users ()", + "CREATE GLOBAL TEMP TABLE users ()", + "CREATE GLOBAL TEMPORARY TABLE users ()", + "CREATE UNLOGGED TABLE users ()", + "CREATE TABLE IF NOT EXISTS users ()", + "CREATE TEMP TABLE IF NOT EXISTS users ()", + "CREATE UNLOGGED TABLE IF NOT EXISTS users ()", + ]); +} + +#[test] +fn create_table_column_variations() { + run_cases(&[ + "CREATE TABLE users (id integer)", + "CREATE TABLE users (id integer STORAGE PLAIN)", + "CREATE TABLE users (id integer STORAGE EXTERNAL)", + "CREATE TABLE users (id integer STORAGE EXTENDED)", + "CREATE TABLE users (id integer STORAGE MAIN)", + "CREATE TABLE users (id integer STORAGE DEFAULT)", + "CREATE TABLE users (body text COMPRESSION pglz)", + "CREATE TABLE users (name text COLLATE \"C\")", + "CREATE TABLE users (id integer DEFAULT 1)", + "CREATE TABLE users (id integer CONSTRAINT users_id_default DEFAULT 1)", + "CREATE TABLE users (id integer CONSTRAINT users_id_nn NOT NULL)", + "CREATE TABLE users (name text NULL)", + "CREATE TABLE users (email text UNIQUE)", + "CREATE TABLE users (email text UNIQUE NULLS DISTINCT)", + "CREATE TABLE users (email text UNIQUE NULLS NOT DISTINCT)", + "CREATE TABLE users (email text UNIQUE WITH (fillfactor = 70))", + "CREATE TABLE users (email text UNIQUE USING INDEX TABLESPACE fastspace)", + "CREATE TABLE users (id integer PRIMARY KEY)", + "CREATE TABLE users (id integer PRIMARY KEY WITH (fillfactor = 70))", + "CREATE TABLE users (id integer PRIMARY KEY USING INDEX TABLESPACE fastspace)", + "CREATE TABLE users (age integer CHECK (age > 0))", + "CREATE TABLE users (age integer CHECK (age > 0) NO INHERIT)", + "CREATE TABLE users (normalized text GENERATED ALWAYS AS (lower(name)) STORED)", + "CREATE TABLE users (account_id integer REFERENCES accounts)", + "CREATE TABLE users (account_id integer REFERENCES accounts (id))", + "CREATE TABLE users (account_id integer REFERENCES accounts (id) MATCH FULL)", + "CREATE TABLE users (account_id integer REFERENCES accounts (id) MATCH SIMPLE)", + "CREATE TABLE users (account_id integer REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE SET NULL)", + "CREATE TABLE users (account_id integer REFERENCES accounts (id) DEFERRABLE INITIALLY DEFERRED)", + "CREATE TABLE users (account_id integer REFERENCES accounts (id) NOT DEFERRABLE INITIALLY IMMEDIATE)", + ]); +} + +#[test] +fn create_table_constraint_variations() { + run_cases(&[ + "CREATE TABLE users (id integer, email text, UNIQUE (email))", + "CREATE TABLE users (id integer, email text, UNIQUE NULLS DISTINCT (email))", + "CREATE TABLE users (id integer, email text, UNIQUE NULLS NOT DISTINCT (email))", + "CREATE TABLE users (id integer, email text, UNIQUE (email) INCLUDE (id))", + "CREATE TABLE users (id integer, email text, UNIQUE (email) WITH (fillfactor = 70))", + "CREATE TABLE users (id integer, email text, CONSTRAINT users_email_key UNIQUE (email) USING INDEX TABLESPACE fastspace)", + "CREATE TABLE users (id integer, PRIMARY KEY (id))", + "CREATE TABLE users (id integer, email text, PRIMARY KEY (id) INCLUDE (email))", + "CREATE TABLE users (id integer, PRIMARY KEY (id) WITH (fillfactor = 70))", + "CREATE TABLE users (id integer, CONSTRAINT users_pkey PRIMARY KEY (id) USING INDEX TABLESPACE fastspace)", + "CREATE TABLE users (age integer, CHECK (age > 0))", + "CREATE TABLE users (age integer, CHECK (age > 0) NO INHERIT)", + "CREATE TABLE users (room int4range, EXCLUDE USING gist (room WITH &&))", + "CREATE TABLE users (room int4range, during tstzrange, EXCLUDE USING gist (room WITH &&, during WITH &&) WHERE (room IS NOT NULL))", + "CREATE TABLE users (room int4range, EXCLUDE (room WITH &&) INCLUDE (room) WITH (fillfactor = 70) USING INDEX TABLESPACE fastspace)", + "CREATE TABLE users (account_id integer, FOREIGN KEY (account_id) REFERENCES accounts)", + "CREATE TABLE users (account_id integer, tenant_id integer, FOREIGN KEY (account_id, tenant_id) REFERENCES accounts (id, tenant_id))", + "CREATE TABLE users (account_id integer, FOREIGN KEY (account_id) REFERENCES accounts (id) MATCH FULL ON DELETE CASCADE ON UPDATE RESTRICT)", + "CREATE TABLE users (account_id integer, tenant_id integer, FOREIGN KEY (account_id, tenant_id) REFERENCES accounts (id, tenant_id) ON DELETE SET NULL (account_id) ON UPDATE SET DEFAULT)", + "CREATE TABLE users (account_id integer, FOREIGN KEY (account_id) REFERENCES accounts (id) MATCH SIMPLE ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED)", + "CREATE TABLE users (account_id integer, CONSTRAINT users_account_fk FOREIGN KEY (account_id) REFERENCES accounts (id) NOT DEFERRABLE INITIALLY IMMEDIATE)", + ]); +} + +#[test] +fn create_table_like_variations() { + run_cases(&[ + "CREATE TABLE users (LIKE old_users)", + "CREATE TABLE users (LIKE old_users INCLUDING COMMENTS)", + "CREATE TABLE users (LIKE old_users INCLUDING COMPRESSION)", + "CREATE TABLE users (LIKE old_users INCLUDING CONSTRAINTS)", + "CREATE TABLE users (LIKE old_users INCLUDING DEFAULTS)", + "CREATE TABLE users (LIKE old_users INCLUDING GENERATED)", + "CREATE TABLE users (LIKE old_users INCLUDING IDENTITY)", + "CREATE TABLE users (LIKE old_users INCLUDING INDEXES)", + "CREATE TABLE users (LIKE old_users INCLUDING STATISTICS)", + "CREATE TABLE users (LIKE old_users INCLUDING STORAGE)", + "CREATE TABLE users (LIKE old_users INCLUDING ALL)", + "CREATE TABLE users (LIKE old_users EXCLUDING COMMENTS)", + "CREATE TABLE users (LIKE old_users EXCLUDING COMPRESSION)", + "CREATE TABLE users (LIKE old_users EXCLUDING CONSTRAINTS)", + "CREATE TABLE users (LIKE old_users EXCLUDING DEFAULTS)", + "CREATE TABLE users (LIKE old_users EXCLUDING GENERATED)", + "CREATE TABLE users (LIKE old_users EXCLUDING IDENTITY)", + "CREATE TABLE users (LIKE old_users EXCLUDING INDEXES)", + "CREATE TABLE users (LIKE old_users EXCLUDING STATISTICS)", + "CREATE TABLE users (LIKE old_users EXCLUDING STORAGE)", + "CREATE TABLE users (LIKE old_users EXCLUDING ALL)", + "CREATE TABLE users (LIKE old_users INCLUDING DEFAULTS EXCLUDING INDEXES)", + "CREATE TABLE users (id integer, LIKE old_users INCLUDING DEFAULTS, email text)", + ]); +} + +#[test] +fn create_table_options_variations() { + run_cases(&[ + "CREATE TABLE users (id integer) INHERITS (base_users)", + "CREATE TABLE users (id integer) INHERITS (base_users, audited_rows)", + "CREATE TABLE users (id integer) PARTITION BY RANGE (created_at)", + "CREATE TABLE users (id integer) PARTITION BY RANGE ((lower(name)) COLLATE \"C\" text_ops)", + "CREATE TABLE users (id integer) PARTITION BY LIST (tenant_id)", + "CREATE TABLE users (id integer) PARTITION BY HASH (tenant_id)", + "CREATE TABLE users (id integer) USING heap", + "CREATE TABLE users (id integer) WITH (fillfactor = 70)", + "CREATE TABLE users (id integer) WITH (fillfactor)", + "CREATE TABLE users (id integer) WITHOUT OIDS", + "CREATE TEMP TABLE users (id integer) ON COMMIT PRESERVE ROWS", + "CREATE TEMP TABLE users (id integer) ON COMMIT DELETE ROWS", + "CREATE TEMP TABLE users (id integer) ON COMMIT DROP", + "CREATE TABLE users (id integer) TABLESPACE fastspace", + "CREATE TEMP TABLE users (id integer) INHERITS (base_users) WITHOUT OIDS ON COMMIT DELETE ROWS TABLESPACE fastspace", + ]); +} + +#[test] +fn create_typed_table_variations() { + run_cases(&[ + "CREATE TABLE users OF user_type", + "CREATE TABLE users OF user_type (id WITH OPTIONS NOT NULL)", + "CREATE TABLE users OF user_type (id WITH OPTIONS DEFAULT 1, CHECK (id > 0))", + "CREATE TABLE users OF user_type PARTITION BY HASH (id)", + "CREATE TABLE users OF user_type USING heap WITH (fillfactor = 70) TABLESPACE fastspace", + ]); +} + +#[test] +fn create_partition_table_variations() { + run_cases(&[ + "CREATE TABLE users_default PARTITION OF users DEFAULT", + "CREATE TABLE users_us PARTITION OF users FOR VALUES IN ('us', 'ca')", + "CREATE TABLE users_hash_0 PARTITION OF users FOR VALUES WITH (MODULUS 4, REMAINDER 0)", + "CREATE TABLE users_hash_0 PARTITION OF users (id WITH OPTIONS NOT NULL) FOR VALUES WITH (MODULUS 4, REMAINDER 0)", + "CREATE TABLE users_us PARTITION OF users FOR VALUES IN ('us', 'ca') PARTITION BY HASH (tenant_id)", + "CREATE TABLE users_us PARTITION OF users FOR VALUES IN ('us', 'ca') USING heap WITH (fillfactor = 70) TABLESPACE fastspace", + ]); +} + +#[test] +fn create_table_identity_variations() { + run_cases(&[ + "CREATE TABLE users (id integer GENERATED ALWAYS AS IDENTITY)", + "CREATE TABLE users (id integer GENERATED BY DEFAULT AS IDENTITY)", + "CREATE TABLE users (id integer GENERATED ALWAYS AS IDENTITY (START WITH 10 INCREMENT BY 2))", + ]); +} + +#[test] +fn create_table_exclude_element_variations() { + run_cases(&[ + "CREATE TABLE bookings (room int4range, EXCLUDE USING gist (room WITH &&))", + "CREATE TABLE bookings (room text, EXCLUDE USING gist (room COLLATE \"C\" text_ops WITH =))", + "CREATE TABLE bookings (room text, EXCLUDE USING gist ((lower(room)) WITH =))", + "CREATE TABLE bookings (room int, EXCLUDE USING btree (room ASC NULLS LAST WITH =))", + ]); +} + +#[test] +#[should_panic(expected = "MATCH PARTIAL not yet implemented")] +fn failing_create_table_column_reference_match_partial() { + run_test("CREATE TABLE users (account_id integer REFERENCES accounts (id) MATCH PARTIAL)"); +} + +#[test] +#[should_panic(expected = "MATCH PARTIAL not yet implemented")] +fn failing_create_table_table_reference_match_partial() { + run_test( + "CREATE TABLE users (account_id integer, FOREIGN KEY (account_id) REFERENCES accounts (id) MATCH PARTIAL ON DELETE SET NULL ON UPDATE SET DEFAULT)", + ); +} + +#[test] +fn create_table_column_not_null_no_inherit() { + run_test("CREATE TABLE users (id integer NOT NULL NO INHERIT)"); +} + +#[test] +fn create_table_partition_of_range_from_to() { + run_test( + "CREATE TABLE users_2024 PARTITION OF users FOR VALUES FROM ('2024-01-01') TO ('2025-01-01')", + ); +} + +#[test] +fn create_table_partition_of_range_minvalue_maxvalue() { + run_test( + "CREATE TABLE users_2024 PARTITION OF users (id WITH OPTIONS NOT NULL) FOR VALUES FROM (MINVALUE) TO (MAXVALUE)", + ); +} + +#[test] +fn create_table_partition_of_range_with_partition_by() { + let ast = parse( + "CREATE TABLE users_2024 PARTITION OF users FOR VALUES FROM ('2024-01-01') TO ('2025-01-01') PARTITION BY HASH (tenant_id)", + ) + .unwrap(); + + // Range partition bounds are exposed through CreateStmt::partbound(). + // lowerdatums()/upperdatums() are generic NodeLists because raw parse + // trees can contain A_Const nodes for concrete values. + let Node::CreateStmt(stmt) = ast.stmts().next().unwrap() else { + panic!("expected CREATE TABLE statement"); + }; + let bounds = stmt.partbound().expect("expected partition bounds"); + let lower = bounds.lowerdatums().first().expect("expected lower bound"); + let upper = bounds.upperdatums().first().expect("expected upper bound"); + + assert!(matches!(lower, Node::A_Const(_))); + assert!(matches!(upper, Node::A_Const(_))); + assert!(!format!("{bounds:?}").is_empty()); +} + +#[test] +fn create_table_partition_of_range_with_options() { + run_test( + "CREATE TABLE users_2024 PARTITION OF users FOR VALUES FROM ('2024-01-01') TO ('2025-01-01') USING heap WITH (fillfactor = 70) TABLESPACE fastspace", + ); +} + +// 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 ] + +// where column_constraint is: + +// [ CONSTRAINT constraint_name ] +// { NOT NULL [ NO INHERIT ] | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | +// 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 ] [ ENFORCED | NOT ENFORCED ] + +// and table_constraint is: + +// [ CONSTRAINT constraint_name ] +// { CHECK ( expression ) [ NO INHERIT ] | +// NOT NULL column_name [ NO INHERIT ] | +// UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | +// PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | +// EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | +// FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] +// [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] + +// and like_option is: + +// { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } + +// 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 ) + +// index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: + +// [ INCLUDE ( column_name [, ... ] ) ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ USING INDEX TABLESPACE tablespace_name ] + +// exclude_element in an EXCLUDE constraint is: + +// { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] + +// referential_action in a FOREIGN KEY/REFERENCES constraint is: + +// { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } diff --git a/tests/test_create_table_as.rs b/tests/test_create_table_as.rs new file mode 100644 index 0000000..15d468b --- /dev/null +++ b/tests/test_create_table_as.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_table_as_parses() { + run_cases(&["CREATE TABLE my_table AS SELECT 1 AS id"]); +} diff --git a/tests/test_create_tablespace.rs b/tests/test_create_tablespace.rs new file mode 100644 index 0000000..90a9e0a --- /dev/null +++ b/tests/test_create_tablespace.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_tablespace_parses() { + run_cases(&["CREATE TABLESPACE my_tablespace LOCATION '/tmp/my_tablespace'"]); +} diff --git a/tests/test_create_text_search_configuration.rs b/tests/test_create_text_search_configuration.rs new file mode 100644 index 0000000..016d7ac --- /dev/null +++ b/tests/test_create_text_search_configuration.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_text_search_configuration_parses() { + run_cases(&["CREATE TEXT SEARCH CONFIGURATION my_config (PARSER = default)"]); +} diff --git a/tests/test_create_text_search_dictionary.rs b/tests/test_create_text_search_dictionary.rs new file mode 100644 index 0000000..bc298bc --- /dev/null +++ b/tests/test_create_text_search_dictionary.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_text_search_dictionary_parses() { + run_cases(&["CREATE TEXT SEARCH DICTIONARY my_dictionary (TEMPLATE = simple)"]); +} diff --git a/tests/test_create_text_search_parser.rs b/tests/test_create_text_search_parser.rs new file mode 100644 index 0000000..cdbec24 --- /dev/null +++ b/tests/test_create_text_search_parser.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_text_search_parser_parses() { + run_cases(&[ + "CREATE TEXT SEARCH PARSER my_parser (START = prsd_start, GETTOKEN = prsd_nexttoken, END = prsd_end, LEXTYPES = prsd_lextype)", + ]); +} diff --git a/tests/test_create_text_search_template.rs b/tests/test_create_text_search_template.rs new file mode 100644 index 0000000..79ab0ae --- /dev/null +++ b/tests/test_create_text_search_template.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_text_search_template_parses() { + run_cases(&["CREATE TEXT SEARCH TEMPLATE my_template (LEXIZE = dsimple_lexize)"]); +} diff --git a/tests/test_create_transform.rs b/tests/test_create_transform.rs new file mode 100644 index 0000000..3bdb51e --- /dev/null +++ b/tests/test_create_transform.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_transform_parses() { + run_cases(&[ + "CREATE TRANSFORM FOR integer LANGUAGE plpython3u (FROM SQL WITH FUNCTION from_sql(integer), TO SQL WITH FUNCTION to_sql(integer))", + ]); +} diff --git a/tests/test_create_trigger.rs b/tests/test_create_trigger.rs new file mode 100644 index 0000000..431901c --- /dev/null +++ b/tests/test_create_trigger.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_trigger_parses() { + run_cases(&[ + "CREATE TRIGGER my_trigger BEFORE INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION my_function()", + ]); +} diff --git a/tests/test_create_type.rs b/tests/test_create_type.rs new file mode 100644 index 0000000..1871f96 --- /dev/null +++ b/tests/test_create_type.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_type_parses() { + run_cases(&["CREATE TYPE my_type AS (id integer)"]); +} diff --git a/tests/test_create_user.rs b/tests/test_create_user.rs new file mode 100644 index 0000000..9449cc2 --- /dev/null +++ b/tests/test_create_user.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_user_parses() { + run_cases(&["CREATE USER my_user"]); +} diff --git a/tests/test_create_user_mapping.rs b/tests/test_create_user_mapping.rs new file mode 100644 index 0000000..e53b51e --- /dev/null +++ b/tests/test_create_user_mapping.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_user_mapping_parses() { + run_cases(&["CREATE USER MAPPING FOR my_user SERVER my_server OPTIONS (user 'remote_user')"]); +} diff --git a/tests/test_create_view.rs b/tests/test_create_view.rs new file mode 100644 index 0000000..73a1ef5 --- /dev/null +++ b/tests/test_create_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn create_view_parses() { + run_cases(&["CREATE VIEW my_view AS SELECT 1 AS id"]); +} diff --git a/tests/test_delete_grammar.rs b/tests/test_delete_grammar.rs new file mode 100644 index 0000000..68903ae --- /dev/null +++ b/tests/test_delete_grammar.rs @@ -0,0 +1,63 @@ +mod common; + +use common::run_parse_walk_cases as run_cases; + +#[test] +fn delete_target_variations() { + run_cases(&[ + "DELETE FROM users", + "DELETE FROM ONLY users", + "DELETE FROM users *", + "DELETE FROM users AS u", + "DELETE FROM users u", + "DELETE FROM public.users AS u", + ]); +} + +#[test] +fn delete_with_clause_variations() { + run_cases(&[ + "WITH stale AS (SELECT id FROM users WHERE active = false) DELETE FROM users USING stale WHERE users.id = stale.id", + "WITH RECURSIVE stale(id) AS (SELECT 1 UNION ALL SELECT id + 1 FROM stale WHERE id < 3) DELETE FROM users USING stale WHERE users.id = stale.id", + "WITH stale AS MATERIALIZED (SELECT id FROM users) DELETE FROM users USING stale WHERE users.id = stale.id", + "WITH stale AS NOT MATERIALIZED (SELECT id FROM users) DELETE FROM users USING stale WHERE users.id = stale.id", + ]); +} + +#[test] +fn delete_using_variations() { + run_cases(&[ + "DELETE FROM users USING orders WHERE users.id = orders.user_id", + "DELETE FROM users USING orders o, sessions s WHERE users.id = o.user_id AND users.id = s.user_id", + "DELETE FROM users USING ONLY archived_users au WHERE users.id = au.id", + "DELETE FROM users USING LATERAL (SELECT 1 AS id) s WHERE users.id = s.id", + "DELETE FROM users USING generate_series(1, 3) AS g(id) WHERE users.id = g.id", + "DELETE FROM users USING orders JOIN invoices ON orders.id = invoices.order_id WHERE users.id = orders.user_id", + ]); +} + +#[test] +fn delete_where_variations() { + run_cases(&[ + "DELETE FROM users WHERE id = 1", + "DELETE FROM users WHERE id = $1 AND active = $2", + "DELETE FROM users WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id)", + "DELETE FROM users WHERE CURRENT OF user_cursor", + ]); +} + +#[test] +fn delete_returning_variations() { + run_cases(&[ + "DELETE FROM users RETURNING *", + "DELETE FROM users RETURNING id", + "DELETE FROM users RETURNING id AS deleted_id, email old_email", + ]); +} + +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] +// [ USING from_item [, ...] ] +// [ WHERE condition | WHERE CURRENT OF cursor_name ] +// [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] +// { * | output_expression [ [ AS ] output_name ] } [, ...] ] diff --git a/tests/test_drop.rs b/tests/test_drop.rs new file mode 100644 index 0000000..a943a0b --- /dev/null +++ b/tests/test_drop.rs @@ -0,0 +1,13 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_parses() { + run_cases(&[ + "DROP TABLE IF EXISTS my_table", + "DROP TABLE IF EXISTS my_table, other_table CASCADE", + ]); +} + +// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] diff --git a/tests/test_drop_access_method.rs b/tests/test_drop_access_method.rs new file mode 100644 index 0000000..1864c44 --- /dev/null +++ b/tests/test_drop_access_method.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_access_method_parses() { + run_cases(&["DROP ACCESS METHOD IF EXISTS my_am"]); +} diff --git a/tests/test_drop_aggregate.rs b/tests/test_drop_aggregate.rs new file mode 100644 index 0000000..dd61feb --- /dev/null +++ b/tests/test_drop_aggregate.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_aggregate_parses() { + run_cases(&["DROP AGGREGATE IF EXISTS my_aggregate(integer)"]); +} diff --git a/tests/test_drop_cast.rs b/tests/test_drop_cast.rs new file mode 100644 index 0000000..b820681 --- /dev/null +++ b/tests/test_drop_cast.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_cast_parses() { + run_cases(&["DROP CAST IF EXISTS (integer AS bigint)"]); +} diff --git a/tests/test_drop_collation.rs b/tests/test_drop_collation.rs new file mode 100644 index 0000000..3e98d4e --- /dev/null +++ b/tests/test_drop_collation.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_collation_parses() { + run_cases(&["DROP COLLATION IF EXISTS my_collation"]); +} diff --git a/tests/test_drop_conversion.rs b/tests/test_drop_conversion.rs new file mode 100644 index 0000000..97ee626 --- /dev/null +++ b/tests/test_drop_conversion.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_conversion_parses() { + run_cases(&["DROP CONVERSION IF EXISTS my_conversion"]); +} diff --git a/tests/test_drop_database.rs b/tests/test_drop_database.rs new file mode 100644 index 0000000..4d246ad --- /dev/null +++ b/tests/test_drop_database.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_database_parses() { + run_cases(&["DROP DATABASE IF EXISTS my_database"]); +} diff --git a/tests/test_drop_domain.rs b/tests/test_drop_domain.rs new file mode 100644 index 0000000..137ae5e --- /dev/null +++ b/tests/test_drop_domain.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_domain_parses() { + run_cases(&["DROP DOMAIN IF EXISTS my_domain"]); +} diff --git a/tests/test_drop_event_trigger.rs b/tests/test_drop_event_trigger.rs new file mode 100644 index 0000000..adedd0c --- /dev/null +++ b/tests/test_drop_event_trigger.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_event_trigger_parses() { + run_cases(&["DROP EVENT TRIGGER IF EXISTS my_event_trigger"]); +} diff --git a/tests/test_drop_extension.rs b/tests/test_drop_extension.rs new file mode 100644 index 0000000..f658991 --- /dev/null +++ b/tests/test_drop_extension.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_extension_parses() { + run_cases(&["DROP EXTENSION IF EXISTS hstore"]); +} diff --git a/tests/test_drop_foreign_data_wrapper.rs b/tests/test_drop_foreign_data_wrapper.rs new file mode 100644 index 0000000..cdc43ac --- /dev/null +++ b/tests/test_drop_foreign_data_wrapper.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_foreign_data_wrapper_parses() { + run_cases(&["DROP FOREIGN DATA WRAPPER IF EXISTS my_fdw"]); +} diff --git a/tests/test_drop_foreign_table.rs b/tests/test_drop_foreign_table.rs new file mode 100644 index 0000000..5029114 --- /dev/null +++ b/tests/test_drop_foreign_table.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_foreign_table_parses() { + run_cases(&["DROP FOREIGN TABLE IF EXISTS my_foreign_table"]); +} diff --git a/tests/test_drop_function.rs b/tests/test_drop_function.rs new file mode 100644 index 0000000..2d7270b --- /dev/null +++ b/tests/test_drop_function.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_function_parses() { + run_cases(&["DROP FUNCTION IF EXISTS my_function(integer)"]); +} diff --git a/tests/test_drop_group.rs b/tests/test_drop_group.rs new file mode 100644 index 0000000..cbcd06b --- /dev/null +++ b/tests/test_drop_group.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_group_parses() { + run_cases(&["DROP GROUP IF EXISTS my_group"]); +} diff --git a/tests/test_drop_index.rs b/tests/test_drop_index.rs new file mode 100644 index 0000000..2e0e2fd --- /dev/null +++ b/tests/test_drop_index.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_index_parses() { + run_cases(&["DROP INDEX IF EXISTS my_index"]); +} diff --git a/tests/test_drop_language.rs b/tests/test_drop_language.rs new file mode 100644 index 0000000..12344b0 --- /dev/null +++ b/tests/test_drop_language.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_language_parses() { + run_cases(&["DROP LANGUAGE IF EXISTS my_language"]); +} diff --git a/tests/test_drop_materialized_view.rs b/tests/test_drop_materialized_view.rs new file mode 100644 index 0000000..7a25d09 --- /dev/null +++ b/tests/test_drop_materialized_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_materialized_view_parses() { + run_cases(&["DROP MATERIALIZED VIEW IF EXISTS my_matview"]); +} diff --git a/tests/test_drop_operator.rs b/tests/test_drop_operator.rs new file mode 100644 index 0000000..a3c5dce --- /dev/null +++ b/tests/test_drop_operator.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_operator_parses() { + run_cases(&["DROP OPERATOR IF EXISTS + (integer, integer)"]); +} diff --git a/tests/test_drop_operator_class.rs b/tests/test_drop_operator_class.rs new file mode 100644 index 0000000..4b0316d --- /dev/null +++ b/tests/test_drop_operator_class.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_operator_class_parses() { + run_cases(&["DROP OPERATOR CLASS IF EXISTS my_opclass USING btree"]); +} diff --git a/tests/test_drop_operator_family.rs b/tests/test_drop_operator_family.rs new file mode 100644 index 0000000..77abcda --- /dev/null +++ b/tests/test_drop_operator_family.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_operator_family_parses() { + run_cases(&["DROP OPERATOR FAMILY IF EXISTS my_opfamily USING btree"]); +} diff --git a/tests/test_drop_owned.rs b/tests/test_drop_owned.rs new file mode 100644 index 0000000..a65b1c9 --- /dev/null +++ b/tests/test_drop_owned.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_owned_parses() { + run_cases(&["DROP OWNED BY my_role"]); +} diff --git a/tests/test_drop_policy.rs b/tests/test_drop_policy.rs new file mode 100644 index 0000000..be94d5d --- /dev/null +++ b/tests/test_drop_policy.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_policy_parses() { + run_cases(&["DROP POLICY IF EXISTS my_policy ON my_table"]); +} diff --git a/tests/test_drop_procedure.rs b/tests/test_drop_procedure.rs new file mode 100644 index 0000000..9bbfe73 --- /dev/null +++ b/tests/test_drop_procedure.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_procedure_parses() { + run_cases(&["DROP PROCEDURE IF EXISTS my_procedure(integer)"]); +} diff --git a/tests/test_drop_publication.rs b/tests/test_drop_publication.rs new file mode 100644 index 0000000..fa80bc4 --- /dev/null +++ b/tests/test_drop_publication.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_publication_parses() { + run_cases(&["DROP PUBLICATION IF EXISTS my_publication"]); +} diff --git a/tests/test_drop_role.rs b/tests/test_drop_role.rs new file mode 100644 index 0000000..514bd21 --- /dev/null +++ b/tests/test_drop_role.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_role_parses() { + run_cases(&["DROP ROLE IF EXISTS my_role"]); +} diff --git a/tests/test_drop_routine.rs b/tests/test_drop_routine.rs new file mode 100644 index 0000000..c19b47d --- /dev/null +++ b/tests/test_drop_routine.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_routine_parses() { + run_cases(&["DROP ROUTINE IF EXISTS my_routine(integer)"]); +} diff --git a/tests/test_drop_rule.rs b/tests/test_drop_rule.rs new file mode 100644 index 0000000..4c47802 --- /dev/null +++ b/tests/test_drop_rule.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_rule_parses() { + run_cases(&["DROP RULE IF EXISTS my_rule ON my_table"]); +} diff --git a/tests/test_drop_schema.rs b/tests/test_drop_schema.rs new file mode 100644 index 0000000..a05a447 --- /dev/null +++ b/tests/test_drop_schema.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_schema_parses() { + run_cases(&["DROP SCHEMA IF EXISTS my_schema"]); +} diff --git a/tests/test_drop_sequence.rs b/tests/test_drop_sequence.rs new file mode 100644 index 0000000..949a91f --- /dev/null +++ b/tests/test_drop_sequence.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_sequence_parses() { + run_cases(&["DROP SEQUENCE IF EXISTS my_sequence"]); +} diff --git a/tests/test_drop_server.rs b/tests/test_drop_server.rs new file mode 100644 index 0000000..652376b --- /dev/null +++ b/tests/test_drop_server.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_server_parses() { + run_cases(&["DROP SERVER IF EXISTS my_server"]); +} diff --git a/tests/test_drop_statistics.rs b/tests/test_drop_statistics.rs new file mode 100644 index 0000000..cd003f2 --- /dev/null +++ b/tests/test_drop_statistics.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_statistics_parses() { + run_cases(&["DROP STATISTICS IF EXISTS my_statistics"]); +} diff --git a/tests/test_drop_subscription.rs b/tests/test_drop_subscription.rs new file mode 100644 index 0000000..b0bee6a --- /dev/null +++ b/tests/test_drop_subscription.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_subscription_parses() { + run_cases(&["DROP SUBSCRIPTION IF EXISTS my_subscription"]); +} diff --git a/tests/test_drop_table.rs b/tests/test_drop_table.rs new file mode 100644 index 0000000..e6b68dc --- /dev/null +++ b/tests/test_drop_table.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_table_parses() { + run_cases(&["DROP TABLE IF EXISTS my_table"]); +} diff --git a/tests/test_drop_tablespace.rs b/tests/test_drop_tablespace.rs new file mode 100644 index 0000000..b7c71cc --- /dev/null +++ b/tests/test_drop_tablespace.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_tablespace_parses() { + run_cases(&["DROP TABLESPACE IF EXISTS my_tablespace"]); +} diff --git a/tests/test_drop_text_search_configuration.rs b/tests/test_drop_text_search_configuration.rs new file mode 100644 index 0000000..c45807b --- /dev/null +++ b/tests/test_drop_text_search_configuration.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_text_search_configuration_parses() { + run_cases(&["DROP TEXT SEARCH CONFIGURATION IF EXISTS my_config"]); +} diff --git a/tests/test_drop_text_search_dictionary.rs b/tests/test_drop_text_search_dictionary.rs new file mode 100644 index 0000000..5fdcfdd --- /dev/null +++ b/tests/test_drop_text_search_dictionary.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_text_search_dictionary_parses() { + run_cases(&["DROP TEXT SEARCH DICTIONARY IF EXISTS my_dictionary"]); +} diff --git a/tests/test_drop_text_search_parser.rs b/tests/test_drop_text_search_parser.rs new file mode 100644 index 0000000..aac85f4 --- /dev/null +++ b/tests/test_drop_text_search_parser.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_text_search_parser_parses() { + run_cases(&["DROP TEXT SEARCH PARSER IF EXISTS my_parser"]); +} diff --git a/tests/test_drop_text_search_template.rs b/tests/test_drop_text_search_template.rs new file mode 100644 index 0000000..15b10c4 --- /dev/null +++ b/tests/test_drop_text_search_template.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_text_search_template_parses() { + run_cases(&["DROP TEXT SEARCH TEMPLATE IF EXISTS my_template"]); +} diff --git a/tests/test_drop_transform.rs b/tests/test_drop_transform.rs new file mode 100644 index 0000000..8fea2b7 --- /dev/null +++ b/tests/test_drop_transform.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_transform_parses() { + run_cases(&["DROP TRANSFORM IF EXISTS FOR integer LANGUAGE plpython3u"]); +} diff --git a/tests/test_drop_trigger.rs b/tests/test_drop_trigger.rs new file mode 100644 index 0000000..a04718c --- /dev/null +++ b/tests/test_drop_trigger.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_trigger_parses() { + run_cases(&["DROP TRIGGER IF EXISTS my_trigger ON my_table"]); +} diff --git a/tests/test_drop_type.rs b/tests/test_drop_type.rs new file mode 100644 index 0000000..220b9d2 --- /dev/null +++ b/tests/test_drop_type.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_type_parses() { + run_cases(&["DROP TYPE IF EXISTS my_type"]); +} diff --git a/tests/test_drop_user.rs b/tests/test_drop_user.rs new file mode 100644 index 0000000..5aab0de --- /dev/null +++ b/tests/test_drop_user.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_user_parses() { + run_cases(&["DROP USER IF EXISTS my_user"]); +} diff --git a/tests/test_drop_user_mapping.rs b/tests/test_drop_user_mapping.rs new file mode 100644 index 0000000..f98df81 --- /dev/null +++ b/tests/test_drop_user_mapping.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_user_mapping_parses() { + run_cases(&["DROP USER MAPPING IF EXISTS FOR my_user SERVER my_server"]); +} diff --git a/tests/test_drop_view.rs b/tests/test_drop_view.rs new file mode 100644 index 0000000..83b6e9e --- /dev/null +++ b/tests/test_drop_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn drop_view_parses() { + run_cases(&["DROP VIEW IF EXISTS my_view"]); +} diff --git a/tests/test_import_foreign_schema.rs b/tests/test_import_foreign_schema.rs new file mode 100644 index 0000000..638af5b --- /dev/null +++ b/tests/test_import_foreign_schema.rs @@ -0,0 +1,10 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn import_foreign_schema_parses() { + run_cases(&[ + "IMPORT FOREIGN SCHEMA remote_schema LIMIT TO (remote_table) FROM SERVER my_server INTO public", + ]); +} diff --git a/tests/test_insert_grammar.rs b/tests/test_insert_grammar.rs new file mode 100644 index 0000000..3bd0ffd --- /dev/null +++ b/tests/test_insert_grammar.rs @@ -0,0 +1,103 @@ +mod common; + +use common::run_parse_walk_cases as run_cases; + +#[test] +fn insert_target_variations() { + run_cases(&[ + "INSERT INTO users DEFAULT VALUES", + "INSERT INTO public.users DEFAULT VALUES", + "INSERT INTO users AS u DEFAULT VALUES", + "INSERT INTO users (id, name) VALUES (1, 'Sage')", + "INSERT INTO users AS u (id, name) VALUES (1, 'Sage')", + ]); +} + +#[test] +fn insert_with_clause_variations() { + run_cases(&[ + "WITH incoming AS (SELECT 1 AS id, 'Sage' AS name) INSERT INTO users SELECT * FROM incoming", + "WITH RECURSIVE incoming(id) AS (SELECT 1 UNION ALL SELECT id + 1 FROM incoming WHERE id < 3) INSERT INTO users (id) SELECT id FROM incoming", + "WITH incoming AS MATERIALIZED (SELECT 1 AS id) INSERT INTO users (id) SELECT id FROM incoming", + "WITH incoming AS NOT MATERIALIZED (SELECT 1 AS id) INSERT INTO users (id) SELECT id FROM incoming", + ]); +} + +#[test] +fn insert_value_source_variations() { + run_cases(&[ + "INSERT INTO users DEFAULT VALUES", + "INSERT INTO users (id, name) VALUES (1, 'Sage')", + "INSERT INTO users (id, name) VALUES (1, DEFAULT)", + "INSERT INTO users (id, name) VALUES (1, 'Sage'), (2, 'River')", + "INSERT INTO users (id, name) VALUES ($1, $2)", + "INSERT INTO users (id, name) SELECT id, name FROM incoming", + "INSERT INTO users SELECT * FROM incoming", + ]); +} + +#[test] +fn insert_overriding_variations() { + run_cases(&[ + "INSERT INTO users (id) OVERRIDING SYSTEM VALUE VALUES (1)", + "INSERT INTO users (id) OVERRIDING USER VALUE VALUES (1)", + "INSERT INTO users (id) OVERRIDING SYSTEM VALUE SELECT id FROM incoming", + "INSERT INTO users (id) OVERRIDING USER VALUE SELECT id FROM incoming", + ]); +} + +#[test] +fn insert_on_conflict_target_variations() { + run_cases(&[ + "INSERT INTO users (id) VALUES (1) ON CONFLICT DO NOTHING", + "INSERT INTO users (id) VALUES (1) ON CONFLICT (id) DO NOTHING", + "INSERT INTO users (email) VALUES ('a@example.com') ON CONFLICT ((lower(email))) DO NOTHING", + "INSERT INTO users (email) VALUES ('a@example.com') ON CONFLICT (email COLLATE \"C\") DO NOTHING", + "INSERT INTO users (email) VALUES ('a@example.com') ON CONFLICT (email text_ops) DO NOTHING", + "INSERT INTO users (email) VALUES ('a@example.com') ON CONFLICT (email) WHERE active DO NOTHING", + "INSERT INTO users (email) VALUES ('a@example.com') ON CONFLICT ON CONSTRAINT users_email_key DO NOTHING", + ]); +} + +#[test] +fn insert_on_conflict_action_variations() { + run_cases(&[ + "INSERT INTO users (id, name) VALUES (1, 'Sage') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name", + "INSERT INTO users (id, name) VALUES (1, 'Sage') ON CONFLICT (id) DO UPDATE SET name = DEFAULT", + "INSERT INTO users (id, name, active) VALUES (1, 'Sage', true) ON CONFLICT (id) DO UPDATE SET (name, active) = ROW (EXCLUDED.name, DEFAULT)", + "INSERT INTO users (id, name, active) VALUES (1, 'Sage', true) ON CONFLICT (id) DO UPDATE SET (name, active) = (EXCLUDED.name, DEFAULT)", + "INSERT INTO users (id, name, active) VALUES (1, 'Sage', true) ON CONFLICT (id) DO UPDATE SET (name, active) = (SELECT EXCLUDED.name, EXCLUDED.active)", + "INSERT INTO users (id, name) VALUES (1, 'Sage') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name WHERE users.name IS DISTINCT FROM EXCLUDED.name", + ]); +} + +#[test] +fn insert_returning_variations() { + run_cases(&[ + "INSERT INTO users DEFAULT VALUES RETURNING *", + "INSERT INTO users (id) VALUES (1) RETURNING id", + "INSERT INTO users (id) VALUES (1) RETURNING id AS inserted_id, email new_email", + ]); +} + +// [ 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 [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] +// { * | 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 ] diff --git a/tests/test_refresh_materialized_view.rs b/tests/test_refresh_materialized_view.rs new file mode 100644 index 0000000..5244a8c --- /dev/null +++ b/tests/test_refresh_materialized_view.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn refresh_materialized_view_parses() { + run_cases(&["REFRESH MATERIALIZED VIEW my_matview"]); +} diff --git a/tests/test_reindex.rs b/tests/test_reindex.rs new file mode 100644 index 0000000..1d83ae1 --- /dev/null +++ b/tests/test_reindex.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn reindex_parses() { + run_cases(&["REINDEX INDEX my_index"]); +} diff --git a/tests/test_security_label.rs b/tests/test_security_label.rs new file mode 100644 index 0000000..64ab761 --- /dev/null +++ b/tests/test_security_label.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn security_label_parses() { + run_cases(&["SECURITY LABEL ON TABLE my_table IS 'classified'"]); +} diff --git a/tests/test_select_grammar.rs b/tests/test_select_grammar.rs new file mode 100644 index 0000000..2652f6c --- /dev/null +++ b/tests/test_select_grammar.rs @@ -0,0 +1,229 @@ +mod common; + +use common::run_parse_walk_cases as run_cases; + +#[test] +fn select_clause_variations() { + run_cases(&[ + "SELECT", + "SELECT ALL", + "SELECT ALL 1", + "SELECT DISTINCT id FROM users", + "SELECT DISTINCT ON (account_id, created_at) account_id, created_at FROM events", + "SELECT *", + "SELECT id AS user_id, name display_name, 1 + 2", + "SELECT FROM users", + "SELECT id FROM users WHERE active AND age >= 18", + "SELECT department, count(*) FROM employees GROUP BY department HAVING count(*) > 1", + "SELECT sum(salary) OVER w FROM employees WINDOW w AS (PARTITION BY department ORDER BY hired_at)", + "SELECT id FROM users ORDER BY created_at ASC NULLS LAST, id DESC NULLS FIRST", + "SELECT id FROM users ORDER BY name USING < NULLS FIRST", + "SELECT id FROM users LIMIT 10", + "SELECT id FROM users LIMIT ALL", + "SELECT id FROM users OFFSET 5", + "SELECT id FROM users OFFSET 5 ROW", + "SELECT id FROM users OFFSET 5 ROWS", + "SELECT id FROM users FETCH FIRST ROW ONLY", + "SELECT id FROM users FETCH FIRST 10 ROWS ONLY", + "SELECT id FROM users FETCH NEXT 10 ROW ONLY", + "SELECT id FROM users ORDER BY id FETCH NEXT 10 ROWS WITH TIES", + "SELECT id FROM users ORDER BY id FETCH NEXT ROW WITH TIES", + "SELECT id FROM users WHERE active GROUP BY id HAVING count(*) > 0 WINDOW w AS (ORDER BY id) ORDER BY id LIMIT 5 OFFSET 1 ROWS", + ]); +} + +#[test] +fn with_clause_variations() { + run_cases(&[ + "WITH w AS (SELECT 1 AS id) SELECT * FROM w", + "WITH w(id, name) AS (SELECT 1, 'a') SELECT id, name FROM w", + "WITH w AS MATERIALIZED (SELECT 1 AS id) SELECT * FROM w", + "WITH w AS NOT MATERIALIZED (SELECT 1 AS id) SELECT * FROM w", + "WITH w AS (VALUES (1), (2)) SELECT * FROM w", + "WITH w AS (INSERT INTO users (id) VALUES (1) RETURNING id) SELECT * FROM w", + "WITH w AS (UPDATE users SET active = true RETURNING id) SELECT * FROM w", + "WITH w AS (DELETE FROM users WHERE active = false RETURNING id) SELECT * FROM w", + "WITH w AS (MERGE INTO users u USING incoming i ON u.id = i.id WHEN MATCHED THEN UPDATE SET active = true RETURNING u.id) SELECT * FROM w", + "WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 3) SELECT * FROM t", + "WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 3) SEARCH BREADTH FIRST BY n SET ordercol SELECT * FROM t", + "WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 3) SEARCH DEPTH FIRST BY n SET ordercol SELECT * FROM t", + "WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 3) CYCLE n SET is_cycle USING path SELECT * FROM t", + "WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 3) CYCLE n SET is_cycle TO true DEFAULT false USING path SELECT * FROM t", + "WITH RECURSIVE t(n, m) AS (SELECT 1, 2 UNION ALL SELECT n + 1, m + 1 FROM t WHERE n < 3) SEARCH BREADTH FIRST BY n, m SET ordercol SELECT * FROM t", + "WITH RECURSIVE t(n, m) AS (SELECT 1, 2 UNION ALL SELECT n + 1, m + 1 FROM t WHERE n < 3) CYCLE n, m SET is_cycle USING path SELECT * FROM t", + "WITH one AS (SELECT 1), two AS (SELECT 2) SELECT * FROM one, two", + ]); +} + +#[test] +fn from_item_variations() { + run_cases(&[ + "SELECT * FROM users", + "SELECT * FROM ONLY users", + "SELECT * FROM users *", + "SELECT * FROM users AS u", + "SELECT * FROM users u", + "SELECT * FROM users AS u (id, name)", + "SELECT * FROM users TABLESAMPLE bernoulli (10)", + "SELECT * FROM users AS u TABLESAMPLE system (25) REPEATABLE (42)", + "SELECT * FROM (SELECT 1 AS id) s", + "SELECT * FROM LATERAL (SELECT 1 AS id) AS s(id)", + "SELECT * FROM LATERAL (SELECT 1 AS id) s", + "WITH w AS (SELECT 1 AS id) SELECT * FROM w AS cte(id)", + "SELECT * FROM foo()", + "SELECT * FROM generate_series(1, 3)", + "SELECT * FROM generate_series(1, 3) WITH ORDINALITY", + "SELECT * FROM generate_series(1, 3) g(value)", + "SELECT * FROM LATERAL generate_series(1, 3) WITH ORDINALITY AS g(value, ordinality)", + "SELECT * FROM json_to_record('{\"a\":1}') AS x(a int)", + "SELECT * FROM json_to_record('{\"a\":1}') x(a int)", + "SELECT * FROM LATERAL json_to_record('{\"a\":1}') AS (a int)", + "SELECT * FROM ROWS FROM (generate_series(1, 3), generate_series(4, 6))", + "SELECT * FROM LATERAL ROWS FROM (generate_series(1, 3)) AS r(n)", + "SELECT * FROM ROWS FROM (json_to_record('{\"a\":1}') AS (a int), generate_series(1, 3)) WITH ORDINALITY AS r(a, b, ordinality)", + "SELECT * FROM users JOIN orders ON users.id = orders.user_id", + "SELECT * FROM users INNER JOIN orders ON users.id = orders.user_id", + "SELECT * FROM users LEFT JOIN orders ON users.id = orders.user_id", + "SELECT * FROM users LEFT OUTER JOIN orders ON users.id = orders.user_id", + "SELECT * FROM users RIGHT JOIN orders USING (user_id)", + "SELECT * FROM users RIGHT OUTER JOIN orders USING (user_id)", + "SELECT * FROM users FULL OUTER JOIN orders USING (user_id)", + "SELECT * FROM users FULL JOIN orders USING (user_id) AS joined_cols", + "SELECT * FROM users JOIN orders USING (user_id, tenant_id)", + "SELECT * FROM users NATURAL INNER JOIN orders", + "SELECT * FROM users NATURAL LEFT JOIN orders", + "SELECT * FROM users NATURAL FULL OUTER JOIN orders", + "SELECT * FROM users CROSS JOIN orders", + "SELECT * FROM users, orders, LATERAL generate_series(1, users.id) AS g(n)", + ]); +} + +#[test] +fn grouping_element_variations() { + run_cases(&[ + "SELECT count(*) FROM users GROUP BY ()", + "SELECT department, count(*) FROM employees GROUP BY department", + "SELECT department, role, count(*) FROM employees GROUP BY (department, role)", + "SELECT department, role, count(*) FROM employees GROUP BY ALL department, role", + "SELECT department, role, count(*) FROM employees GROUP BY DISTINCT department, role", + "SELECT department, role, count(*) FROM employees GROUP BY ROLLUP (department, (role, location))", + "SELECT department, role, count(*) FROM employees GROUP BY CUBE (department, (role, location))", + "SELECT department, role, count(*) FROM employees GROUP BY GROUPING SETS ((), department, (department, role), ROLLUP (location, role), CUBE (department, location))", + ]); +} + +#[test] +fn set_operation_variations() { + run_cases(&[ + "SELECT 1 UNION SELECT 2", + "SELECT 1 UNION ALL SELECT 2", + "SELECT 1 UNION DISTINCT SELECT 2", + "SELECT 1 INTERSECT SELECT 1", + "SELECT 1 INTERSECT ALL SELECT 1", + "SELECT 1 INTERSECT DISTINCT SELECT 1", + "SELECT 1 EXCEPT SELECT 2", + "SELECT 1 EXCEPT ALL SELECT 2", + "SELECT 1 EXCEPT DISTINCT SELECT 2", + "(SELECT 1 UNION SELECT 2) EXCEPT SELECT 3 ORDER BY 1 LIMIT 1", + ]); +} + +#[test] +fn locking_clause_variations() { + run_cases(&[ + "SELECT * FROM users FOR UPDATE", + "SELECT * FROM users FOR NO KEY UPDATE", + "SELECT * FROM users FOR SHARE", + "SELECT * FROM users FOR KEY SHARE", + "SELECT * FROM users FOR UPDATE OF users", + "SELECT * FROM users u JOIN orders o ON u.id = o.user_id FOR UPDATE OF u, o", + "SELECT * FROM users FOR UPDATE NOWAIT", + "SELECT * FROM users FOR UPDATE SKIP LOCKED", + "SELECT * FROM users FOR UPDATE NOWAIT FOR SHARE SKIP LOCKED", + ]); +} + +#[test] +fn table_statement_variations() { + run_cases(&["TABLE users", "TABLE ONLY users", "TABLE users *"]); +} + +#[test] +fn parameter_variations() { + run_cases(&[ + "SELECT $1", + "SELECT $1::int AS id, coalesce($2, 'fallback') name", + "SELECT DISTINCT ON ($1) $1, id FROM users", + "SELECT * FROM users WHERE id = $1 AND active = $2", + "SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > $1)", + "SELECT department, count(*) FROM employees GROUP BY department HAVING count(*) > $1", + "SELECT count(*) FROM employees GROUP BY ROLLUP (department, $1)", + "SELECT sum(salary) OVER w FROM employees WINDOW w AS (PARTITION BY $1 ORDER BY hired_at)", + "SELECT * FROM users TABLESAMPLE bernoulli ($1) REPEATABLE ($2)", + "SELECT * FROM generate_series($1, $2)", + "SELECT * FROM ROWS FROM (generate_series($1, $2), generate_series($3, $4))", + "SELECT * FROM users JOIN orders ON users.id = orders.user_id AND orders.total > $1", + "WITH w AS (SELECT $1 AS id) SELECT * FROM w WHERE id = $2", + "WITH w AS (VALUES ($1), ($2)) SELECT * FROM w", + "WITH w AS (INSERT INTO users (id) VALUES ($1) RETURNING id) SELECT * FROM w", + "SELECT $1 UNION ALL SELECT $2", + "SELECT $1 INTERSECT SELECT $2", + "SELECT $1 EXCEPT SELECT $2", + "SELECT id FROM users ORDER BY coalesce($1, id) ASC NULLS LAST", + "SELECT id FROM users LIMIT $1", + "SELECT id FROM users OFFSET $1 ROWS", + "SELECT id FROM users FETCH FIRST $1 ROWS ONLY", + "SELECT id FROM users ORDER BY id FETCH NEXT $1 ROWS WITH TIES", + ]); +} + +// SELECT grammar: +// +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] +// [ { * | expression [ [ AS ] output_name ] } [, ...] ] +// [ FROM from_item [, ...] ] +// [ WHERE condition ] +// [ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ] +// [ HAVING condition ] +// [ WINDOW window_name AS ( window_definition ) [, ...] ] +// [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] +// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] +// [ LIMIT { count | ALL } ] +// [ OFFSET start [ ROW | ROWS ] ] +// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ] +// [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF from_reference [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ] + +// where from_item can be one of: + +// [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] +// [ LATERAL ] ( select ) [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// 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 + +// and grouping_element can be one of: + +// ( ) +// expression +// ( expression [, ...] ) +// ROLLUP ( { expression | ( expression [, ...] ) } [, ...] ) +// CUBE ( { expression | ( expression [, ...] ) } [, ...] ) +// GROUPING SETS ( grouping_element [, ...] ) + +// and with_query is: + +// 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 ] + +// TABLE [ ONLY ] table_name [ * ] +// diff --git a/tests/test_select_into.rs b/tests/test_select_into.rs new file mode 100644 index 0000000..75fac8b --- /dev/null +++ b/tests/test_select_into.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn select_into_parses() { + run_cases(&["SELECT 1 AS id INTO my_table"]); +} diff --git a/tests/test_truncate.rs b/tests/test_truncate.rs new file mode 100644 index 0000000..9ccd7c1 --- /dev/null +++ b/tests/test_truncate.rs @@ -0,0 +1,8 @@ +mod common; + +use common::run_parse_debug_cases as run_cases; + +#[test] +fn truncate_parses() { + run_cases(&["TRUNCATE TABLE my_table"]); +} diff --git a/tests/test_update_grammar.rs b/tests/test_update_grammar.rs new file mode 100644 index 0000000..ca4aa6d --- /dev/null +++ b/tests/test_update_grammar.rs @@ -0,0 +1,79 @@ +mod common; + +use common::run_parse_walk_cases as run_cases; + +#[test] +fn update_target_variations() { + run_cases(&[ + "UPDATE users SET name = 'Sage'", + "UPDATE ONLY users SET name = 'Sage'", + "UPDATE users * SET name = 'Sage'", + "UPDATE users AS u SET name = 'Sage'", + "UPDATE users u SET name = 'Sage'", + "UPDATE public.users AS u SET name = 'Sage'", + ]); +} + +#[test] +fn update_with_clause_variations() { + run_cases(&[ + "WITH incoming AS (SELECT 1 AS id, 'Sage' AS name) UPDATE users SET name = incoming.name FROM incoming WHERE users.id = incoming.id", + "WITH RECURSIVE incoming(id) AS (SELECT 1 UNION ALL SELECT id + 1 FROM incoming WHERE id < 3) UPDATE users SET active = true FROM incoming WHERE users.id = incoming.id", + "WITH incoming AS MATERIALIZED (SELECT 1 AS id) UPDATE users SET active = true FROM incoming WHERE users.id = incoming.id", + "WITH incoming AS NOT MATERIALIZED (SELECT 1 AS id) UPDATE users SET active = true FROM incoming WHERE users.id = incoming.id", + ]); +} + +#[test] +fn update_set_variations() { + run_cases(&[ + "UPDATE users SET name = 'Sage'", + "UPDATE users SET name = DEFAULT", + "UPDATE users SET name = $1, active = $2", + "UPDATE users SET (name, active) = ROW ('Sage', true)", + "UPDATE users SET (name, active) = ('Sage', DEFAULT)", + "UPDATE users SET (name, active) = (SELECT name, active FROM incoming WHERE incoming.id = users.id)", + "UPDATE users SET name = upper(name), updated_at = now()", + ]); +} + +#[test] +fn update_from_variations() { + run_cases(&[ + "UPDATE users SET active = false FROM orders WHERE users.id = orders.user_id", + "UPDATE users SET active = false FROM orders o, sessions s WHERE users.id = o.user_id AND users.id = s.user_id", + "UPDATE users SET active = false FROM LATERAL (SELECT 1 AS id) s WHERE users.id = s.id", + "UPDATE users SET active = false FROM generate_series(1, 3) AS g(id) WHERE users.id = g.id", + "UPDATE users SET active = false FROM orders JOIN invoices ON orders.id = invoices.order_id WHERE users.id = orders.user_id", + ]); +} + +#[test] +fn update_where_variations() { + run_cases(&[ + "UPDATE users SET active = false WHERE id = 1", + "UPDATE users SET active = $1 WHERE id = $2", + "UPDATE users SET active = false WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id)", + "UPDATE users SET active = false WHERE CURRENT OF user_cursor", + ]); +} + +#[test] +fn update_returning_variations() { + run_cases(&[ + "UPDATE users SET active = false RETURNING *", + "UPDATE users SET active = false RETURNING id", + "UPDATE users SET active = false RETURNING id AS updated_id, email new_email", + ]); +} + +// [ 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 [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] +// { * | output_expression [ [ AS ] output_name ] } [, ...] ] From 36f72c02594ae3635358a55834a54163c2323e09 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 16 Jul 2026 17:01:04 -0700 Subject: [PATCH 2/5] obscure ddl --- build.rs | 7 + tests/test_alter_aggregate.rs | 22 +- tests/test_alter_collation.rs | 18 +- tests/test_alter_conversion.rs | 15 +- tests/test_alter_database.rs | 38 ++- tests/test_alter_default_privileges.rs | 87 ++++- tests/test_alter_domain.rs | 43 ++- tests/test_alter_event_trigger.rs | 19 +- tests/test_alter_extension.rs | 55 ++- tests/test_alter_foreign_data_wrapper.rs | 22 +- tests/test_alter_foreign_table.rs | 62 +++- tests/test_alter_function.rs | 44 ++- tests/test_alter_group.rs | 23 +- tests/test_alter_index.rs | 28 +- tests/test_alter_language.rs | 13 +- tests/test_alter_large_object.rs | 9 +- tests/test_alter_materialized_view.rs | 49 ++- tests/test_alter_operator.rs | 26 +- tests/test_alter_operator_class.rs | 20 +- tests/test_alter_operator_family.rs | 34 +- tests/test_alter_policy.rs | 17 +- tests/test_alter_procedure.rs | 36 +- tests/test_alter_publication.rs | 38 ++- tests/test_alter_role.rs | 45 ++- tests/test_alter_routine.rs | 40 ++- tests/test_alter_rule.rs | 9 +- tests/test_alter_schema.rs | 13 +- tests/test_alter_sequence.rs | 27 +- tests/test_alter_server.rs | 16 +- tests/test_alter_statistics.rs | 17 +- tests/test_alter_subscription.rs | 31 +- tests/test_alter_system.rs | 17 +- tests/test_alter_table.rs | 192 ++++++++++- tests/test_alter_tablespace.rs | 17 +- tests/test_alter_text_search_configuration.rs | 96 +++++- tests/test_alter_text_search_dictionary.rs | 19 +- tests/test_alter_text_search_parser.rs | 13 +- tests/test_alter_text_search_template.rs | 13 +- tests/test_alter_trigger.rs | 14 +- tests/test_alter_type.rs | 34 +- tests/test_alter_user.rs | 43 ++- tests/test_alter_user_mapping.rs | 13 +- tests/test_alter_view.rs | 24 +- tests/test_comment.rs | 68 +++- tests/test_create_access_method.rs | 14 +- tests/test_create_aggregate.rs | 73 +++- tests/test_create_cast.rs | 23 +- tests/test_create_collation.rs | 21 +- tests/test_create_conversion.rs | 11 +- tests/test_create_database.rs | 30 +- tests/test_create_domain.rs | 20 +- tests/test_create_event_trigger.rs | 13 +- tests/test_create_extension.rs | 15 +- tests/test_create_foreign_data_wrapper.rs | 15 +- tests/test_create_foreign_table.rs | 59 +++- tests/test_create_function.rs | 22 +- tests/test_create_group.rs | 31 +- tests/test_create_index.rs | 18 +- tests/test_create_language.rs | 14 +- tests/test_create_materialized_view.rs | 18 +- tests/test_create_operator.rs | 18 +- tests/test_create_operator_class.rs | 15 +- tests/test_create_operator_family.rs | 9 +- tests/test_create_policy.rs | 17 +- tests/test_create_procedure.rs | 21 +- tests/test_create_publication.rs | 25 +- tests/test_create_role.rs | 29 +- tests/test_create_rule.rs | 18 +- tests/test_create_schema.rs | 24 +- tests/test_create_sequence.rs | 19 +- tests/test_create_server.rs | 14 +- tests/test_create_statistics.rs | 19 +- tests/test_create_subscription.rs | 13 +- tests/test_create_table_as.rs | 19 +- tests/test_create_tablespace.rs | 15 +- .../test_create_text_search_configuration.rs | 15 +- tests/test_create_text_search_dictionary.rs | 14 +- tests/test_create_text_search_parser.rs | 15 +- tests/test_create_text_search_template.rs | 15 +- tests/test_create_transform.rs | 13 +- tests/test_create_trigger.rs | 26 +- tests/test_create_type.rs | 52 ++- tests/test_create_user.rs | 31 +- tests/test_create_user_mapping.rs | 15 +- tests/test_create_view.rs | 17 +- tests/test_delete_grammar.rs | 8 + tests/test_drop.rs | 320 +++++++++++++++++- tests/test_drop_access_method.rs | 12 +- tests/test_drop_aggregate.rs | 18 +- tests/test_drop_cast.rs | 12 +- tests/test_drop_collation.rs | 13 +- tests/test_drop_conversion.rs | 13 +- tests/test_drop_database.rs | 16 +- tests/test_drop_domain.rs | 13 +- tests/test_drop_event_trigger.rs | 12 +- tests/test_drop_extension.rs | 13 +- tests/test_drop_foreign_data_wrapper.rs | 13 +- tests/test_drop_foreign_table.rs | 13 +- tests/test_drop_function.rs | 13 +- tests/test_drop_group.rs | 12 +- tests/test_drop_index.rs | 13 +- tests/test_drop_language.rs | 13 +- tests/test_drop_materialized_view.rs | 13 +- tests/test_drop_operator.rs | 12 +- tests/test_drop_operator_class.rs | 13 +- tests/test_drop_operator_family.rs | 13 +- tests/test_drop_owned.rs | 12 +- tests/test_drop_policy.rs | 12 +- tests/test_drop_procedure.rs | 13 +- tests/test_drop_publication.rs | 13 +- tests/test_drop_role.rs | 12 +- tests/test_drop_routine.rs | 13 +- tests/test_drop_rule.rs | 13 +- tests/test_drop_schema.rs | 13 +- tests/test_drop_sequence.rs | 13 +- tests/test_drop_server.rs | 13 +- tests/test_drop_statistics.rs | 13 +- tests/test_drop_subscription.rs | 13 +- tests/test_drop_table.rs | 13 +- tests/test_drop_tablespace.rs | 12 +- tests/test_drop_text_search_configuration.rs | 13 +- tests/test_drop_text_search_dictionary.rs | 13 +- tests/test_drop_text_search_parser.rs | 13 +- tests/test_drop_text_search_template.rs | 13 +- tests/test_drop_transform.rs | 12 +- tests/test_drop_trigger.rs | 12 +- tests/test_drop_type.rs | 13 +- tests/test_drop_user.rs | 12 +- tests/test_drop_user_mapping.rs | 13 +- tests/test_drop_view.rs | 13 +- tests/test_import_foreign_schema.rs | 15 +- tests/test_insert_grammar.rs | 8 + tests/test_refresh_materialized_view.rs | 14 +- tests/test_reindex.rs | 23 +- tests/test_security_label.rs | 42 ++- tests/test_select_grammar.rs | 10 +- tests/test_select_into.rs | 27 +- tests/test_truncate.rs | 14 +- tests/test_update_grammar.rs | 8 + 139 files changed, 3267 insertions(+), 148 deletions(-) diff --git a/build.rs b/build.rs index 3422879..bda787d 100644 --- a/build.rs +++ b/build.rs @@ -1316,6 +1316,13 @@ fn build_node_struct(s: &syn::ItemStruct, type_comment_regex: &Regex) -> NodeStr // and ColumnRef for MINVALUE/MAXVALUE, not only PartitionRangeDatum. (("PartitionBoundSpec", "lowerdatums"), NodeFieldType::List), (("PartitionBoundSpec", "upperdatums"), NodeFieldType::List), + // The raw parser stores text-search token types as Integer nodes, not + // String nodes, and dicts is a nested list of qualified names. + ( + ("AlterTSConfigurationStmt", "tokentype"), + NodeFieldType::List, + ), + (("AlterTSConfigurationStmt", "dicts"), NodeFieldType::List), ]; let attrs = clean_doc_comments(&s.attrs); diff --git a/tests/test_alter_aggregate.rs b/tests/test_alter_aggregate.rs index f37f9ce..199dcbc 100644 --- a/tests/test_alter_aggregate.rs +++ b/tests/test_alter_aggregate.rs @@ -2,7 +2,27 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER AGGREGATE +// Description: change the definition of an aggregate function +// Syntax: +// 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 [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-alteraggregate.html + #[test] fn alter_aggregate_parses() { - run_cases(&["ALTER AGGREGATE my_sum(integer) RENAME TO my_sum2"]); + run_cases(&[ + r#"ALTER AGGREGATE my_sum(integer) RENAME TO my_sum_int"#, + r#"ALTER AGGREGATE my_sum(integer) OWNER TO CURRENT_USER"#, + r#"ALTER AGGREGATE my_sum(integer) SET SCHEMA analytics"#, + ]); } diff --git a/tests/test_alter_collation.rs b/tests/test_alter_collation.rs index 6e3a20d..d088689 100644 --- a/tests/test_alter_collation.rs +++ b/tests/test_alter_collation.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER COLLATION +// Description: change the definition of a collation +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altercollation.html + #[test] fn alter_collation_parses() { - run_cases(&["ALTER COLLATION my_collation RENAME TO my_collation2"]); + run_cases(&[ + r#"ALTER COLLATION my_collation REFRESH VERSION"#, + r#"ALTER COLLATION my_collation RENAME TO my_new_collation"#, + r#"ALTER COLLATION my_collation OWNER TO CURRENT_USER"#, + r#"ALTER COLLATION my_collation SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_conversion.rs b/tests/test_alter_conversion.rs index 353ce93..9852547 100644 --- a/tests/test_alter_conversion.rs +++ b/tests/test_alter_conversion.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER CONVERSION +// Description: change the definition of a conversion +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterconversion.html + #[test] fn alter_conversion_parses() { - run_cases(&["ALTER CONVERSION my_conversion RENAME TO my_conversion2"]); + run_cases(&[ + r#"ALTER CONVERSION my_conversion RENAME TO my_new_conversion"#, + r#"ALTER CONVERSION my_conversion OWNER TO CURRENT_USER"#, + r#"ALTER CONVERSION my_conversion SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_database.rs b/tests/test_alter_database.rs index d3b8c16..e5894ab 100644 --- a/tests/test_alter_database.rs +++ b/tests/test_alter_database.rs @@ -2,7 +2,43 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER DATABASE +// Description: change a database +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterdatabase.html + #[test] fn alter_database_parses() { - run_cases(&["ALTER DATABASE mydb SET work_mem TO '64MB'"]); + run_cases(&[ + r#"ALTER DATABASE mydb WITH ALLOW_CONNECTIONS false"#, + r#"ALTER DATABASE mydb RENAME TO mydb2"#, + r#"ALTER DATABASE mydb OWNER TO CURRENT_USER"#, + r#"ALTER DATABASE mydb SET TABLESPACE fastspace"#, + r#"ALTER DATABASE mydb SET search_path TO public, extensions"#, + r#"ALTER DATABASE mydb SET work_mem = '64MB'"#, + r#"ALTER DATABASE mydb SET enable_seqscan FROM CURRENT"#, + r#"ALTER DATABASE mydb RESET work_mem"#, + r#"ALTER DATABASE mydb RESET ALL"#, + ]); } diff --git a/tests/test_alter_default_privileges.rs b/tests/test_alter_default_privileges.rs index 962f781..2a768d1 100644 --- a/tests/test_alter_default_privileges.rs +++ b/tests/test_alter_default_privileges.rs @@ -2,7 +2,92 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER DEFAULT PRIVILEGES +// Description: define default access privileges +// Syntax: +// 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 ] +// +// GRANT { { SELECT | UPDATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON LARGE OBJECTS +// 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 ] +// +// REVOKE [ GRANT OPTION FOR ] +// { { SELECT | UPDATE } +// [, ...] | ALL [ PRIVILEGES ] } +// ON LARGE OBJECTS +// FROM { [ GROUP ] role_name | PUBLIC } [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-alterdefaultprivileges.html + #[test] fn alter_default_privileges_parses() { - run_cases(&["ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO public"]); + run_cases(&[ + r#"ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO app_user"#, + r#"ALTER DEFAULT PRIVILEGES FOR ROLE owner_role IN SCHEMA public GRANT USAGE ON TYPES TO app_user WITH GRANT OPTION"#, + r#"ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE GRANT OPTION FOR SELECT ON TABLES FROM app_user CASCADE"#, + r#"ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON ROUTINES FROM PUBLIC RESTRICT"#, + ]); } diff --git a/tests/test_alter_domain.rs b/tests/test_alter_domain.rs index 834b23b..cf176b4 100644 --- a/tests/test_alter_domain.rs +++ b/tests/test_alter_domain.rs @@ -2,7 +2,48 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER DOMAIN +// Description: change the definition of a domain +// Syntax: +// 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) } +// +// URL: https://www.postgresql.org/docs/18/sql-alterdomain.html + #[test] fn alter_domain_parses() { - run_cases(&["ALTER DOMAIN my_domain SET NOT NULL"]); + run_cases(&[ + r#"ALTER DOMAIN email_domain SET DEFAULT 'unknown@example.com'"#, + r#"ALTER DOMAIN email_domain DROP DEFAULT"#, + r#"ALTER DOMAIN email_domain SET NOT NULL"#, + r#"ALTER DOMAIN email_domain DROP NOT NULL"#, + r#"ALTER DOMAIN email_domain ADD CONSTRAINT email_check CHECK (VALUE LIKE '%@%') NOT VALID"#, + r#"ALTER DOMAIN email_domain DROP CONSTRAINT IF EXISTS email_check CASCADE"#, + r#"ALTER DOMAIN email_domain RENAME CONSTRAINT email_check TO email_check_new"#, + r#"ALTER DOMAIN email_domain VALIDATE CONSTRAINT email_check"#, + r#"ALTER DOMAIN email_domain OWNER TO CURRENT_USER"#, + r#"ALTER DOMAIN email_domain RENAME TO email_domain_new"#, + r#"ALTER DOMAIN email_domain SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_event_trigger.rs b/tests/test_alter_event_trigger.rs index bd0e9c3..1fc0d17 100644 --- a/tests/test_alter_event_trigger.rs +++ b/tests/test_alter_event_trigger.rs @@ -2,7 +2,24 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER EVENT TRIGGER +// Description: change the definition of an event trigger +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altereventtrigger.html + #[test] fn alter_event_trigger_parses() { - run_cases(&["ALTER EVENT TRIGGER my_event_trigger RENAME TO my_event_trigger2"]); + run_cases(&[ + r#"ALTER EVENT TRIGGER trg DISABLE"#, + r#"ALTER EVENT TRIGGER trg ENABLE"#, + r#"ALTER EVENT TRIGGER trg ENABLE REPLICA"#, + r#"ALTER EVENT TRIGGER trg ENABLE ALWAYS"#, + r#"ALTER EVENT TRIGGER trg OWNER TO CURRENT_USER"#, + r#"ALTER EVENT TRIGGER trg RENAME TO trg_new"#, + ]); } diff --git a/tests/test_alter_extension.rs b/tests/test_alter_extension.rs index 0e016d9..b270808 100644 --- a/tests/test_alter_extension.rs +++ b/tests/test_alter_extension.rs @@ -2,7 +2,60 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER EXTENSION +// Description: change the definition of an extension +// Syntax: +// 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 [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-alterextension.html + #[test] fn alter_extension_parses() { - run_cases(&["ALTER EXTENSION hstore UPDATE"]); + run_cases(&[ + r#"ALTER EXTENSION hstore UPDATE"#, + r#"ALTER EXTENSION hstore UPDATE TO '1.8'"#, + r#"ALTER EXTENSION hstore SET SCHEMA public"#, + r#"ALTER EXTENSION hstore ADD TABLE my_table"#, + r#"ALTER EXTENSION hstore DROP FUNCTION my_function(integer)"#, + ]); } diff --git a/tests/test_alter_foreign_data_wrapper.rs b/tests/test_alter_foreign_data_wrapper.rs index 2cdcafa..95664d0 100644 --- a/tests/test_alter_foreign_data_wrapper.rs +++ b/tests/test_alter_foreign_data_wrapper.rs @@ -2,7 +2,27 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER FOREIGN DATA WRAPPER +// Description: change the definition of a foreign-data wrapper +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterforeigndatawrapper.html + #[test] fn alter_foreign_data_wrapper_parses() { - run_cases(&["ALTER FOREIGN DATA WRAPPER my_fdw RENAME TO my_fdw2"]); + run_cases(&[ + r#"ALTER FOREIGN DATA WRAPPER my_fdw HANDLER my_handler"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw NO HANDLER"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw VALIDATOR my_validator"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw NO VALIDATOR"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw OPTIONS (ADD host 'localhost', SET port '5432', DROP oldopt)"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw OWNER TO CURRENT_USER"#, + r#"ALTER FOREIGN DATA WRAPPER my_fdw RENAME TO my_fdw_new"#, + ]); } diff --git a/tests/test_alter_foreign_table.rs b/tests/test_alter_foreign_table.rs index 62c6bfb..9aee7d7 100644 --- a/tests/test_alter_foreign_table.rs +++ b/tests/test_alter_foreign_table.rs @@ -2,7 +2,67 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER FOREIGN TABLE +// Description: change the definition of a foreign table +// Syntax: +// 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 ] [ 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 ] +// 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'] [, ... ]) +// +// URL: https://www.postgresql.org/docs/18/sql-alterforeigntable.html + #[test] fn alter_foreign_table_parses() { - run_cases(&["ALTER FOREIGN TABLE my_foreign_table RENAME TO my_foreign_table2"]); + run_cases(&[ + r#"ALTER FOREIGN TABLE IF EXISTS ONLY ft ADD COLUMN IF NOT EXISTS payload text OPTIONS (column_name 'payload')"#, + r#"ALTER FOREIGN TABLE ft DROP COLUMN IF EXISTS old_col CASCADE"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload TYPE varchar(200)"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload SET DEFAULT 'x'"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload DROP DEFAULT"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload SET NOT NULL"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload DROP NOT NULL"#, + r#"ALTER FOREIGN TABLE ft ALTER COLUMN payload SET STATISTICS 100"#, + r#"ALTER FOREIGN TABLE ft ADD CHECK (payload <> '') NOT VALID"#, + r#"ALTER FOREIGN TABLE ft VALIDATE CONSTRAINT payload_check"#, + r#"ALTER FOREIGN TABLE ft DROP CONSTRAINT IF EXISTS payload_check RESTRICT"#, + r#"ALTER FOREIGN TABLE ft DISABLE TRIGGER ALL"#, + r#"ALTER FOREIGN TABLE ft ENABLE ALWAYS TRIGGER trg"#, + r#"ALTER FOREIGN TABLE ft SET WITHOUT OIDS"#, + r#"ALTER FOREIGN TABLE ft OWNER TO CURRENT_USER"#, + r#"ALTER FOREIGN TABLE ft OPTIONS (ADD schema_name 'public', SET table_name 'remote_table')"#, + r#"ALTER FOREIGN TABLE ft RENAME COLUMN payload TO body"#, + r#"ALTER FOREIGN TABLE ft RENAME TO ft_new"#, + r#"ALTER FOREIGN TABLE ft SET SCHEMA archive"#, + ]); } diff --git a/tests/test_alter_function.rs b/tests/test_alter_function.rs index cd9c4cc..d36895a 100644 --- a/tests/test_alter_function.rs +++ b/tests/test_alter_function.rs @@ -2,7 +2,49 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER FUNCTION +// Description: change the definition of a function +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterfunction.html + #[test] fn alter_function_parses() { - run_cases(&["ALTER FUNCTION my_function(integer) RENAME TO my_function2"]); + run_cases(&[ + r#"ALTER FUNCTION my_function(integer) CALLED ON NULL INPUT"#, + r#"ALTER FUNCTION my_function(integer) RETURNS NULL ON NULL INPUT"#, + r#"ALTER FUNCTION my_function(integer) STRICT"#, + r#"ALTER FUNCTION my_function(integer) IMMUTABLE PARALLEL SAFE COST 5 ROWS 10 SET search_path TO public"#, + r#"ALTER FUNCTION my_function(integer) RESET ALL"#, + r#"ALTER FUNCTION my_function(integer) OWNER TO CURRENT_USER"#, + r#"ALTER FUNCTION my_function(integer) RENAME TO my_function_new"#, + r#"ALTER FUNCTION my_function(integer) SET SCHEMA public"#, + r#"ALTER FUNCTION my_function(integer) DEPENDS ON EXTENSION hstore"#, + r#"ALTER FUNCTION my_function(integer) NO DEPENDS ON EXTENSION hstore"#, + ]); } diff --git a/tests/test_alter_group.rs b/tests/test_alter_group.rs index 120c6b5..9ad3efc 100644 --- a/tests/test_alter_group.rs +++ b/tests/test_alter_group.rs @@ -2,7 +2,28 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER GROUP +// Description: change role name or membership +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altergroup.html + #[test] fn alter_group_parses() { - run_cases(&["ALTER GROUP my_group ADD USER my_user"]); + run_cases(&[ + r#"ALTER GROUP old_group RENAME TO new_group"#, + r#"ALTER GROUP my_group ADD USER alice, bob"#, + r#"ALTER GROUP my_group DROP USER alice, bob"#, + ]); } diff --git a/tests/test_alter_index.rs b/tests/test_alter_index.rs index ec63b69..a6d6886 100644 --- a/tests/test_alter_index.rs +++ b/tests/test_alter_index.rs @@ -2,7 +2,33 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER INDEX +// Description: change the definition of an index +// Syntax: +// ALTER INDEX [ IF EXISTS ] name RENAME TO new_name +// ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name +// ALTER INDEX name ATTACH PARTITION index_name +// ALTER INDEX name [ NO ] DEPENDS ON EXTENSION extension_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 +// ALTER INDEX ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] +// SET TABLESPACE new_tablespace [ NOWAIT ] +// +// URL: https://www.postgresql.org/docs/18/sql-alterindex.html + #[test] fn alter_index_parses() { - run_cases(&["ALTER INDEX my_index RENAME TO my_index2"]); + run_cases(&[ + r#"ALTER INDEX IF EXISTS my_index RENAME TO my_index_new"#, + r#"ALTER INDEX ALL IN TABLESPACE oldspace OWNED BY app_user SET TABLESPACE newspace NOWAIT"#, + r#"ALTER INDEX my_index ATTACH PARTITION my_index_part"#, + r#"ALTER INDEX my_index DEPENDS ON EXTENSION hstore"#, + r#"ALTER INDEX my_index NO DEPENDS ON EXTENSION hstore"#, + r#"ALTER INDEX my_index SET TABLESPACE fastspace"#, + r#"ALTER INDEX my_index SET (fillfactor = 80, deduplicate_items = off)"#, + r#"ALTER INDEX my_index RESET (fillfactor)"#, + r#"ALTER INDEX my_index ALTER COLUMN 1 SET STATISTICS 100"#, + ]); } diff --git a/tests/test_alter_language.rs b/tests/test_alter_language.rs index 4b51e8b..7bc9115 100644 --- a/tests/test_alter_language.rs +++ b/tests/test_alter_language.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER LANGUAGE +// Description: change the definition of a procedural language +// Syntax: +// ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO new_name +// ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// +// URL: https://www.postgresql.org/docs/18/sql-alterlanguage.html + #[test] fn alter_language_parses() { - run_cases(&["ALTER LANGUAGE my_language RENAME TO my_language2"]); + run_cases(&[ + r#"ALTER LANGUAGE plsample RENAME TO plsample2"#, + r#"ALTER LANGUAGE plsample OWNER TO CURRENT_USER"#, + ]); } diff --git a/tests/test_alter_large_object.rs b/tests/test_alter_large_object.rs index 5defb12..1c5887a 100644 --- a/tests/test_alter_large_object.rs +++ b/tests/test_alter_large_object.rs @@ -2,7 +2,14 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER LARGE OBJECT +// Description: change the definition of a large object +// Syntax: +// ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// +// URL: https://www.postgresql.org/docs/18/sql-alterlargeobject.html + #[test] fn alter_large_object_parses() { - run_cases(&["ALTER LARGE OBJECT 123 OWNER TO current_user"]); + run_cases(&[r#"ALTER LARGE OBJECT 12345 OWNER TO CURRENT_USER"#]); } diff --git a/tests/test_alter_materialized_view.rs b/tests/test_alter_materialized_view.rs index 78420c9..03598a8 100644 --- a/tests/test_alter_materialized_view.rs +++ b/tests/test_alter_materialized_view.rs @@ -2,7 +2,54 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER MATERIALIZED VIEW +// Description: change the definition of a materialized view +// Syntax: +// 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 } +// +// URL: https://www.postgresql.org/docs/18/sql-altermaterializedview.html + #[test] fn alter_materialized_view_parses() { - run_cases(&["ALTER MATERIALIZED VIEW my_matview RENAME TO my_matview2"]); + run_cases(&[ + r#"ALTER MATERIALIZED VIEW IF EXISTS mv RENAME TO mv_new"#, + r#"ALTER MATERIALIZED VIEW mv ALTER COLUMN col SET STATISTICS 100"#, + r#"ALTER MATERIALIZED VIEW mv ALTER COLUMN col SET (n_distinct = 10)"#, + r#"ALTER MATERIALIZED VIEW mv ALTER COLUMN col RESET (n_distinct)"#, + r#"ALTER MATERIALIZED VIEW mv CLUSTER ON mv_idx"#, + r#"ALTER MATERIALIZED VIEW mv SET WITHOUT CLUSTER"#, + r#"ALTER MATERIALIZED VIEW mv SET ACCESS METHOD heap"#, + r#"ALTER MATERIALIZED VIEW mv SET TABLESPACE fastspace"#, + r#"ALTER MATERIALIZED VIEW mv SET (fillfactor = 80)"#, + r#"ALTER MATERIALIZED VIEW mv RESET (fillfactor)"#, + r#"ALTER MATERIALIZED VIEW mv OWNER TO CURRENT_USER"#, + r#"ALTER MATERIALIZED VIEW mv SET SCHEMA public"#, + r#"ALTER MATERIALIZED VIEW ALL IN TABLESPACE oldspace OWNED BY app_user SET TABLESPACE newspace NOWAIT"#, + ]); } diff --git a/tests/test_alter_operator.rs b/tests/test_alter_operator.rs index d564547..8ef5633 100644 --- a/tests/test_alter_operator.rs +++ b/tests/test_alter_operator.rs @@ -2,7 +2,31 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER OPERATOR +// Description: change the definition of an operator +// Syntax: +// 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 +// } [, ... ] ) +// +// URL: https://www.postgresql.org/docs/18/sql-alteroperator.html + #[test] fn alter_operator_parses() { - run_cases(&["ALTER OPERATOR + (integer, integer) OWNER TO current_user"]); + run_cases(&[ + r#"ALTER OPERATOR +(integer, integer) OWNER TO CURRENT_USER"#, + r#"ALTER OPERATOR +(integer, integer) SET SCHEMA public"#, + r#"ALTER OPERATOR +(integer, integer) SET (RESTRICT = my_restrict, JOIN = my_join)"#, + ]); } diff --git a/tests/test_alter_operator_class.rs b/tests/test_alter_operator_class.rs index 5ecaba3..30d581a 100644 --- a/tests/test_alter_operator_class.rs +++ b/tests/test_alter_operator_class.rs @@ -2,7 +2,25 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER OPERATOR CLASS +// Description: change the definition of an operator class +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alteropclass.html + #[test] fn alter_operator_class_parses() { - run_cases(&["ALTER OPERATOR CLASS my_opclass USING btree RENAME TO my_opclass2"]); + run_cases(&[ + r#"ALTER OPERATOR CLASS my_opclass USING btree RENAME TO my_opclass_new"#, + r#"ALTER OPERATOR CLASS my_opclass USING btree OWNER TO CURRENT_USER"#, + r#"ALTER OPERATOR CLASS my_opclass USING btree SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_operator_family.rs b/tests/test_alter_operator_family.rs index 83edc58..8db219d 100644 --- a/tests/test_alter_operator_family.rs +++ b/tests/test_alter_operator_family.rs @@ -2,7 +2,39 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER OPERATOR FAMILY +// Description: change the definition of an operator family +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alteropfamily.html + #[test] fn alter_operator_family_parses() { - run_cases(&["ALTER OPERATOR FAMILY my_opfamily USING btree RENAME TO my_opfamily2"]); + run_cases(&[ + r#"ALTER OPERATOR FAMILY my_family USING btree ADD OPERATOR 1 =(integer, integer)"#, + r#"ALTER OPERATOR FAMILY my_family USING btree DROP OPERATOR 1 (integer, integer)"#, + r#"ALTER OPERATOR FAMILY my_family USING btree RENAME TO my_family_new"#, + r#"ALTER OPERATOR FAMILY my_family USING btree OWNER TO CURRENT_USER"#, + r#"ALTER OPERATOR FAMILY my_family USING btree SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_policy.rs b/tests/test_alter_policy.rs index 03bc3ec..e1d59a7 100644 --- a/tests/test_alter_policy.rs +++ b/tests/test_alter_policy.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER POLICY +// Description: change the definition of a row-level security policy +// Syntax: +// 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 ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-alterpolicy.html + #[test] fn alter_policy_parses() { - run_cases(&["ALTER POLICY my_policy ON my_table RENAME TO my_policy2"]); + run_cases(&[ + r#"ALTER POLICY pol ON my_table RENAME TO pol_new"#, + r#"ALTER POLICY pol ON my_table TO app_user USING (tenant_id = 1) WITH CHECK (tenant_id = 1)"#, + ]); } diff --git a/tests/test_alter_procedure.rs b/tests/test_alter_procedure.rs index 78f0bc5..5bc2061 100644 --- a/tests/test_alter_procedure.rs +++ b/tests/test_alter_procedure.rs @@ -2,7 +2,41 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER PROCEDURE +// Description: change the definition of a procedure +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterprocedure.html + #[test] fn alter_procedure_parses() { - run_cases(&["ALTER PROCEDURE my_procedure(integer) RENAME TO my_procedure2"]); + run_cases(&[ + r#"ALTER PROCEDURE my_proc(integer) SECURITY DEFINER"#, + r#"ALTER PROCEDURE my_proc(integer) SECURITY INVOKER"#, + r#"ALTER PROCEDURE my_proc(integer) SET search_path TO public"#, + r#"ALTER PROCEDURE my_proc(integer) RESET ALL"#, + r#"ALTER PROCEDURE my_proc(integer) OWNER TO CURRENT_USER"#, + r#"ALTER PROCEDURE my_proc(integer) RENAME TO my_proc_new"#, + r#"ALTER PROCEDURE my_proc(integer) SET SCHEMA public"#, + r#"ALTER PROCEDURE my_proc(integer) DEPENDS ON EXTENSION hstore"#, + r#"ALTER PROCEDURE my_proc(integer) NO DEPENDS ON EXTENSION hstore"#, + ]); } diff --git a/tests/test_alter_publication.rs b/tests/test_alter_publication.rs index 39c10ed..851cb09 100644 --- a/tests/test_alter_publication.rs +++ b/tests/test_alter_publication.rs @@ -2,7 +2,43 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER PUBLICATION +// Description: change the definition of a publication +// Syntax: +// ALTER PUBLICATION name ADD publication_object [, ...] +// ALTER PUBLICATION name SET publication_object [, ...] +// ALTER PUBLICATION name DROP publication_drop_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 table_and_columns [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +// +// and publication_drop_object is one of: +// +// TABLE [ ONLY ] table_name [ * ] [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +// +// and table_and_columns is: +// +// [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-alterpublication.html + #[test] fn alter_publication_parses() { - run_cases(&["ALTER PUBLICATION my_publication RENAME TO my_publication2"]); + run_cases(&[ + r#"ALTER PUBLICATION pub ADD TABLE users, orders"#, + r#"ALTER PUBLICATION pub SET TABLE users WHERE (id > 0)"#, + r#"ALTER PUBLICATION pub DROP TABLE users"#, + r#"ALTER PUBLICATION pub ADD TABLES IN SCHEMA public, sales"#, + r#"ALTER PUBLICATION pub SET TABLES IN SCHEMA public"#, + r#"ALTER PUBLICATION pub DROP TABLES IN SCHEMA sales"#, + r#"ALTER PUBLICATION pub SET (publish = 'insert, update', publish_via_partition_root = true)"#, + r#"ALTER PUBLICATION pub OWNER TO CURRENT_USER"#, + r#"ALTER PUBLICATION pub RENAME TO pub_new"#, + ]); } diff --git a/tests/test_alter_role.rs b/tests/test_alter_role.rs index 692887d..420b398 100644 --- a/tests/test_alter_role.rs +++ b/tests/test_alter_role.rs @@ -2,7 +2,50 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER ROLE +// Description: change a database role +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterrole.html + #[test] fn alter_role_parses() { - run_cases(&["ALTER ROLE my_role SET work_mem TO '64MB'"]); + run_cases(&[ + r#"ALTER ROLE app_user WITH LOGIN CREATEDB PASSWORD 'secret'"#, + r#"ALTER ROLE app_user RENAME TO app_user_new"#, + r#"ALTER ROLE app_user IN DATABASE mydb SET search_path TO public"#, + r#"ALTER ROLE app_user SET work_mem = '64MB'"#, + r#"ALTER ROLE app_user SET enable_seqscan FROM CURRENT"#, + r#"ALTER ROLE app_user RESET work_mem"#, + r#"ALTER ROLE app_user RESET ALL"#, + r#"ALTER ROLE ALL IN DATABASE mydb SET statement_timeout TO '5s'"#, + ]); } diff --git a/tests/test_alter_routine.rs b/tests/test_alter_routine.rs index 1d4a991..e9818a8 100644 --- a/tests/test_alter_routine.rs +++ b/tests/test_alter_routine.rs @@ -2,7 +2,45 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER ROUTINE +// Description: change the definition of a routine +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterroutine.html + #[test] fn alter_routine_parses() { - run_cases(&["ALTER ROUTINE my_routine(integer) RENAME TO my_routine2"]); + run_cases(&[ + r#"ALTER ROUTINE my_function(integer) IMMUTABLE PARALLEL SAFE COST 10"#, + r#"ALTER ROUTINE my_function(integer) SET search_path TO public"#, + r#"ALTER ROUTINE my_function(integer) RESET ALL"#, + r#"ALTER ROUTINE my_function(integer) OWNER TO CURRENT_USER"#, + r#"ALTER ROUTINE my_function(integer) RENAME TO my_function_new"#, + r#"ALTER ROUTINE my_function(integer) SET SCHEMA public"#, + r#"ALTER ROUTINE my_function(integer) DEPENDS ON EXTENSION hstore"#, + r#"ALTER ROUTINE my_function(integer) NO DEPENDS ON EXTENSION hstore"#, + ]); } diff --git a/tests/test_alter_rule.rs b/tests/test_alter_rule.rs index 56f9e4d..9771b45 100644 --- a/tests/test_alter_rule.rs +++ b/tests/test_alter_rule.rs @@ -2,7 +2,14 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER RULE +// Description: change the definition of a rule +// Syntax: +// ALTER RULE name ON table_name RENAME TO new_name +// +// URL: https://www.postgresql.org/docs/18/sql-alterrule.html + #[test] fn alter_rule_parses() { - run_cases(&["ALTER RULE my_rule ON my_table RENAME TO my_rule2"]); + run_cases(&[r#"ALTER RULE my_rule ON my_table RENAME TO my_rule_new"#]); } diff --git a/tests/test_alter_schema.rs b/tests/test_alter_schema.rs index 9d8be59..7f1d9f4 100644 --- a/tests/test_alter_schema.rs +++ b/tests/test_alter_schema.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER SCHEMA +// Description: change the definition of a schema +// Syntax: +// ALTER SCHEMA name RENAME TO new_name +// ALTER SCHEMA name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } +// +// URL: https://www.postgresql.org/docs/18/sql-alterschema.html + #[test] fn alter_schema_parses() { - run_cases(&["ALTER SCHEMA my_schema RENAME TO my_schema2"]); + run_cases(&[ + r#"ALTER SCHEMA old_schema RENAME TO new_schema"#, + r#"ALTER SCHEMA old_schema OWNER TO CURRENT_USER"#, + ]); } diff --git a/tests/test_alter_sequence.rs b/tests/test_alter_sequence.rs index 3abc62d..be640cf 100644 --- a/tests/test_alter_sequence.rs +++ b/tests/test_alter_sequence.rs @@ -2,7 +2,32 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER SEQUENCE +// Description: change the definition of a sequence generator +// Syntax: +// ALTER SEQUENCE [ IF EXISTS ] name +// [ AS data_type ] +// [ INCREMENT [ BY ] increment ] +// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] +// [ [ NO ] CYCLE ] +// [ START [ WITH ] start ] +// [ RESTART [ [ WITH ] restart ] ] +// [ CACHE cache ] +// [ 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altersequence.html + #[test] fn alter_sequence_parses() { - run_cases(&["ALTER SEQUENCE my_sequence RESTART WITH 1"]); + run_cases(&[ + r#"ALTER SEQUENCE IF EXISTS seq AS bigint INCREMENT BY 2 MINVALUE 1 MAXVALUE 1000 START WITH 10 RESTART WITH 20 CACHE 5 CYCLE OWNED BY users.id"#, + r#"ALTER SEQUENCE seq NO MINVALUE NO MAXVALUE NO CYCLE OWNED BY NONE"#, + r#"ALTER SEQUENCE seq OWNER TO CURRENT_USER"#, + r#"ALTER SEQUENCE seq RENAME TO seq_new"#, + r#"ALTER SEQUENCE seq SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_server.rs b/tests/test_alter_server.rs index 397d42a..168e9db 100644 --- a/tests/test_alter_server.rs +++ b/tests/test_alter_server.rs @@ -2,7 +2,21 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER SERVER +// Description: change the definition of a foreign server +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alterserver.html + #[test] fn alter_server_parses() { - run_cases(&["ALTER SERVER my_server RENAME TO my_server2"]); + run_cases(&[ + r#"ALTER SERVER my_server VERSION '2.0' OPTIONS (ADD host 'localhost', SET port '5432', DROP oldopt)"#, + r#"ALTER SERVER my_server OWNER TO CURRENT_USER"#, + r#"ALTER SERVER my_server RENAME TO my_server_new"#, + ]); } diff --git a/tests/test_alter_statistics.rs b/tests/test_alter_statistics.rs index cb9c789..a31fd9b 100644 --- a/tests/test_alter_statistics.rs +++ b/tests/test_alter_statistics.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER STATISTICS +// Description: change the definition of an extended statistics object +// Syntax: +// 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 } +// +// URL: https://www.postgresql.org/docs/18/sql-alterstatistics.html + #[test] fn alter_statistics_parses() { - run_cases(&["ALTER STATISTICS my_statistics SET STATISTICS 100"]); + run_cases(&[ + r#"ALTER STATISTICS stats SET STATISTICS 1000"#, + r#"ALTER STATISTICS stats OWNER TO CURRENT_USER"#, + r#"ALTER STATISTICS stats RENAME TO stats_new"#, + r#"ALTER STATISTICS stats SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_subscription.rs b/tests/test_alter_subscription.rs index ab1a62d..e8bf75c 100644 --- a/tests/test_alter_subscription.rs +++ b/tests/test_alter_subscription.rs @@ -2,7 +2,36 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER SUBSCRIPTION +// Description: change the definition of a subscription +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altersubscription.html + #[test] fn alter_subscription_parses() { - run_cases(&["ALTER SUBSCRIPTION my_subscription ENABLE"]); + run_cases(&[ + r#"ALTER SUBSCRIPTION sub CONNECTION 'host=localhost dbname=postgres'"#, + r#"ALTER SUBSCRIPTION sub SET PUBLICATION pub1, pub2 WITH (copy_data = false)"#, + r#"ALTER SUBSCRIPTION sub ADD PUBLICATION pub3 WITH (copy_data = true)"#, + r#"ALTER SUBSCRIPTION sub DROP PUBLICATION pub3 WITH (refresh = false)"#, + r#"ALTER SUBSCRIPTION sub REFRESH PUBLICATION WITH (copy_data = false)"#, + r#"ALTER SUBSCRIPTION sub ENABLE"#, + r#"ALTER SUBSCRIPTION sub DISABLE"#, + r#"ALTER SUBSCRIPTION sub SET (slot_name = 'slot1', synchronous_commit = off)"#, + r#"ALTER SUBSCRIPTION sub SKIP (lsn = '0/16B6C50')"#, + r#"ALTER SUBSCRIPTION sub OWNER TO CURRENT_USER"#, + r#"ALTER SUBSCRIPTION sub RENAME TO sub_new"#, + ]); } diff --git a/tests/test_alter_system.rs b/tests/test_alter_system.rs index bf48f62..33b4822 100644 --- a/tests/test_alter_system.rs +++ b/tests/test_alter_system.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER SYSTEM +// Description: change a server configuration parameter +// Syntax: +// ALTER SYSTEM SET configuration_parameter { TO | = } { value [, ...] | DEFAULT } +// +// ALTER SYSTEM RESET configuration_parameter +// ALTER SYSTEM RESET ALL +// +// URL: https://www.postgresql.org/docs/18/sql-altersystem.html + #[test] fn alter_system_parses() { - run_cases(&["ALTER SYSTEM SET work_mem TO '64MB'"]); + run_cases(&[ + r#"ALTER SYSTEM SET work_mem TO '64MB'"#, + r#"ALTER SYSTEM SET work_mem = '64MB'"#, + r#"ALTER SYSTEM RESET work_mem"#, + r#"ALTER SYSTEM RESET ALL"#, + ]); } diff --git a/tests/test_alter_table.rs b/tests/test_alter_table.rs index 35ba51f..ab191ab 100644 --- a/tests/test_alter_table.rs +++ b/tests/test_alter_table.rs @@ -2,7 +2,197 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TABLE +// Description: change the definition of a table +// Syntax: +// ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] +// action [, ... ] +// 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 ] +// +// 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 ] [ ENFORCED | NOT ENFORCED ] +// ALTER CONSTRAINT constraint_name [ INHERIT | NO INHERIT ] +// 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 } +// +// 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 ) +// +// and column_constraint is: +// +// [ CONSTRAINT constraint_name ] +// { NOT NULL [ NO INHERIT ] | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | +// 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 ] [ ENFORCED | NOT ENFORCED ] +// +// and table_constraint is: +// +// [ CONSTRAINT constraint_name ] +// { CHECK ( expression ) [ NO INHERIT ] | +// NOT NULL column_name [ NO INHERIT ] | +// UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | +// PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | +// EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | +// FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] +// [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +// +// and table_constraint_using_index is: +// +// [ CONSTRAINT constraint_name ] +// { UNIQUE | PRIMARY KEY } USING INDEX index_name +// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] +// +// index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +// +// [ INCLUDE ( column_name [, ... ] ) ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ USING INDEX TABLESPACE tablespace_name ] +// +// exclude_element in an EXCLUDE constraint is: +// +// { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] +// +// referential_action in a FOREIGN KEY/REFERENCES constraint is: +// +// { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } +// +// URL: https://www.postgresql.org/docs/18/sql-altertable.html + #[test] fn alter_table_parses() { - run_cases(&["ALTER TABLE my_table ADD COLUMN new_column integer"]); + run_cases(&[ + r#"ALTER TABLE IF EXISTS ONLY my_table ADD COLUMN IF NOT EXISTS new_column integer COLLATE "C" DEFAULT 0"#, + r#"ALTER TABLE my_table DROP COLUMN IF EXISTS old_column CASCADE"#, + r#"ALTER TABLE my_table ALTER COLUMN id TYPE bigint USING id::bigint"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET DEFAULT 1"#, + r#"ALTER TABLE my_table ALTER COLUMN id DROP DEFAULT"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET NOT NULL"#, + r#"ALTER TABLE my_table ALTER COLUMN id DROP NOT NULL"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET EXPRESSION AS (id + 1)"#, + r#"ALTER TABLE my_table ALTER COLUMN id DROP EXPRESSION IF EXISTS"#, + r#"ALTER TABLE my_table ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY (START WITH 1)"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET GENERATED BY DEFAULT"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET INCREMENT BY 2"#, + r#"ALTER TABLE my_table ALTER COLUMN id RESTART WITH 10"#, + r#"ALTER TABLE my_table ALTER COLUMN id DROP IDENTITY IF EXISTS"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET STATISTICS DEFAULT"#, + r#"ALTER TABLE my_table ALTER COLUMN id SET (n_distinct = 10)"#, + r#"ALTER TABLE my_table ALTER COLUMN id RESET (n_distinct)"#, + r#"ALTER TABLE my_table ALTER COLUMN body SET STORAGE EXTENDED"#, + r#"ALTER TABLE my_table ALTER COLUMN body SET COMPRESSION pglz"#, + r#"ALTER TABLE my_table ADD CONSTRAINT nn NOT NULL id NO INHERIT"#, + r#"ALTER TABLE my_table ADD CONSTRAINT chk CHECK (id > 0) NOT VALID"#, + r#"ALTER TABLE my_table ADD CONSTRAINT uq UNIQUE NULLS NOT DISTINCT (id) INCLUDE (body) WITH (fillfactor = 80) USING INDEX TABLESPACE fastspace"#, + r#"ALTER TABLE my_table ADD CONSTRAINT pk PRIMARY KEY USING INDEX my_index"#, + r#"ALTER TABLE my_table ALTER CONSTRAINT fk DEFERRABLE INITIALLY DEFERRED ENFORCED"#, + r#"ALTER TABLE my_table ALTER CONSTRAINT nn NO INHERIT"#, + r#"ALTER TABLE my_table VALIDATE CONSTRAINT chk"#, + r#"ALTER TABLE my_table DROP CONSTRAINT IF EXISTS chk RESTRICT"#, + r#"ALTER TABLE my_table DISABLE TRIGGER USER"#, + r#"ALTER TABLE my_table ENABLE REPLICA TRIGGER trg"#, + r#"ALTER TABLE my_table DISABLE RULE rewrite_rule"#, + r#"ALTER TABLE my_table ENABLE ALWAYS RULE rewrite_rule"#, + r#"ALTER TABLE my_table DISABLE ROW LEVEL SECURITY"#, + r#"ALTER TABLE my_table ENABLE ROW LEVEL SECURITY"#, + r#"ALTER TABLE my_table FORCE ROW LEVEL SECURITY"#, + r#"ALTER TABLE my_table NO FORCE ROW LEVEL SECURITY"#, + r#"ALTER TABLE my_table CLUSTER ON my_index"#, + r#"ALTER TABLE my_table SET WITHOUT CLUSTER"#, + r#"ALTER TABLE my_table SET WITHOUT OIDS"#, + r#"ALTER TABLE my_table SET ACCESS METHOD DEFAULT"#, + r#"ALTER TABLE my_table SET TABLESPACE fastspace"#, + r#"ALTER TABLE my_table SET LOGGED"#, + r#"ALTER TABLE my_table SET UNLOGGED"#, + r#"ALTER TABLE my_table SET (fillfactor = 80)"#, + r#"ALTER TABLE my_table RESET (fillfactor)"#, + r#"ALTER TABLE my_table INHERIT parent_table"#, + r#"ALTER TABLE my_table NO INHERIT parent_table"#, + r#"ALTER TABLE my_table OF my_type"#, + r#"ALTER TABLE my_table NOT OF"#, + r#"ALTER TABLE my_table OWNER TO CURRENT_USER"#, + r#"ALTER TABLE my_table REPLICA IDENTITY DEFAULT"#, + r#"ALTER TABLE my_table REPLICA IDENTITY USING INDEX my_index"#, + r#"ALTER TABLE my_table RENAME COLUMN old_column TO new_column"#, + r#"ALTER TABLE my_table RENAME CONSTRAINT old_constraint TO new_constraint"#, + r#"ALTER TABLE my_table RENAME TO my_table_new"#, + r#"ALTER TABLE my_table SET SCHEMA archive"#, + r#"ALTER TABLE ALL IN TABLESPACE oldspace OWNED BY app_user SET TABLESPACE newspace NOWAIT"#, + r#"ALTER TABLE parent ATTACH PARTITION child FOR VALUES IN (1, 2)"#, + r#"ALTER TABLE parent ATTACH PARTITION child FOR VALUES FROM (1, MINVALUE) TO (10, MAXVALUE)"#, + r#"ALTER TABLE parent ATTACH PARTITION child FOR VALUES WITH (MODULUS 4, REMAINDER 1)"#, + r#"ALTER TABLE parent ATTACH PARTITION child DEFAULT"#, + r#"ALTER TABLE parent DETACH PARTITION child CONCURRENTLY"#, + r#"ALTER TABLE parent DETACH PARTITION child FINALIZE"#, + ]); } diff --git a/tests/test_alter_tablespace.rs b/tests/test_alter_tablespace.rs index 8d7cae9..285f44f 100644 --- a/tests/test_alter_tablespace.rs +++ b/tests/test_alter_tablespace.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TABLESPACE +// Description: change the definition of a tablespace +// Syntax: +// 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 [, ... ] ) +// +// URL: https://www.postgresql.org/docs/18/sql-altertablespace.html + #[test] fn alter_tablespace_parses() { - run_cases(&["ALTER TABLESPACE my_tablespace RENAME TO my_tablespace2"]); + run_cases(&[ + r#"ALTER TABLESPACE fastspace RENAME TO slowspace"#, + r#"ALTER TABLESPACE fastspace OWNER TO CURRENT_USER"#, + r#"ALTER TABLESPACE fastspace SET (random_page_cost = 1.1, seq_page_cost = 1.0)"#, + r#"ALTER TABLESPACE fastspace RESET (random_page_cost)"#, + ]); } diff --git a/tests/test_alter_text_search_configuration.rs b/tests/test_alter_text_search_configuration.rs index f0982f4..def5ffd 100644 --- a/tests/test_alter_text_search_configuration.rs +++ b/tests/test_alter_text_search_configuration.rs @@ -1,8 +1,98 @@ mod common; -use common::run_parse_debug_cases as run_cases; +use common::run_parse_debug_case as run_case; +use pg_raw_parse::{Node, parse}; + +// Command: ALTER TEXT SEARCH CONFIGURATION +// Description: change the definition of a text search configuration +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altertsconfig.html + +#[test] +fn alter_text_search_configuration_add_mapping() { + run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config ADD MAPPING FOR asciiword WITH simple"#); +} + +#[test] +fn alter_text_search_configuration_alter_mapping_for_tokens() { + run_case( + r#"ALTER TEXT SEARCH CONFIGURATION my_config ALTER MAPPING FOR asciiword WITH english_stem"#, + ); +} + +#[test] +fn alter_text_search_configuration_replace_mapping_dictionary() { + run_case( + r#"ALTER TEXT SEARCH CONFIGURATION my_config ALTER MAPPING REPLACE simple WITH english_stem"#, + ); +} + +#[test] +fn alter_text_search_configuration_replace_mapping_for_tokens() { + run_case( + r#"ALTER TEXT SEARCH CONFIGURATION my_config ALTER MAPPING FOR asciiword REPLACE simple WITH english_stem"#, + ); +} + +#[test] +fn alter_text_search_configuration_drop_mapping() { + run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config DROP MAPPING IF EXISTS FOR asciiword"#); +} + +#[test] +fn alter_text_search_configuration_rename() { + run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config RENAME TO my_config_new"#); +} + +#[test] +fn alter_text_search_configuration_owner() { + run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config OWNER TO CURRENT_USER"#); +} + +#[test] +fn alter_text_search_configuration_set_schema() { + run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config SET SCHEMA public"#); +} #[test] -fn alter_text_search_configuration_parses() { - run_cases(&["ALTER TEXT SEARCH CONFIGURATION my_config RENAME TO my_config2"]); +fn alter_text_search_configuration_mapping_fields_are_node_lists() { + let ast = + parse(r#"ALTER TEXT SEARCH CONFIGURATION my_config ADD MAPPING FOR asciiword WITH simple"#) + .unwrap(); + + let Node::AlterTSConfigurationStmt(stmt) = ast.stmts().next().unwrap() else { + panic!("expected AlterTSConfigurationStmt"); + }; + + // tokentype() is a generic NodeList. For named token types, entries are + // String nodes. + let token_type = stmt.tokentype().first().expect("expected token type"); + assert_eq!(token_type.as_str(), Some("asciiword")); + + // Dictionaries are represented as a list of qualified-name lists. For the + // unqualified dictionary `simple`, dicts() contains one nested NodeList, + // and that nested list contains one String node. + let dictionary_name = stmt + .dicts() + .first() + .expect("expected dictionary") + .expect_node_list(); + assert_eq!( + dictionary_name.first().and_then(Node::as_str), + Some("simple") + ); } diff --git a/tests/test_alter_text_search_dictionary.rs b/tests/test_alter_text_search_dictionary.rs index 47fc266..54e11ad 100644 --- a/tests/test_alter_text_search_dictionary.rs +++ b/tests/test_alter_text_search_dictionary.rs @@ -2,7 +2,24 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TEXT SEARCH DICTIONARY +// Description: change the definition of a text search dictionary +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-altertsdictionary.html + #[test] fn alter_text_search_dictionary_parses() { - run_cases(&["ALTER TEXT SEARCH DICTIONARY my_dictionary RENAME TO my_dictionary2"]); + run_cases(&[ + r#"ALTER TEXT SEARCH DICTIONARY my_dict (StopWords = english)"#, + r#"ALTER TEXT SEARCH DICTIONARY my_dict RENAME TO my_dict_new"#, + r#"ALTER TEXT SEARCH DICTIONARY my_dict OWNER TO CURRENT_USER"#, + r#"ALTER TEXT SEARCH DICTIONARY my_dict SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_text_search_parser.rs b/tests/test_alter_text_search_parser.rs index c6bf5b9..c56fd06 100644 --- a/tests/test_alter_text_search_parser.rs +++ b/tests/test_alter_text_search_parser.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TEXT SEARCH PARSER +// Description: change the definition of a text search parser +// Syntax: +// ALTER TEXT SEARCH PARSER name RENAME TO new_name +// ALTER TEXT SEARCH PARSER name SET SCHEMA new_schema +// +// URL: https://www.postgresql.org/docs/18/sql-altertsparser.html + #[test] fn alter_text_search_parser_parses() { - run_cases(&["ALTER TEXT SEARCH PARSER my_parser RENAME TO my_parser2"]); + run_cases(&[ + r#"ALTER TEXT SEARCH PARSER my_parser RENAME TO my_parser_new"#, + r#"ALTER TEXT SEARCH PARSER my_parser SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_text_search_template.rs b/tests/test_alter_text_search_template.rs index da8cb34..bca49c9 100644 --- a/tests/test_alter_text_search_template.rs +++ b/tests/test_alter_text_search_template.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TEXT SEARCH TEMPLATE +// Description: change the definition of a text search template +// Syntax: +// ALTER TEXT SEARCH TEMPLATE name RENAME TO new_name +// ALTER TEXT SEARCH TEMPLATE name SET SCHEMA new_schema +// +// URL: https://www.postgresql.org/docs/18/sql-altertstemplate.html + #[test] fn alter_text_search_template_parses() { - run_cases(&["ALTER TEXT SEARCH TEMPLATE my_template RENAME TO my_template2"]); + run_cases(&[ + r#"ALTER TEXT SEARCH TEMPLATE my_template RENAME TO my_template_new"#, + r#"ALTER TEXT SEARCH TEMPLATE my_template SET SCHEMA public"#, + ]); } diff --git a/tests/test_alter_trigger.rs b/tests/test_alter_trigger.rs index 84645e8..a4931dd 100644 --- a/tests/test_alter_trigger.rs +++ b/tests/test_alter_trigger.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TRIGGER +// Description: change the definition of a trigger +// Syntax: +// ALTER TRIGGER name ON table_name RENAME TO new_name +// ALTER TRIGGER name ON table_name [ NO ] DEPENDS ON EXTENSION extension_name +// +// URL: https://www.postgresql.org/docs/18/sql-altertrigger.html + #[test] fn alter_trigger_parses() { - run_cases(&["ALTER TRIGGER my_trigger ON my_table RENAME TO my_trigger2"]); + run_cases(&[ + r#"ALTER TRIGGER trg ON my_table RENAME TO trg_new"#, + r#"ALTER TRIGGER trg ON my_table DEPENDS ON EXTENSION hstore"#, + r#"ALTER TRIGGER trg ON my_table NO DEPENDS ON EXTENSION hstore"#, + ]); } diff --git a/tests/test_alter_type.rs b/tests/test_alter_type.rs index 373f2a9..3c0562d 100644 --- a/tests/test_alter_type.rs +++ b/tests/test_alter_type.rs @@ -2,7 +2,39 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER TYPE +// Description: change the definition of a type +// Syntax: +// 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 ] +// +// URL: https://www.postgresql.org/docs/18/sql-altertype.html + #[test] fn alter_type_parses() { - run_cases(&["ALTER TYPE my_type RENAME TO my_type2"]); + run_cases(&[ + r#"ALTER TYPE my_type OWNER TO CURRENT_USER"#, + r#"ALTER TYPE my_type RENAME TO my_type_new"#, + r#"ALTER TYPE my_type SET SCHEMA public"#, + r#"ALTER TYPE my_type RENAME ATTRIBUTE old_attr TO new_attr CASCADE"#, + r#"ALTER TYPE my_type ADD ATTRIBUTE new_attr integer COLLATE "C" RESTRICT"#, + r#"ALTER TYPE my_type DROP ATTRIBUTE IF EXISTS old_attr CASCADE"#, + r#"ALTER TYPE my_type ALTER ATTRIBUTE attr TYPE text COLLATE "C" CASCADE"#, + r#"ALTER TYPE mood ADD VALUE 'happy' BEFORE 'sad'"#, + r#"ALTER TYPE mood RENAME VALUE 'happy' TO 'joyful'"#, + r#"ALTER TYPE my_type SET (RECEIVE = my_receive, SEND = my_send)"#, + r#"ALTER TYPE my_type SET (STORAGE = extended)"#, + ]); } diff --git a/tests/test_alter_user.rs b/tests/test_alter_user.rs index f1ba8de..20a6713 100644 --- a/tests/test_alter_user.rs +++ b/tests/test_alter_user.rs @@ -2,7 +2,48 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER USER +// Description: change a database role +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-alteruser.html + #[test] fn alter_user_parses() { - run_cases(&["ALTER USER my_user SET work_mem TO '64MB'"]); + run_cases(&[ + r#"ALTER USER app_user WITH LOGIN PASSWORD 'secret'"#, + r#"ALTER USER app_user RENAME TO app_user_new"#, + r#"ALTER USER app_user SET search_path TO public"#, + r#"ALTER USER app_user IN DATABASE mydb SET work_mem TO '64MB'"#, + r#"ALTER USER app_user RESET work_mem"#, + r#"ALTER USER app_user RESET ALL"#, + ]); } diff --git a/tests/test_alter_user_mapping.rs b/tests/test_alter_user_mapping.rs index b227c24..a90f031 100644 --- a/tests/test_alter_user_mapping.rs +++ b/tests/test_alter_user_mapping.rs @@ -2,9 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER USER MAPPING +// Description: change the definition of a user mapping +// Syntax: +// ALTER USER MAPPING FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC } +// SERVER server_name +// OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) +// +// URL: https://www.postgresql.org/docs/18/sql-alterusermapping.html + #[test] fn alter_user_mapping_parses() { run_cases(&[ - "ALTER USER MAPPING FOR my_user SERVER my_server OPTIONS (SET user 'remote_user')", + r#"ALTER USER MAPPING FOR app_user SERVER my_server OPTIONS (ADD user 'remote', SET password 'secret')"#, + r#"ALTER USER MAPPING FOR CURRENT_USER SERVER my_server OPTIONS (DROP password)"#, + r#"ALTER USER MAPPING FOR PUBLIC SERVER my_server OPTIONS (SET user 'public')"#, ]); } diff --git a/tests/test_alter_view.rs b/tests/test_alter_view.rs index 7a4fc4c..dca326c 100644 --- a/tests/test_alter_view.rs +++ b/tests/test_alter_view.rs @@ -2,7 +2,29 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: ALTER VIEW +// Description: change the definition of a view +// Syntax: +// 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 [, ... ] ) +// +// URL: https://www.postgresql.org/docs/18/sql-alterview.html + #[test] fn alter_view_parses() { - run_cases(&["ALTER VIEW my_view RENAME TO my_view2"]); + run_cases(&[ + r#"ALTER VIEW IF EXISTS v ALTER COLUMN col SET DEFAULT 1"#, + r#"ALTER VIEW v ALTER COLUMN col DROP DEFAULT"#, + r#"ALTER VIEW v OWNER TO CURRENT_USER"#, + r#"ALTER VIEW v RENAME TO v_new"#, + r#"ALTER VIEW v SET SCHEMA public"#, + r#"ALTER VIEW v SET (security_barrier = true, check_option = local)"#, + r#"ALTER VIEW v RESET (security_barrier)"#, + ]); } diff --git a/tests/test_comment.rs b/tests/test_comment.rs index f7c69d0..d56f505 100644 --- a/tests/test_comment.rs +++ b/tests/test_comment.rs @@ -2,7 +2,73 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: COMMENT +// Description: define or change the comment of an object +// Syntax: +// 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 [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-comment.html + #[test] fn comment_parses() { - run_cases(&["COMMENT ON TABLE my_table IS 'comment'"]); + run_cases(&[ + r#"COMMENT ON TABLE my_table IS 'table comment'"#, + r#"COMMENT ON COLUMN my_table.id IS 'column comment'"#, + r#"COMMENT ON FUNCTION my_function(integer) IS 'function comment'"#, + r#"COMMENT ON OPERATOR +(integer, integer) IS 'operator comment'"#, + r#"COMMENT ON CONSTRAINT my_constraint ON my_table IS 'constraint comment'"#, + r#"COMMENT ON LARGE OBJECT 12345 IS 'large object comment'"#, + r#"COMMENT ON TABLE my_table IS NULL"#, + ]); } diff --git a/tests/test_create_access_method.rs b/tests/test_create_access_method.rs index dabb88c..9db4b41 100644 --- a/tests/test_create_access_method.rs +++ b/tests/test_create_access_method.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE ACCESS METHOD +// Description: define a new access method +// Syntax: +// CREATE ACCESS METHOD name +// TYPE access_method_type +// HANDLER handler_function +// +// URL: https://www.postgresql.org/docs/18/sql-create-access-method.html + #[test] fn create_access_method_parses() { - run_cases(&["CREATE ACCESS METHOD my_am TYPE INDEX HANDLER my_handler"]); + run_cases(&[ + r#"CREATE ACCESS METHOD my_am TYPE INDEX HANDLER my_handler"#, + r#"CREATE ACCESS METHOD my_table_am TYPE TABLE HANDLER my_table_handler"#, + ]); } diff --git a/tests/test_create_aggregate.rs b/tests/test_create_aggregate.rs index 9caeb3e..2043fef 100644 --- a/tests/test_create_aggregate.rs +++ b/tests/test_create_aggregate.rs @@ -2,7 +2,78 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE AGGREGATE +// Description: define a new aggregate function +// Syntax: +// 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 ] +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createaggregate.html + #[test] fn create_aggregate_parses() { - run_cases(&["CREATE AGGREGATE my_aggregate(integer) (SFUNC = int4pl, STYPE = integer)"]); + run_cases(&[ + r#"CREATE AGGREGATE my_sum(integer) (SFUNC = int4pl, STYPE = integer)"#, + r#"CREATE AGGREGATE my_sum(*) (SFUNC = int8inc, STYPE = bigint)"#, + r#"CREATE AGGREGATE my_sum(ORDER BY integer) (SFUNC = int4pl, STYPE = integer)"#, + r#"CREATE AGGREGATE my_hypothetical(integer ORDER BY integer) (SFUNC = int4pl, STYPE = integer, FINALFUNC = int4abs)"#, + ]); } diff --git a/tests/test_create_cast.rs b/tests/test_create_cast.rs index 5b33279..18ec092 100644 --- a/tests/test_create_cast.rs +++ b/tests/test_create_cast.rs @@ -2,7 +2,28 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE CAST +// Description: define a new cast +// Syntax: +// 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 ] +// +// URL: https://www.postgresql.org/docs/18/sql-createcast.html + #[test] fn create_cast_parses() { - run_cases(&["CREATE CAST (integer AS bigint) WITHOUT FUNCTION AS IMPLICIT"]); + run_cases(&[ + r#"CREATE CAST (integer AS bigint) WITHOUT FUNCTION AS IMPLICIT"#, + r#"CREATE CAST (integer AS text) WITH FUNCTION int4out(integer) AS ASSIGNMENT"#, + r#"CREATE CAST (my_type AS text) WITH INOUT"#, + ]); } diff --git a/tests/test_create_collation.rs b/tests/test_create_collation.rs index e39de90..7155a69 100644 --- a/tests/test_create_collation.rs +++ b/tests/test_create_collation.rs @@ -2,7 +2,26 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE COLLATION +// Description: define a new collation +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createcollation.html + #[test] fn create_collation_parses() { - run_cases(&["CREATE COLLATION my_collation (provider = libc, locale = 'C')"]); + run_cases(&[ + r#"CREATE COLLATION my_collation (provider = libc, locale = 'C')"#, + r#"CREATE COLLATION IF NOT EXISTS my_collation FROM "C""#, + ]); } diff --git a/tests/test_create_conversion.rs b/tests/test_create_conversion.rs index 4aece4c..6a82aa2 100644 --- a/tests/test_create_conversion.rs +++ b/tests/test_create_conversion.rs @@ -2,9 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE CONVERSION +// Description: define a new encoding conversion +// Syntax: +// CREATE [ DEFAULT ] CONVERSION name +// FOR source_encoding TO dest_encoding FROM function_name +// +// URL: https://www.postgresql.org/docs/18/sql-createconversion.html + #[test] fn create_conversion_parses() { run_cases(&[ - "CREATE DEFAULT CONVERSION my_conversion FOR 'UTF8' TO 'LATIN1' FROM utf8_to_latin1", + r#"CREATE DEFAULT CONVERSION my_conversion FOR 'UTF8' TO 'LATIN1' FROM my_convert_function"#, + r#"CREATE CONVERSION my_conversion FOR 'LATIN1' TO 'UTF8' FROM my_convert_function"#, ]); } diff --git a/tests/test_create_database.rs b/tests/test_create_database.rs index 648d4c4..37277fd 100644 --- a/tests/test_create_database.rs +++ b/tests/test_create_database.rs @@ -2,7 +2,35 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE DATABASE +// Description: create a new database +// Syntax: +// 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 ] +// +// URL: https://www.postgresql.org/docs/18/sql-createdatabase.html + #[test] fn create_database_parses() { - run_cases(&["CREATE DATABASE my_database"]); + run_cases(&[ + r#"CREATE DATABASE mydb"#, + r#"CREATE DATABASE mydb WITH OWNER = app_user TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'C' TABLESPACE = pg_default ALLOW_CONNECTIONS = true CONNECTION LIMIT = 10 IS_TEMPLATE = false"#, + r#"CREATE DATABASE mydb STRATEGY = WAL_LOG"#, + ]); } diff --git a/tests/test_create_domain.rs b/tests/test_create_domain.rs index bfb1985..63125ff 100644 --- a/tests/test_create_domain.rs +++ b/tests/test_create_domain.rs @@ -2,7 +2,25 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE DOMAIN +// Description: define a new domain +// Syntax: +// CREATE DOMAIN name [ AS ] data_type +// [ COLLATE collation ] +// [ DEFAULT expression ] +// [ domain_constraint [ ... ] ] +// +// where domain_constraint is: +// +// [ CONSTRAINT constraint_name ] +// { NOT NULL | NULL | CHECK (expression) } +// +// URL: https://www.postgresql.org/docs/18/sql-createdomain.html + #[test] fn create_domain_parses() { - run_cases(&["CREATE DOMAIN my_domain AS integer CHECK (VALUE > 0)"]); + run_cases(&[ + r#"CREATE DOMAIN email_domain AS text CHECK (VALUE LIKE '%@%')"#, + r#"CREATE DOMAIN email_domain AS text COLLATE "C" DEFAULT 'x@example.com' NOT NULL CONSTRAINT email_check CHECK (VALUE LIKE '%@%')"#, + ]); } diff --git a/tests/test_create_event_trigger.rs b/tests/test_create_event_trigger.rs index e9e74e3..94091b3 100644 --- a/tests/test_create_event_trigger.rs +++ b/tests/test_create_event_trigger.rs @@ -2,9 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE EVENT TRIGGER +// Description: define a new event trigger +// Syntax: +// CREATE EVENT TRIGGER name +// ON event +// [ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ] +// EXECUTE { FUNCTION | PROCEDURE } function_name() +// +// URL: https://www.postgresql.org/docs/18/sql-createeventtrigger.html + #[test] fn create_event_trigger_parses() { run_cases(&[ - "CREATE EVENT TRIGGER my_event_trigger ON ddl_command_start EXECUTE FUNCTION my_function()", + r#"CREATE EVENT TRIGGER trg ON ddl_command_start EXECUTE FUNCTION my_function()"#, + r#"CREATE EVENT TRIGGER trg ON sql_drop WHEN TAG IN ('DROP TABLE', 'DROP VIEW') EXECUTE FUNCTION my_function()"#, ]); } diff --git a/tests/test_create_extension.rs b/tests/test_create_extension.rs index 9113f69..3cfe76e 100644 --- a/tests/test_create_extension.rs +++ b/tests/test_create_extension.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE EXTENSION +// Description: install an extension +// Syntax: +// CREATE EXTENSION [ IF NOT EXISTS ] extension_name +// [ WITH ] [ SCHEMA schema_name ] +// [ VERSION version ] +// [ CASCADE ] +// +// URL: https://www.postgresql.org/docs/18/sql-createextension.html + #[test] fn create_extension_parses() { - run_cases(&["CREATE EXTENSION IF NOT EXISTS hstore"]); + run_cases(&[ + r#"CREATE EXTENSION hstore"#, + r#"CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public VERSION '1.8' CASCADE"#, + ]); } diff --git a/tests/test_create_foreign_data_wrapper.rs b/tests/test_create_foreign_data_wrapper.rs index 47e18a5..8d6e341 100644 --- a/tests/test_create_foreign_data_wrapper.rs +++ b/tests/test_create_foreign_data_wrapper.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE FOREIGN DATA WRAPPER +// Description: define a new foreign-data wrapper +// Syntax: +// CREATE FOREIGN DATA WRAPPER name +// [ HANDLER handler_function | NO HANDLER ] +// [ VALIDATOR validator_function | NO VALIDATOR ] +// [ OPTIONS ( option 'value' [, ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createforeigndatawrapper.html + #[test] fn create_foreign_data_wrapper_parses() { - run_cases(&["CREATE FOREIGN DATA WRAPPER my_fdw HANDLER my_fdw_handler"]); + run_cases(&[ + r#"CREATE FOREIGN DATA WRAPPER my_fdw HANDLER my_handler VALIDATOR my_validator OPTIONS (host 'localhost')"#, + r#"CREATE FOREIGN DATA WRAPPER my_fdw NO HANDLER NO VALIDATOR"#, + ]); } diff --git a/tests/test_create_foreign_table.rs b/tests/test_create_foreign_table.rs index 7ad1ca8..450e33d 100644 --- a/tests/test_create_foreign_table.rs +++ b/tests/test_create_foreign_table.rs @@ -2,7 +2,64 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE FOREIGN TABLE +// Description: define a new foreign table +// Syntax: +// CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ +// { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ] +// | table_constraint +// | LIKE source_table [ like_option ... ] } +// [, ... ] +// ] ) +// [ 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 [ NO INHERIT ] | +// NULL | +// CHECK ( expression ) [ NO INHERIT ] | +// DEFAULT default_expr | +// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] } +// [ ENFORCED | NOT ENFORCED ] +// +// and table_constraint is: +// +// [ CONSTRAINT constraint_name ] +// { NOT NULL column_name [ NO INHERIT ] | +// CHECK ( expression ) [ NO INHERIT ] } +// [ ENFORCED | NOT ENFORCED ] +// +// and like_option is: +// +// { INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL } +// +// 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 ) +// +// URL: https://www.postgresql.org/docs/18/sql-createforeigntable.html + #[test] fn create_foreign_table_parses() { - run_cases(&["CREATE FOREIGN TABLE my_foreign_table (id integer) SERVER my_server"]); + run_cases(&[ + r#"CREATE FOREIGN TABLE ft (id integer OPTIONS (column_name 'id'), body text COLLATE "C" NOT NULL) SERVER my_server OPTIONS (schema_name 'public', table_name 'remote')"#, + r#"CREATE FOREIGN TABLE IF NOT EXISTS ft PARTITION OF parent FOR VALUES IN (1) SERVER my_server"#, + r#"CREATE FOREIGN TABLE ft (LIKE source INCLUDING DEFAULTS, CHECK (id > 0), FOREIGN KEY (id) REFERENCES other(id)) SERVER my_server"#, + ]); } diff --git a/tests/test_create_function.rs b/tests/test_create_function.rs index 616a9c6..44900ab 100644 --- a/tests/test_create_function.rs +++ b/tests/test_create_function.rs @@ -2,14 +2,9 @@ mod common; use common::run_parse_debug_cases as run_cases; -#[test] -fn create_function_parses() { - run_cases(&[ - "CREATE FUNCTION my_function() RETURNS integer LANGUAGE SQL AS 'SELECT 1'", - "CREATE OR REPLACE FUNCTION my_function(arg integer DEFAULT 1) RETURNS TABLE (value integer) LANGUAGE SQL STABLE AS 'SELECT arg'", - ]); -} - +// Command: CREATE FUNCTION +// Description: define a new function +// Syntax: // CREATE [ OR REPLACE ] FUNCTION // name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) // [ RETURNS rettype @@ -30,3 +25,14 @@ fn create_function_parses() { // | AS 'obj_file', 'link_symbol' // | sql_body // } ... +// +// URL: https://www.postgresql.org/docs/18/sql-createfunction.html + +#[test] +fn create_function_parses() { + run_cases(&[ + r#"CREATE FUNCTION my_function() RETURNS integer LANGUAGE SQL AS 'SELECT 1'"#, + r#"CREATE OR REPLACE FUNCTION my_function(arg integer DEFAULT 1) RETURNS TABLE (value integer) LANGUAGE SQL STABLE AS 'SELECT arg'"#, + r#"CREATE FUNCTION my_function(IN arg integer, OUT value integer) RETURNS integer LANGUAGE SQL STRICT SECURITY DEFINER COST 5 ROWS 1 SET search_path TO public AS 'SELECT arg'"#, + ]); +} diff --git a/tests/test_create_group.rs b/tests/test_create_group.rs index 22be07e..d6fe0e6 100644 --- a/tests/test_create_group.rs +++ b/tests/test_create_group.rs @@ -2,7 +2,36 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE GROUP +// Description: define a new database role +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-creategroup.html + #[test] fn create_group_parses() { - run_cases(&["CREATE GROUP my_group"]); + run_cases(&[ + r#"CREATE GROUP my_group"#, + r#"CREATE GROUP my_group WITH USER alice, bob"#, + ]); } diff --git a/tests/test_create_index.rs b/tests/test_create_index.rs index 7b5ff48..11cdefc 100644 --- a/tests/test_create_index.rs +++ b/tests/test_create_index.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE INDEX +// Description: define a new index +// Syntax: +// 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 ] +// +// URL: https://www.postgresql.org/docs/18/sql-createindex.html + #[test] fn create_index_parses() { - run_cases(&["CREATE INDEX my_index ON my_table (id)"]); + run_cases(&[ + r#"CREATE INDEX my_index ON my_table (id)"#, + r#"CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS my_index ON ONLY my_table USING btree (id COLLATE "C" int4_ops ASC NULLS LAST, (lower(name)) DESC) INCLUDE (email) NULLS NOT DISTINCT WITH (fillfactor = 80) TABLESPACE fastspace WHERE id > 0"#, + ]); } diff --git a/tests/test_create_language.rs b/tests/test_create_language.rs index 8bd51ec..d8d1729 100644 --- a/tests/test_create_language.rs +++ b/tests/test_create_language.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE LANGUAGE +// Description: define a new procedural language +// Syntax: +// CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name +// HANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ] +// CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name +// +// URL: https://www.postgresql.org/docs/18/sql-createlanguage.html + #[test] fn create_language_parses() { - run_cases(&["CREATE LANGUAGE my_language"]); + run_cases(&[ + r#"CREATE LANGUAGE plsample"#, + r#"CREATE OR REPLACE TRUSTED PROCEDURAL LANGUAGE plsample HANDLER my_handler INLINE my_inline VALIDATOR my_validator"#, + ]); } diff --git a/tests/test_create_materialized_view.rs b/tests/test_create_materialized_view.rs index 44b3f53..a28751a 100644 --- a/tests/test_create_materialized_view.rs +++ b/tests/test_create_materialized_view.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE MATERIALIZED VIEW +// Description: define a new materialized view +// Syntax: +// CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name +// [ (column_name [, ...] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) ] +// [ TABLESPACE tablespace_name ] +// AS query +// [ WITH [ NO ] DATA ] +// +// URL: https://www.postgresql.org/docs/18/sql-creatematerializedview.html + #[test] fn create_materialized_view_parses() { - run_cases(&["CREATE MATERIALIZED VIEW my_matview AS SELECT 1 AS id"]); + run_cases(&[ + r#"CREATE MATERIALIZED VIEW mv AS SELECT 1 AS col"#, + r#"CREATE MATERIALIZED VIEW IF NOT EXISTS mv (col) USING heap WITH (fillfactor = 80) TABLESPACE fastspace AS SELECT 1 WITH NO DATA"#, + ]); } diff --git a/tests/test_create_operator.rs b/tests/test_create_operator.rs index 5eff8b0..eec9c03 100644 --- a/tests/test_create_operator.rs +++ b/tests/test_create_operator.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE OPERATOR +// Description: define a new operator +// Syntax: +// 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 ] +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createoperator.html + #[test] fn create_operator_parses() { - run_cases(&["CREATE OPERATOR === (FUNCTION = int4eq, LEFTARG = integer, RIGHTARG = integer)"]); + run_cases(&[ + r#"CREATE OPERATOR + (FUNCTION = my_add, LEFTARG = integer, RIGHTARG = integer)"#, + r#"CREATE OPERATOR public.## (PROCEDURE = my_op, LEFTARG = NONE, RIGHTARG = integer, COMMUTATOR = OPERATOR(public.##), NEGATOR = OPERATOR(public.!!), RESTRICT = my_restrict, JOIN = my_join, HASHES, MERGES)"#, + ]); } diff --git a/tests/test_create_operator_class.rs b/tests/test_create_operator_class.rs index 11fb0cf..4c4816c 100644 --- a/tests/test_create_operator_class.rs +++ b/tests/test_create_operator_class.rs @@ -2,9 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE OPERATOR CLASS +// Description: define a new operator class +// Syntax: +// 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 +// } [, ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-createopclass.html + #[test] fn create_operator_class_parses() { run_cases(&[ - "CREATE OPERATOR CLASS my_opclass DEFAULT FOR TYPE integer USING btree AS OPERATOR 1 < (integer, integer), FUNCTION 1 btint4cmp(integer, integer)", + r#"CREATE OPERATOR CLASS my_opclass DEFAULT FOR TYPE integer USING btree AS OPERATOR 1 <(integer, integer), FUNCTION 1 btint4cmp(integer, integer), STORAGE integer"#, + r#"CREATE OPERATOR CLASS my_opclass FOR TYPE integer USING hash FAMILY my_family AS OPERATOR 1 =(integer, integer), FUNCTION 1 hashint4(integer)"#, ]); } diff --git a/tests/test_create_operator_family.rs b/tests/test_create_operator_family.rs index 530b18f..c3ad50b 100644 --- a/tests/test_create_operator_family.rs +++ b/tests/test_create_operator_family.rs @@ -2,7 +2,14 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE OPERATOR FAMILY +// Description: define a new operator family +// Syntax: +// CREATE OPERATOR FAMILY name USING index_method +// +// URL: https://www.postgresql.org/docs/18/sql-createopfamily.html + #[test] fn create_operator_family_parses() { - run_cases(&["CREATE OPERATOR FAMILY my_opfamily USING btree"]); + run_cases(&[r#"CREATE OPERATOR FAMILY my_family USING btree"#]); } diff --git a/tests/test_create_policy.rs b/tests/test_create_policy.rs index 001724b..26f7dac 100644 --- a/tests/test_create_policy.rs +++ b/tests/test_create_policy.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE POLICY +// Description: define a new row-level security policy for a table +// Syntax: +// 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 ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createpolicy.html + #[test] fn create_policy_parses() { - run_cases(&["CREATE POLICY my_policy ON my_table USING (true)"]); + run_cases(&[ + r#"CREATE POLICY pol ON my_table"#, + r#"CREATE POLICY pol ON my_table AS RESTRICTIVE FOR UPDATE TO app_user USING (tenant_id = 1) WITH CHECK (tenant_id = 1)"#, + ]); } diff --git a/tests/test_create_procedure.rs b/tests/test_create_procedure.rs index b7083af..4bb5b6d 100644 --- a/tests/test_create_procedure.rs +++ b/tests/test_create_procedure.rs @@ -2,7 +2,26 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE PROCEDURE +// Description: define a new procedure +// Syntax: +// 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 +// } ... +// +// URL: https://www.postgresql.org/docs/18/sql-createprocedure.html + #[test] fn create_procedure_parses() { - run_cases(&["CREATE PROCEDURE my_procedure() LANGUAGE SQL AS 'SELECT 1'"]); + run_cases(&[ + r#"CREATE PROCEDURE my_proc() LANGUAGE SQL AS 'SELECT 1'"#, + r#"CREATE OR REPLACE PROCEDURE my_proc(IN arg integer DEFAULT 1, OUT value integer) LANGUAGE SQL SECURITY DEFINER SET search_path TO public AS 'SELECT arg'"#, + ]); } diff --git a/tests/test_create_publication.rs b/tests/test_create_publication.rs index 22236ca..babf66e 100644 --- a/tests/test_create_publication.rs +++ b/tests/test_create_publication.rs @@ -2,7 +2,30 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE PUBLICATION +// Description: define a new publication +// Syntax: +// CREATE PUBLICATION name +// [ FOR ALL TABLES +// | FOR publication_object [, ... ] ] +// [ WITH ( publication_parameter [= value] [, ... ] ) ] +// +// where publication_object is one of: +// +// TABLE table_and_columns [, ... ] +// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +// +// and table_and_columns is: +// +// [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createpublication.html + #[test] fn create_publication_parses() { - run_cases(&["CREATE PUBLICATION my_publication FOR TABLE my_table"]); + run_cases(&[ + r#"CREATE PUBLICATION pub FOR ALL TABLES"#, + r#"CREATE PUBLICATION pub FOR TABLE users, ONLY orders (id, total) WHERE (total > 0), TABLES IN SCHEMA public WITH (publish = 'insert, update', publish_via_partition_root = true)"#, + r#"CREATE PUBLICATION pub WITH (publish = 'truncate')"#, + ]); } diff --git a/tests/test_create_role.rs b/tests/test_create_role.rs index 3bae714..ed585c1 100644 --- a/tests/test_create_role.rs +++ b/tests/test_create_role.rs @@ -2,7 +2,34 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE ROLE +// Description: define a new database role +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createrole.html + #[test] fn create_role_parses() { - run_cases(&["CREATE ROLE my_role"]); + run_cases(&[ + r#"CREATE ROLE app_user"#, + r#"CREATE ROLE app_user WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 5 PASSWORD 'secret' VALID UNTIL 'infinity' IN ROLE parent_role ROLE child_role ADMIN admin_role USER legacy_user SYSID 10"#, + ]); } diff --git a/tests/test_create_rule.rs b/tests/test_create_rule.rs index 1a5376c..2d01ddc 100644 --- a/tests/test_create_rule.rs +++ b/tests/test_create_rule.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE RULE +// Description: define a new rewrite rule +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createrule.html + #[test] fn create_rule_parses() { - run_cases(&["CREATE RULE my_rule AS ON SELECT TO my_table DO INSTEAD SELECT * FROM my_table"]); + run_cases(&[ + r#"CREATE RULE my_rule AS ON INSERT TO my_table DO INSTEAD NOTHING"#, + r#"CREATE OR REPLACE RULE my_rule AS ON UPDATE TO my_table WHERE NEW.id > 0 DO ALSO (NOTIFY my_channel; SELECT 1)"#, + ]); } diff --git a/tests/test_create_schema.rs b/tests/test_create_schema.rs index 83e681b..4396a8a 100644 --- a/tests/test_create_schema.rs +++ b/tests/test_create_schema.rs @@ -2,7 +2,29 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE SCHEMA +// Description: define a new schema +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createschema.html + #[test] fn create_schema_parses() { - run_cases(&["CREATE SCHEMA my_schema"]); + run_cases(&[ + r#"CREATE SCHEMA my_schema"#, + r#"CREATE SCHEMA IF NOT EXISTS AUTHORIZATION app_user"#, + r#"CREATE SCHEMA AUTHORIZATION app_user CREATE TABLE t (id integer) CREATE VIEW v AS SELECT 1 AS id"#, + r#"CREATE SCHEMA my_schema AUTHORIZATION app_user"#, + ]); } diff --git a/tests/test_create_sequence.rs b/tests/test_create_sequence.rs index a0f210f..3e4f566 100644 --- a/tests/test_create_sequence.rs +++ b/tests/test_create_sequence.rs @@ -2,7 +2,24 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE SEQUENCE +// Description: define a new sequence generator +// Syntax: +// CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name +// [ AS data_type ] +// [ INCREMENT [ BY ] increment ] +// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] +// [ [ NO ] CYCLE ] +// [ START [ WITH ] start ] +// [ CACHE cache ] +// [ OWNED BY { table_name.column_name | NONE } ] +// +// URL: https://www.postgresql.org/docs/18/sql-createsequence.html + #[test] fn create_sequence_parses() { - run_cases(&["CREATE SEQUENCE my_sequence"]); + run_cases(&[ + r#"CREATE SEQUENCE seq"#, + r#"CREATE TEMPORARY SEQUENCE IF NOT EXISTS seq AS bigint INCREMENT BY 2 MINVALUE 1 MAXVALUE 100 START WITH 10 CACHE 5 CYCLE OWNED BY users.id"#, + ]); } diff --git a/tests/test_create_server.rs b/tests/test_create_server.rs index d14c5b4..3336c7e 100644 --- a/tests/test_create_server.rs +++ b/tests/test_create_server.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE SERVER +// Description: define a new foreign server +// Syntax: +// CREATE SERVER [ IF NOT EXISTS ] server_name [ TYPE 'server_type' ] [ VERSION 'server_version' ] +// FOREIGN DATA WRAPPER fdw_name +// [ OPTIONS ( option 'value' [, ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createserver.html + #[test] fn create_server_parses() { - run_cases(&["CREATE SERVER my_server FOREIGN DATA WRAPPER my_fdw"]); + run_cases(&[ + r#"CREATE SERVER my_server FOREIGN DATA WRAPPER my_fdw"#, + r#"CREATE SERVER IF NOT EXISTS my_server TYPE 'postgres' VERSION '18' FOREIGN DATA WRAPPER my_fdw OPTIONS (host 'localhost', dbname 'postgres')"#, + ]); } diff --git a/tests/test_create_statistics.rs b/tests/test_create_statistics.rs index 24a9955..5387dab 100644 --- a/tests/test_create_statistics.rs +++ b/tests/test_create_statistics.rs @@ -2,7 +2,24 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE STATISTICS +// Description: define extended statistics +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createstatistics.html + #[test] fn create_statistics_parses() { - run_cases(&["CREATE STATISTICS my_statistics ON a, b FROM my_table"]); + run_cases(&[ + r#"CREATE STATISTICS stats ON id, name FROM users"#, + r#"CREATE STATISTICS IF NOT EXISTS stats (dependencies, ndistinct, mcv) ON id, lower(name) FROM users"#, + ]); } diff --git a/tests/test_create_subscription.rs b/tests/test_create_subscription.rs index 0c418a2..206d9a6 100644 --- a/tests/test_create_subscription.rs +++ b/tests/test_create_subscription.rs @@ -2,9 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE SUBSCRIPTION +// Description: define a new subscription +// Syntax: +// CREATE SUBSCRIPTION subscription_name +// CONNECTION 'conninfo' +// PUBLICATION publication_name [, ...] +// [ WITH ( subscription_parameter [= value] [, ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createsubscription.html + #[test] fn create_subscription_parses() { run_cases(&[ - "CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost' PUBLICATION my_publication", + r#"CREATE SUBSCRIPTION sub CONNECTION 'host=localhost dbname=postgres' PUBLICATION pub"#, + r#"CREATE SUBSCRIPTION sub CONNECTION 'host=localhost dbname=postgres' PUBLICATION pub1, pub2 WITH (copy_data = false, create_slot = false)"#, ]); } diff --git a/tests/test_create_table_as.rs b/tests/test_create_table_as.rs index 15d468b..fd9612d 100644 --- a/tests/test_create_table_as.rs +++ b/tests/test_create_table_as.rs @@ -2,7 +2,24 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TABLE AS +// Description: define a new table from the results of a query +// Syntax: +// CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name +// [ (column_name [, ...] ) ] +// [ USING method ] +// [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] +// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] +// [ TABLESPACE tablespace_name ] +// AS query +// [ WITH [ NO ] DATA ] +// +// URL: https://www.postgresql.org/docs/18/sql-createtableas.html + #[test] fn create_table_as_parses() { - run_cases(&["CREATE TABLE my_table AS SELECT 1 AS id"]); + run_cases(&[ + r#"CREATE TABLE new_table AS SELECT 1 AS id"#, + r#"CREATE TEMP TABLE IF NOT EXISTS new_table (id, name) USING heap WITH (fillfactor = 80) ON COMMIT DROP TABLESPACE fastspace AS SELECT 1 AS id, 'x' AS name WITH NO DATA"#, + ]); } diff --git a/tests/test_create_tablespace.rs b/tests/test_create_tablespace.rs index 90a9e0a..48af316 100644 --- a/tests/test_create_tablespace.rs +++ b/tests/test_create_tablespace.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TABLESPACE +// Description: define a new tablespace +// Syntax: +// CREATE TABLESPACE tablespace_name +// [ OWNER { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ] +// LOCATION 'directory' +// [ WITH ( tablespace_option = value [, ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createtablespace.html + #[test] fn create_tablespace_parses() { - run_cases(&["CREATE TABLESPACE my_tablespace LOCATION '/tmp/my_tablespace'"]); + run_cases(&[ + r#"CREATE TABLESPACE fastspace LOCATION '/tmp/fastspace'"#, + r#"CREATE TABLESPACE fastspace OWNER app_user LOCATION '/tmp/fastspace' WITH (random_page_cost = 1.1)"#, + ]); } diff --git a/tests/test_create_text_search_configuration.rs b/tests/test_create_text_search_configuration.rs index 016d7ac..2d3c19d 100644 --- a/tests/test_create_text_search_configuration.rs +++ b/tests/test_create_text_search_configuration.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TEXT SEARCH CONFIGURATION +// Description: define a new text search configuration +// Syntax: +// CREATE TEXT SEARCH CONFIGURATION name ( +// PARSER = parser_name | +// COPY = source_config +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createtsconfig.html + #[test] fn create_text_search_configuration_parses() { - run_cases(&["CREATE TEXT SEARCH CONFIGURATION my_config (PARSER = default)"]); + run_cases(&[ + r#"CREATE TEXT SEARCH CONFIGURATION my_config (PARSER = default)"#, + r#"CREATE TEXT SEARCH CONFIGURATION my_config (COPY = pg_catalog.english)"#, + ]); } diff --git a/tests/test_create_text_search_dictionary.rs b/tests/test_create_text_search_dictionary.rs index bc298bc..3f193f6 100644 --- a/tests/test_create_text_search_dictionary.rs +++ b/tests/test_create_text_search_dictionary.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TEXT SEARCH DICTIONARY +// Description: define a new text search dictionary +// Syntax: +// CREATE TEXT SEARCH DICTIONARY name ( +// TEMPLATE = template +// [, option = value [, ... ]] +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createtsdictionary.html + #[test] fn create_text_search_dictionary_parses() { - run_cases(&["CREATE TEXT SEARCH DICTIONARY my_dictionary (TEMPLATE = simple)"]); + run_cases(&[ + r#"CREATE TEXT SEARCH DICTIONARY my_dict (TEMPLATE = simple, StopWords = english)"#, + ]); } diff --git a/tests/test_create_text_search_parser.rs b/tests/test_create_text_search_parser.rs index cdbec24..3880d27 100644 --- a/tests/test_create_text_search_parser.rs +++ b/tests/test_create_text_search_parser.rs @@ -2,9 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TEXT SEARCH PARSER +// Description: define a new text search parser +// Syntax: +// CREATE TEXT SEARCH PARSER name ( +// START = start_function , +// GETTOKEN = gettoken_function , +// END = end_function , +// LEXTYPES = lextypes_function +// [, HEADLINE = headline_function ] +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createtsparser.html + #[test] fn create_text_search_parser_parses() { run_cases(&[ - "CREATE TEXT SEARCH PARSER my_parser (START = prsd_start, GETTOKEN = prsd_nexttoken, END = prsd_end, LEXTYPES = prsd_lextype)", + r#"CREATE TEXT SEARCH PARSER my_parser (START = prsd_start, GETTOKEN = prsd_nexttoken, END = prsd_end, LEXTYPES = prsd_lextype, HEADLINE = prsd_headline)"#, ]); } diff --git a/tests/test_create_text_search_template.rs b/tests/test_create_text_search_template.rs index 79ab0ae..c4081eb 100644 --- a/tests/test_create_text_search_template.rs +++ b/tests/test_create_text_search_template.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TEXT SEARCH TEMPLATE +// Description: define a new text search template +// Syntax: +// CREATE TEXT SEARCH TEMPLATE name ( +// [ INIT = init_function , ] +// LEXIZE = lexize_function +// ) +// +// URL: https://www.postgresql.org/docs/18/sql-createtstemplate.html + #[test] fn create_text_search_template_parses() { - run_cases(&["CREATE TEXT SEARCH TEMPLATE my_template (LEXIZE = dsimple_lexize)"]); + run_cases(&[ + r#"CREATE TEXT SEARCH TEMPLATE my_template (INIT = dsimple_init, LEXIZE = dsimple_lexize)"#, + r#"CREATE TEXT SEARCH TEMPLATE my_template (LEXIZE = dsimple_lexize)"#, + ]); } diff --git a/tests/test_create_transform.rs b/tests/test_create_transform.rs index 3bdb51e..9f34b6b 100644 --- a/tests/test_create_transform.rs +++ b/tests/test_create_transform.rs @@ -2,9 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TRANSFORM +// Description: define a new transform +// Syntax: +// 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 [, ...]) ] +// ); +// +// URL: https://www.postgresql.org/docs/18/sql-createtransform.html + #[test] fn create_transform_parses() { run_cases(&[ - "CREATE TRANSFORM FOR integer LANGUAGE plpython3u (FROM SQL WITH FUNCTION from_sql(integer), TO SQL WITH FUNCTION to_sql(integer))", + r#"CREATE TRANSFORM FOR my_type LANGUAGE plsample (FROM SQL WITH FUNCTION my_from_sql(my_type), TO SQL WITH FUNCTION my_to_sql(internal))"#, + r#"CREATE OR REPLACE TRANSFORM FOR my_type LANGUAGE plsample (FROM SQL WITH FUNCTION my_from_sql(my_type))"#, ]); } diff --git a/tests/test_create_trigger.rs b/tests/test_create_trigger.rs index 431901c..dc5d543 100644 --- a/tests/test_create_trigger.rs +++ b/tests/test_create_trigger.rs @@ -2,9 +2,33 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TRIGGER +// Description: define a new trigger +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createtrigger.html + #[test] fn create_trigger_parses() { run_cases(&[ - "CREATE TRIGGER my_trigger BEFORE INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION my_function()", + r#"CREATE TRIGGER trg BEFORE INSERT OR UPDATE OF name ON my_table FOR EACH ROW WHEN (NEW.id > 0) EXECUTE FUNCTION my_function()"#, + r#"CREATE OR REPLACE TRIGGER trg AFTER DELETE ON my_table FOR EACH ROW EXECUTE FUNCTION my_function()"#, + r#"CREATE CONSTRAINT TRIGGER trg AFTER DELETE ON my_table DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION my_function()"#, + r#"CREATE TRIGGER trg AFTER TRUNCATE ON my_table REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE PROCEDURE my_function()"#, ]); } diff --git a/tests/test_create_type.rs b/tests/test_create_type.rs index 1871f96..503091c 100644 --- a/tests/test_create_type.rs +++ b/tests/test_create_type.rs @@ -2,7 +2,57 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE TYPE +// Description: define a new data type +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createtype.html + #[test] fn create_type_parses() { - run_cases(&["CREATE TYPE my_type AS (id integer)"]); + run_cases(&[ + r#"CREATE TYPE address AS (street text COLLATE "C", zip integer)"#, + r#"CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')"#, + r#"CREATE TYPE inventory_item AS RANGE (SUBTYPE = integer, SUBTYPE_OPCLASS = int4_ops, COLLATION = "C", CANONICAL = my_canonical, SUBTYPE_DIFF = my_diff, MULTIRANGE_TYPE_NAME = inventory_item_multirange)"#, + r#"CREATE TYPE shell_type"#, + r#"CREATE TYPE my_base_type (INPUT = my_input, OUTPUT = my_output, RECEIVE = my_receive, SEND = my_send, INTERNALLENGTH = variable, PASSEDBYVALUE, ALIGNMENT = int4, STORAGE = extended, LIKE = integer, CATEGORY = 'U', PREFERRED = true, DEFAULT = '0', ELEMENT = integer, DELIMITER = ',', COLLATABLE = true)"#, + ]); } diff --git a/tests/test_create_user.rs b/tests/test_create_user.rs index 9449cc2..291230d 100644 --- a/tests/test_create_user.rs +++ b/tests/test_create_user.rs @@ -2,7 +2,36 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE USER +// Description: define a new database role +// Syntax: +// 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 +// +// URL: https://www.postgresql.org/docs/18/sql-createuser.html + #[test] fn create_user_parses() { - run_cases(&["CREATE USER my_user"]); + run_cases(&[ + r#"CREATE USER app_user"#, + r#"CREATE USER app_user WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 5 PASSWORD 'secret' VALID UNTIL 'infinity' IN ROLE parent_role ROLE child_role ADMIN admin_role USER legacy_user SYSID 10"#, + ]); } diff --git a/tests/test_create_user_mapping.rs b/tests/test_create_user_mapping.rs index e53b51e..f1f22c8 100644 --- a/tests/test_create_user_mapping.rs +++ b/tests/test_create_user_mapping.rs @@ -2,7 +2,20 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE USER MAPPING +// Description: define a new mapping of a user to a foreign server +// Syntax: +// CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } +// SERVER server_name +// [ OPTIONS ( option 'value' [ , ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-createusermapping.html + #[test] fn create_user_mapping_parses() { - run_cases(&["CREATE USER MAPPING FOR my_user SERVER my_server OPTIONS (user 'remote_user')"]); + run_cases(&[ + r#"CREATE USER MAPPING FOR app_user SERVER my_server OPTIONS (user 'remote', password 'secret')"#, + r#"CREATE USER MAPPING IF NOT EXISTS FOR CURRENT_USER SERVER my_server OPTIONS (user 'current')"#, + r#"CREATE USER MAPPING FOR PUBLIC SERVER my_server"#, + ]); } diff --git a/tests/test_create_view.rs b/tests/test_create_view.rs index 73a1ef5..b8b8926 100644 --- a/tests/test_create_view.rs +++ b/tests/test_create_view.rs @@ -2,7 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: CREATE VIEW +// Description: define a new view +// Syntax: +// CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW name [ ( column_name [, ...] ) ] +// [ WITH ( view_option_name [= view_option_value] [, ... ] ) ] +// AS query +// [ WITH [ CASCADED | LOCAL ] CHECK OPTION ] +// +// URL: https://www.postgresql.org/docs/18/sql-createview.html + #[test] fn create_view_parses() { - run_cases(&["CREATE VIEW my_view AS SELECT 1 AS id"]); + run_cases(&[ + r#"CREATE VIEW v AS SELECT 1 AS col"#, + r#"CREATE OR REPLACE TEMP RECURSIVE VIEW v (col) WITH (security_barrier = true, check_option = local) AS SELECT 1 AS col"#, + r#"CREATE OR REPLACE TEMP VIEW v (col) WITH (security_barrier = true) AS SELECT 1 AS col WITH LOCAL CHECK OPTION"#, + r#"CREATE VIEW v AS SELECT 1 AS col WITH CASCADED CHECK OPTION"#, + ]); } diff --git a/tests/test_delete_grammar.rs b/tests/test_delete_grammar.rs index 68903ae..438d27a 100644 --- a/tests/test_delete_grammar.rs +++ b/tests/test_delete_grammar.rs @@ -52,12 +52,20 @@ fn delete_returning_variations() { "DELETE FROM users RETURNING *", "DELETE FROM users RETURNING id", "DELETE FROM users RETURNING id AS deleted_id, email old_email", + "DELETE FROM users RETURNING WITH (OLD AS old_row) old_row.id", + "DELETE FROM users RETURNING WITH (NEW AS new_row) new_row.id", + "DELETE FROM users RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.id AS old_id, new_row.id AS new_id", ]); } +// Command: DELETE +// Description: delete rows of a table +// Syntax: // [ WITH [ RECURSIVE ] with_query [, ...] ] // DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] // [ USING from_item [, ...] ] // [ WHERE condition | WHERE CURRENT OF cursor_name ] // [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] // { * | output_expression [ [ AS ] output_name ] } [, ...] ] +// +// URL: https://www.postgresql.org/docs/18/sql-delete.html diff --git a/tests/test_drop.rs b/tests/test_drop.rs index a943a0b..2dc610f 100644 --- a/tests/test_drop.rs +++ b/tests/test_drop.rs @@ -2,12 +2,324 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP ACCESS METHOD +// Description: remove an access method +// Syntax: +// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-drop-access-method.html +// +// Command: DROP AGGREGATE +// Description: remove an aggregate function +// Syntax: +// DROP AGGREGATE [ IF EXISTS ] name ( aggregate_signature ) [, ...] [ CASCADE | RESTRICT ] +// +// where aggregate_signature is: +// +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropaggregate.html +// +// Command: DROP CAST +// Description: remove a cast +// Syntax: +// DROP CAST [ IF EXISTS ] (source_type AS target_type) [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropcast.html +// +// Command: DROP COLLATION +// Description: remove a collation +// Syntax: +// DROP COLLATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropcollation.html +// +// Command: DROP CONVERSION +// Description: remove a conversion +// Syntax: +// DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropconversion.html +// +// Command: DROP DATABASE +// Description: remove a database +// Syntax: +// DROP DATABASE [ IF EXISTS ] name [ [ WITH ] ( option [, ...] ) ] +// +// where option can be: +// +// FORCE +// +// URL: https://www.postgresql.org/docs/18/sql-dropdatabase.html +// +// Command: DROP DOMAIN +// Description: remove a domain +// Syntax: +// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropdomain.html +// +// Command: DROP EVENT TRIGGER +// Description: remove an event trigger +// Syntax: +// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropeventtrigger.html +// +// Command: DROP EXTENSION +// Description: remove an extension +// Syntax: +// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropextension.html +// +// Command: DROP FOREIGN DATA WRAPPER +// Description: remove a foreign-data wrapper +// Syntax: +// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropforeigndatawrapper.html +// +// Command: DROP FOREIGN TABLE +// Description: remove a foreign table +// Syntax: +// DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropforeigntable.html +// +// Command: DROP FUNCTION +// Description: remove a function +// Syntax: +// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropfunction.html +// +// Command: DROP GROUP +// Description: remove a database role +// Syntax: +// DROP GROUP [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-dropgroup.html +// +// Command: DROP INDEX +// Description: remove an index +// Syntax: +// DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropindex.html +// +// Command: DROP LANGUAGE +// Description: remove a procedural language +// Syntax: +// DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droplanguage.html +// +// Command: DROP MATERIALIZED VIEW +// Description: remove a materialized view +// Syntax: +// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropmaterializedview.html +// +// Command: DROP OPERATOR +// Description: remove an operator +// Syntax: +// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropoperator.html +// +// Command: DROP OPERATOR CLASS +// Description: remove an operator class +// Syntax: +// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropopclass.html +// +// Command: DROP OPERATOR FAMILY +// Description: remove an operator family +// Syntax: +// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropopfamily.html +// +// Command: DROP OWNED +// Description: remove database objects owned by a database role +// Syntax: +// DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-drop-owned.html +// +// Command: DROP POLICY +// Description: remove a row-level security policy from a table +// Syntax: +// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droppolicy.html +// +// Command: DROP PROCEDURE +// Description: remove a procedure +// Syntax: +// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropprocedure.html +// +// Command: DROP PUBLICATION +// Description: remove a publication +// Syntax: +// DROP PUBLICATION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droppublication.html +// +// Command: DROP ROLE +// Description: remove a database role +// Syntax: +// DROP ROLE [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-droprole.html +// +// Command: DROP ROUTINE +// Description: remove a routine +// Syntax: +// DROP ROUTINE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droproutine.html +// +// Command: DROP RULE +// Description: remove a rewrite rule +// Syntax: +// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droprule.html +// +// Command: DROP SCHEMA +// Description: remove a schema +// Syntax: +// DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropschema.html +// +// Command: DROP SEQUENCE +// Description: remove a sequence +// Syntax: +// DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropsequence.html +// +// Command: DROP SERVER +// Description: remove a foreign server descriptor +// Syntax: +// DROP SERVER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropserver.html +// +// Command: DROP STATISTICS +// Description: remove extended statistics +// Syntax: +// DROP STATISTICS [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropstatistics.html +// +// Command: DROP SUBSCRIPTION +// Description: remove a subscription +// Syntax: +// DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropsubscription.html +// +// Command: DROP TABLE +// Description: remove a table +// Syntax: +// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptable.html +// +// Command: DROP TABLESPACE +// Description: remove a tablespace +// Syntax: +// DROP TABLESPACE [ IF EXISTS ] name +// +// URL: https://www.postgresql.org/docs/18/sql-droptablespace.html +// +// Command: DROP TEXT SEARCH CONFIGURATION +// Description: remove a text search configuration +// Syntax: +// DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsconfig.html +// +// Command: DROP TEXT SEARCH DICTIONARY +// Description: remove a text search dictionary +// Syntax: +// DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsdictionary.html +// +// Command: DROP TEXT SEARCH PARSER +// Description: remove a text search parser +// Syntax: +// DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsparser.html +// +// Command: DROP TEXT SEARCH TEMPLATE +// Description: remove a text search template +// Syntax: +// DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptstemplate.html +// +// Command: DROP TRANSFORM +// Description: remove a transform +// Syntax: +// DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptransform.html +// +// Command: DROP TRIGGER +// Description: remove a trigger +// Syntax: +// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptrigger.html +// +// Command: DROP TYPE +// Description: remove a data type +// Syntax: +// DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptype.html +// +// Command: DROP USER +// Description: remove a database role +// Syntax: +// DROP USER [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-dropuser.html +// +// Command: DROP USER MAPPING +// Description: remove a user mapping for a foreign server +// Syntax: +// DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name +// +// URL: https://www.postgresql.org/docs/18/sql-dropusermapping.html +// +// Command: DROP VIEW +// Description: remove a view +// Syntax: +// DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropview.html + #[test] fn drop_parses() { run_cases(&[ - "DROP TABLE IF EXISTS my_table", - "DROP TABLE IF EXISTS my_table, other_table CASCADE", + r#"DROP TABLE IF EXISTS my_table"#, + r#"DROP TABLE IF EXISTS my_table, other_table CASCADE"#, ]); } - -// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] diff --git a/tests/test_drop_access_method.rs b/tests/test_drop_access_method.rs index 1864c44..ac7e943 100644 --- a/tests/test_drop_access_method.rs +++ b/tests/test_drop_access_method.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP ACCESS METHOD +// Description: remove an access method +// Syntax: +// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-drop-access-method.html + #[test] fn drop_access_method_parses() { - run_cases(&["DROP ACCESS METHOD IF EXISTS my_am"]); + run_cases(&[ + r#"DROP ACCESS METHOD my_am"#, + r#"DROP ACCESS METHOD IF EXISTS my_am CASCADE"#, + ]); } diff --git a/tests/test_drop_aggregate.rs b/tests/test_drop_aggregate.rs index dd61feb..d81bd6e 100644 --- a/tests/test_drop_aggregate.rs +++ b/tests/test_drop_aggregate.rs @@ -2,7 +2,23 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP AGGREGATE +// Description: remove an aggregate function +// Syntax: +// DROP AGGREGATE [ IF EXISTS ] name ( aggregate_signature ) [, ...] [ CASCADE | RESTRICT ] +// +// where aggregate_signature is: +// +// * | +// [ argmode ] [ argname ] argtype [ , ... ] | +// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropaggregate.html + #[test] fn drop_aggregate_parses() { - run_cases(&["DROP AGGREGATE IF EXISTS my_aggregate(integer)"]); + run_cases(&[ + r#"DROP AGGREGATE my_sum(integer)"#, + r#"DROP AGGREGATE IF EXISTS my_sum(integer), my_sum(bigint) CASCADE"#, + ]); } diff --git a/tests/test_drop_cast.rs b/tests/test_drop_cast.rs index b820681..10754ec 100644 --- a/tests/test_drop_cast.rs +++ b/tests/test_drop_cast.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP CAST +// Description: remove a cast +// Syntax: +// DROP CAST [ IF EXISTS ] (source_type AS target_type) [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropcast.html + #[test] fn drop_cast_parses() { - run_cases(&["DROP CAST IF EXISTS (integer AS bigint)"]); + run_cases(&[ + r#"DROP CAST (integer AS bigint)"#, + r#"DROP CAST IF EXISTS (integer AS bigint) CASCADE"#, + ]); } diff --git a/tests/test_drop_collation.rs b/tests/test_drop_collation.rs index 3e98d4e..23257ae 100644 --- a/tests/test_drop_collation.rs +++ b/tests/test_drop_collation.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP COLLATION +// Description: remove a collation +// Syntax: +// DROP COLLATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropcollation.html + #[test] fn drop_collation_parses() { - run_cases(&["DROP COLLATION IF EXISTS my_collation"]); + run_cases(&[ + r#"DROP COLLATION my_collation"#, + r#"DROP COLLATION IF EXISTS my_collation, my_collation_old CASCADE"#, + r#"DROP COLLATION IF EXISTS my_collation RESTRICT"#, + ]); } diff --git a/tests/test_drop_conversion.rs b/tests/test_drop_conversion.rs index 97ee626..2fd4612 100644 --- a/tests/test_drop_conversion.rs +++ b/tests/test_drop_conversion.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP CONVERSION +// Description: remove a conversion +// Syntax: +// DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropconversion.html + #[test] fn drop_conversion_parses() { - run_cases(&["DROP CONVERSION IF EXISTS my_conversion"]); + run_cases(&[ + r#"DROP CONVERSION my_conversion"#, + r#"DROP CONVERSION IF EXISTS my_conversion, my_conversion_old CASCADE"#, + r#"DROP CONVERSION IF EXISTS my_conversion RESTRICT"#, + ]); } diff --git a/tests/test_drop_database.rs b/tests/test_drop_database.rs index 4d246ad..351925b 100644 --- a/tests/test_drop_database.rs +++ b/tests/test_drop_database.rs @@ -2,7 +2,21 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP DATABASE +// Description: remove a database +// Syntax: +// DROP DATABASE [ IF EXISTS ] name [ [ WITH ] ( option [, ...] ) ] +// +// where option can be: +// +// FORCE +// +// URL: https://www.postgresql.org/docs/18/sql-dropdatabase.html + #[test] fn drop_database_parses() { - run_cases(&["DROP DATABASE IF EXISTS my_database"]); + run_cases(&[ + r#"DROP DATABASE mydb"#, + r#"DROP DATABASE IF EXISTS mydb WITH (FORCE)"#, + ]); } diff --git a/tests/test_drop_domain.rs b/tests/test_drop_domain.rs index 137ae5e..3162ceb 100644 --- a/tests/test_drop_domain.rs +++ b/tests/test_drop_domain.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP DOMAIN +// Description: remove a domain +// Syntax: +// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropdomain.html + #[test] fn drop_domain_parses() { - run_cases(&["DROP DOMAIN IF EXISTS my_domain"]); + run_cases(&[ + r#"DROP DOMAIN email_domain"#, + r#"DROP DOMAIN IF EXISTS email_domain, email_domain_old CASCADE"#, + r#"DROP DOMAIN IF EXISTS email_domain RESTRICT"#, + ]); } diff --git a/tests/test_drop_event_trigger.rs b/tests/test_drop_event_trigger.rs index adedd0c..832662b 100644 --- a/tests/test_drop_event_trigger.rs +++ b/tests/test_drop_event_trigger.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP EVENT TRIGGER +// Description: remove an event trigger +// Syntax: +// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropeventtrigger.html + #[test] fn drop_event_trigger_parses() { - run_cases(&["DROP EVENT TRIGGER IF EXISTS my_event_trigger"]); + run_cases(&[ + r#"DROP EVENT TRIGGER trg"#, + r#"DROP EVENT TRIGGER IF EXISTS trg CASCADE"#, + ]); } diff --git a/tests/test_drop_extension.rs b/tests/test_drop_extension.rs index f658991..b003c22 100644 --- a/tests/test_drop_extension.rs +++ b/tests/test_drop_extension.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP EXTENSION +// Description: remove an extension +// Syntax: +// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropextension.html + #[test] fn drop_extension_parses() { - run_cases(&["DROP EXTENSION IF EXISTS hstore"]); + run_cases(&[ + r#"DROP EXTENSION hstore"#, + r#"DROP EXTENSION IF EXISTS hstore, hstore_old CASCADE"#, + r#"DROP EXTENSION IF EXISTS hstore RESTRICT"#, + ]); } diff --git a/tests/test_drop_foreign_data_wrapper.rs b/tests/test_drop_foreign_data_wrapper.rs index cdc43ac..546de5b 100644 --- a/tests/test_drop_foreign_data_wrapper.rs +++ b/tests/test_drop_foreign_data_wrapper.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP FOREIGN DATA WRAPPER +// Description: remove a foreign-data wrapper +// Syntax: +// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropforeigndatawrapper.html + #[test] fn drop_foreign_data_wrapper_parses() { - run_cases(&["DROP FOREIGN DATA WRAPPER IF EXISTS my_fdw"]); + run_cases(&[ + r#"DROP FOREIGN DATA WRAPPER my_fdw"#, + r#"DROP FOREIGN DATA WRAPPER IF EXISTS my_fdw, my_fdw_old CASCADE"#, + r#"DROP FOREIGN DATA WRAPPER IF EXISTS my_fdw RESTRICT"#, + ]); } diff --git a/tests/test_drop_foreign_table.rs b/tests/test_drop_foreign_table.rs index 5029114..883279a 100644 --- a/tests/test_drop_foreign_table.rs +++ b/tests/test_drop_foreign_table.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP FOREIGN TABLE +// Description: remove a foreign table +// Syntax: +// DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropforeigntable.html + #[test] fn drop_foreign_table_parses() { - run_cases(&["DROP FOREIGN TABLE IF EXISTS my_foreign_table"]); + run_cases(&[ + r#"DROP FOREIGN TABLE ft"#, + r#"DROP FOREIGN TABLE IF EXISTS ft, ft_old CASCADE"#, + r#"DROP FOREIGN TABLE IF EXISTS ft RESTRICT"#, + ]); } diff --git a/tests/test_drop_function.rs b/tests/test_drop_function.rs index 2d7270b..8e859de 100644 --- a/tests/test_drop_function.rs +++ b/tests/test_drop_function.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP FUNCTION +// Description: remove a function +// Syntax: +// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropfunction.html + #[test] fn drop_function_parses() { - run_cases(&["DROP FUNCTION IF EXISTS my_function(integer)"]); + run_cases(&[ + r#"DROP FUNCTION my_function(integer)"#, + r#"DROP FUNCTION IF EXISTS my_function(integer), my_function(text) CASCADE"#, + ]); } diff --git a/tests/test_drop_group.rs b/tests/test_drop_group.rs index cbcd06b..068b22c 100644 --- a/tests/test_drop_group.rs +++ b/tests/test_drop_group.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP GROUP +// Description: remove a database role +// Syntax: +// DROP GROUP [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-dropgroup.html + #[test] fn drop_group_parses() { - run_cases(&["DROP GROUP IF EXISTS my_group"]); + run_cases(&[ + r#"DROP GROUP my_group"#, + r#"DROP GROUP IF EXISTS my_group, my_group_old"#, + ]); } diff --git a/tests/test_drop_index.rs b/tests/test_drop_index.rs index 2e0e2fd..0f5fa5c 100644 --- a/tests/test_drop_index.rs +++ b/tests/test_drop_index.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP INDEX +// Description: remove an index +// Syntax: +// DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropindex.html + #[test] fn drop_index_parses() { - run_cases(&["DROP INDEX IF EXISTS my_index"]); + run_cases(&[ + r#"DROP INDEX my_index"#, + r#"DROP INDEX IF EXISTS my_index, my_index_old CASCADE"#, + r#"DROP INDEX IF EXISTS my_index RESTRICT"#, + ]); } diff --git a/tests/test_drop_language.rs b/tests/test_drop_language.rs index 12344b0..1d626dd 100644 --- a/tests/test_drop_language.rs +++ b/tests/test_drop_language.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP LANGUAGE +// Description: remove a procedural language +// Syntax: +// DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droplanguage.html + #[test] fn drop_language_parses() { - run_cases(&["DROP LANGUAGE IF EXISTS my_language"]); + run_cases(&[ + r#"DROP LANGUAGE plsample"#, + r#"DROP LANGUAGE IF EXISTS plsample, plsample_old CASCADE"#, + r#"DROP LANGUAGE IF EXISTS plsample RESTRICT"#, + ]); } diff --git a/tests/test_drop_materialized_view.rs b/tests/test_drop_materialized_view.rs index 7a25d09..40be3cc 100644 --- a/tests/test_drop_materialized_view.rs +++ b/tests/test_drop_materialized_view.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP MATERIALIZED VIEW +// Description: remove a materialized view +// Syntax: +// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropmaterializedview.html + #[test] fn drop_materialized_view_parses() { - run_cases(&["DROP MATERIALIZED VIEW IF EXISTS my_matview"]); + run_cases(&[ + r#"DROP MATERIALIZED VIEW mv"#, + r#"DROP MATERIALIZED VIEW IF EXISTS mv, mv_old CASCADE"#, + r#"DROP MATERIALIZED VIEW IF EXISTS mv RESTRICT"#, + ]); } diff --git a/tests/test_drop_operator.rs b/tests/test_drop_operator.rs index a3c5dce..be30ac4 100644 --- a/tests/test_drop_operator.rs +++ b/tests/test_drop_operator.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP OPERATOR +// Description: remove an operator +// Syntax: +// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropoperator.html + #[test] fn drop_operator_parses() { - run_cases(&["DROP OPERATOR IF EXISTS + (integer, integer)"]); + run_cases(&[ + r#"DROP OPERATOR +(integer, integer)"#, + r#"DROP OPERATOR IF EXISTS +(integer, integer), -(integer, integer) CASCADE"#, + ]); } diff --git a/tests/test_drop_operator_class.rs b/tests/test_drop_operator_class.rs index 4b0316d..8a75ded 100644 --- a/tests/test_drop_operator_class.rs +++ b/tests/test_drop_operator_class.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP OPERATOR CLASS +// Description: remove an operator class +// Syntax: +// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropopclass.html + #[test] fn drop_operator_class_parses() { - run_cases(&["DROP OPERATOR CLASS IF EXISTS my_opclass USING btree"]); + run_cases(&[ + r#"DROP OPERATOR CLASS my_opclass USING btree"#, + r#"DROP OPERATOR CLASS IF EXISTS my_opclass USING btree CASCADE"#, + r#"DROP OPERATOR CLASS IF EXISTS my_opclass USING btree RESTRICT"#, + ]); } diff --git a/tests/test_drop_operator_family.rs b/tests/test_drop_operator_family.rs index 77abcda..bf6f23e 100644 --- a/tests/test_drop_operator_family.rs +++ b/tests/test_drop_operator_family.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP OPERATOR FAMILY +// Description: remove an operator family +// Syntax: +// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropopfamily.html + #[test] fn drop_operator_family_parses() { - run_cases(&["DROP OPERATOR FAMILY IF EXISTS my_opfamily USING btree"]); + run_cases(&[ + r#"DROP OPERATOR FAMILY my_family USING btree"#, + r#"DROP OPERATOR FAMILY IF EXISTS my_family USING btree CASCADE"#, + r#"DROP OPERATOR FAMILY IF EXISTS my_family USING btree RESTRICT"#, + ]); } diff --git a/tests/test_drop_owned.rs b/tests/test_drop_owned.rs index a65b1c9..435375c 100644 --- a/tests/test_drop_owned.rs +++ b/tests/test_drop_owned.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP OWNED +// Description: remove database objects owned by a database role +// Syntax: +// DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-drop-owned.html + #[test] fn drop_owned_parses() { - run_cases(&["DROP OWNED BY my_role"]); + run_cases(&[ + r#"DROP OWNED BY app_user"#, + r#"DROP OWNED BY app_user, other_user CASCADE"#, + ]); } diff --git a/tests/test_drop_policy.rs b/tests/test_drop_policy.rs index be94d5d..043b5ca 100644 --- a/tests/test_drop_policy.rs +++ b/tests/test_drop_policy.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP POLICY +// Description: remove a row-level security policy from a table +// Syntax: +// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droppolicy.html + #[test] fn drop_policy_parses() { - run_cases(&["DROP POLICY IF EXISTS my_policy ON my_table"]); + run_cases(&[ + r#"DROP POLICY pol ON my_table"#, + r#"DROP POLICY IF EXISTS pol ON my_table"#, + ]); } diff --git a/tests/test_drop_procedure.rs b/tests/test_drop_procedure.rs index 9bbfe73..09f9490 100644 --- a/tests/test_drop_procedure.rs +++ b/tests/test_drop_procedure.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP PROCEDURE +// Description: remove a procedure +// Syntax: +// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropprocedure.html + #[test] fn drop_procedure_parses() { - run_cases(&["DROP PROCEDURE IF EXISTS my_procedure(integer)"]); + run_cases(&[ + r#"DROP PROCEDURE my_proc(integer)"#, + r#"DROP PROCEDURE IF EXISTS my_proc(integer), my_proc(text) CASCADE"#, + ]); } diff --git a/tests/test_drop_publication.rs b/tests/test_drop_publication.rs index fa80bc4..996a4d1 100644 --- a/tests/test_drop_publication.rs +++ b/tests/test_drop_publication.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP PUBLICATION +// Description: remove a publication +// Syntax: +// DROP PUBLICATION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droppublication.html + #[test] fn drop_publication_parses() { - run_cases(&["DROP PUBLICATION IF EXISTS my_publication"]); + run_cases(&[ + r#"DROP PUBLICATION pub"#, + r#"DROP PUBLICATION IF EXISTS pub, pub_old CASCADE"#, + r#"DROP PUBLICATION IF EXISTS pub RESTRICT"#, + ]); } diff --git a/tests/test_drop_role.rs b/tests/test_drop_role.rs index 514bd21..51f509e 100644 --- a/tests/test_drop_role.rs +++ b/tests/test_drop_role.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP ROLE +// Description: remove a database role +// Syntax: +// DROP ROLE [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-droprole.html + #[test] fn drop_role_parses() { - run_cases(&["DROP ROLE IF EXISTS my_role"]); + run_cases(&[ + r#"DROP ROLE app_user"#, + r#"DROP ROLE IF EXISTS app_user, app_user_old"#, + ]); } diff --git a/tests/test_drop_routine.rs b/tests/test_drop_routine.rs index c19b47d..afca9c7 100644 --- a/tests/test_drop_routine.rs +++ b/tests/test_drop_routine.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP ROUTINE +// Description: remove a routine +// Syntax: +// DROP ROUTINE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] +// [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droproutine.html + #[test] fn drop_routine_parses() { - run_cases(&["DROP ROUTINE IF EXISTS my_routine(integer)"]); + run_cases(&[ + r#"DROP ROUTINE my_function(integer)"#, + r#"DROP ROUTINE IF EXISTS my_function(integer), my_proc(text) CASCADE"#, + ]); } diff --git a/tests/test_drop_rule.rs b/tests/test_drop_rule.rs index 4c47802..a743ef9 100644 --- a/tests/test_drop_rule.rs +++ b/tests/test_drop_rule.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP RULE +// Description: remove a rewrite rule +// Syntax: +// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droprule.html + #[test] fn drop_rule_parses() { - run_cases(&["DROP RULE IF EXISTS my_rule ON my_table"]); + run_cases(&[ + r#"DROP RULE my_rule ON my_table"#, + r#"DROP RULE IF EXISTS my_rule ON my_table CASCADE"#, + r#"DROP RULE IF EXISTS my_rule ON my_table RESTRICT"#, + ]); } diff --git a/tests/test_drop_schema.rs b/tests/test_drop_schema.rs index a05a447..aa3b2cd 100644 --- a/tests/test_drop_schema.rs +++ b/tests/test_drop_schema.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP SCHEMA +// Description: remove a schema +// Syntax: +// DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropschema.html + #[test] fn drop_schema_parses() { - run_cases(&["DROP SCHEMA IF EXISTS my_schema"]); + run_cases(&[ + r#"DROP SCHEMA my_schema"#, + r#"DROP SCHEMA IF EXISTS my_schema, my_schema_old CASCADE"#, + r#"DROP SCHEMA IF EXISTS my_schema RESTRICT"#, + ]); } diff --git a/tests/test_drop_sequence.rs b/tests/test_drop_sequence.rs index 949a91f..a993bec 100644 --- a/tests/test_drop_sequence.rs +++ b/tests/test_drop_sequence.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP SEQUENCE +// Description: remove a sequence +// Syntax: +// DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropsequence.html + #[test] fn drop_sequence_parses() { - run_cases(&["DROP SEQUENCE IF EXISTS my_sequence"]); + run_cases(&[ + r#"DROP SEQUENCE seq"#, + r#"DROP SEQUENCE IF EXISTS seq, seq_old CASCADE"#, + r#"DROP SEQUENCE IF EXISTS seq RESTRICT"#, + ]); } diff --git a/tests/test_drop_server.rs b/tests/test_drop_server.rs index 652376b..7d9d12d 100644 --- a/tests/test_drop_server.rs +++ b/tests/test_drop_server.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP SERVER +// Description: remove a foreign server descriptor +// Syntax: +// DROP SERVER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropserver.html + #[test] fn drop_server_parses() { - run_cases(&["DROP SERVER IF EXISTS my_server"]); + run_cases(&[ + r#"DROP SERVER my_server"#, + r#"DROP SERVER IF EXISTS my_server, my_server_old CASCADE"#, + r#"DROP SERVER IF EXISTS my_server RESTRICT"#, + ]); } diff --git a/tests/test_drop_statistics.rs b/tests/test_drop_statistics.rs index cd003f2..cbee752 100644 --- a/tests/test_drop_statistics.rs +++ b/tests/test_drop_statistics.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP STATISTICS +// Description: remove extended statistics +// Syntax: +// DROP STATISTICS [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropstatistics.html + #[test] fn drop_statistics_parses() { - run_cases(&["DROP STATISTICS IF EXISTS my_statistics"]); + run_cases(&[ + r#"DROP STATISTICS stats"#, + r#"DROP STATISTICS IF EXISTS stats, stats_old CASCADE"#, + r#"DROP STATISTICS IF EXISTS stats RESTRICT"#, + ]); } diff --git a/tests/test_drop_subscription.rs b/tests/test_drop_subscription.rs index b0bee6a..d31b5a3 100644 --- a/tests/test_drop_subscription.rs +++ b/tests/test_drop_subscription.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP SUBSCRIPTION +// Description: remove a subscription +// Syntax: +// DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropsubscription.html + #[test] fn drop_subscription_parses() { - run_cases(&["DROP SUBSCRIPTION IF EXISTS my_subscription"]); + run_cases(&[ + r#"DROP SUBSCRIPTION sub"#, + r#"DROP SUBSCRIPTION IF EXISTS sub CASCADE"#, + r#"DROP SUBSCRIPTION IF EXISTS sub RESTRICT"#, + ]); } diff --git a/tests/test_drop_table.rs b/tests/test_drop_table.rs index e6b68dc..d9f63ec 100644 --- a/tests/test_drop_table.rs +++ b/tests/test_drop_table.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TABLE +// Description: remove a table +// Syntax: +// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptable.html + #[test] fn drop_table_parses() { - run_cases(&["DROP TABLE IF EXISTS my_table"]); + run_cases(&[ + r#"DROP TABLE my_table"#, + r#"DROP TABLE IF EXISTS my_table, my_table_old CASCADE"#, + r#"DROP TABLE IF EXISTS my_table RESTRICT"#, + ]); } diff --git a/tests/test_drop_tablespace.rs b/tests/test_drop_tablespace.rs index b7c71cc..1fcb4e4 100644 --- a/tests/test_drop_tablespace.rs +++ b/tests/test_drop_tablespace.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TABLESPACE +// Description: remove a tablespace +// Syntax: +// DROP TABLESPACE [ IF EXISTS ] name +// +// URL: https://www.postgresql.org/docs/18/sql-droptablespace.html + #[test] fn drop_tablespace_parses() { - run_cases(&["DROP TABLESPACE IF EXISTS my_tablespace"]); + run_cases(&[ + r#"DROP TABLESPACE fastspace"#, + r#"DROP TABLESPACE IF EXISTS fastspace"#, + ]); } diff --git a/tests/test_drop_text_search_configuration.rs b/tests/test_drop_text_search_configuration.rs index c45807b..cbdb401 100644 --- a/tests/test_drop_text_search_configuration.rs +++ b/tests/test_drop_text_search_configuration.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TEXT SEARCH CONFIGURATION +// Description: remove a text search configuration +// Syntax: +// DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsconfig.html + #[test] fn drop_text_search_configuration_parses() { - run_cases(&["DROP TEXT SEARCH CONFIGURATION IF EXISTS my_config"]); + run_cases(&[ + r#"DROP TEXT SEARCH CONFIGURATION my_config"#, + r#"DROP TEXT SEARCH CONFIGURATION IF EXISTS my_config, my_config_old CASCADE"#, + r#"DROP TEXT SEARCH CONFIGURATION IF EXISTS my_config RESTRICT"#, + ]); } diff --git a/tests/test_drop_text_search_dictionary.rs b/tests/test_drop_text_search_dictionary.rs index 5fdcfdd..f60e817 100644 --- a/tests/test_drop_text_search_dictionary.rs +++ b/tests/test_drop_text_search_dictionary.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TEXT SEARCH DICTIONARY +// Description: remove a text search dictionary +// Syntax: +// DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsdictionary.html + #[test] fn drop_text_search_dictionary_parses() { - run_cases(&["DROP TEXT SEARCH DICTIONARY IF EXISTS my_dictionary"]); + run_cases(&[ + r#"DROP TEXT SEARCH DICTIONARY my_dict"#, + r#"DROP TEXT SEARCH DICTIONARY IF EXISTS my_dict, my_dict_old CASCADE"#, + r#"DROP TEXT SEARCH DICTIONARY IF EXISTS my_dict RESTRICT"#, + ]); } diff --git a/tests/test_drop_text_search_parser.rs b/tests/test_drop_text_search_parser.rs index aac85f4..2d312a7 100644 --- a/tests/test_drop_text_search_parser.rs +++ b/tests/test_drop_text_search_parser.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TEXT SEARCH PARSER +// Description: remove a text search parser +// Syntax: +// DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptsparser.html + #[test] fn drop_text_search_parser_parses() { - run_cases(&["DROP TEXT SEARCH PARSER IF EXISTS my_parser"]); + run_cases(&[ + r#"DROP TEXT SEARCH PARSER my_parser"#, + r#"DROP TEXT SEARCH PARSER IF EXISTS my_parser, my_parser_old CASCADE"#, + r#"DROP TEXT SEARCH PARSER IF EXISTS my_parser RESTRICT"#, + ]); } diff --git a/tests/test_drop_text_search_template.rs b/tests/test_drop_text_search_template.rs index 15b10c4..729a5e4 100644 --- a/tests/test_drop_text_search_template.rs +++ b/tests/test_drop_text_search_template.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TEXT SEARCH TEMPLATE +// Description: remove a text search template +// Syntax: +// DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptstemplate.html + #[test] fn drop_text_search_template_parses() { - run_cases(&["DROP TEXT SEARCH TEMPLATE IF EXISTS my_template"]); + run_cases(&[ + r#"DROP TEXT SEARCH TEMPLATE my_template"#, + r#"DROP TEXT SEARCH TEMPLATE IF EXISTS my_template, my_template_old CASCADE"#, + r#"DROP TEXT SEARCH TEMPLATE IF EXISTS my_template RESTRICT"#, + ]); } diff --git a/tests/test_drop_transform.rs b/tests/test_drop_transform.rs index 8fea2b7..5684097 100644 --- a/tests/test_drop_transform.rs +++ b/tests/test_drop_transform.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TRANSFORM +// Description: remove a transform +// Syntax: +// DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptransform.html + #[test] fn drop_transform_parses() { - run_cases(&["DROP TRANSFORM IF EXISTS FOR integer LANGUAGE plpython3u"]); + run_cases(&[ + r#"DROP TRANSFORM FOR my_type LANGUAGE plsample"#, + r#"DROP TRANSFORM IF EXISTS FOR my_type LANGUAGE plsample CASCADE"#, + ]); } diff --git a/tests/test_drop_trigger.rs b/tests/test_drop_trigger.rs index a04718c..88a37d1 100644 --- a/tests/test_drop_trigger.rs +++ b/tests/test_drop_trigger.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TRIGGER +// Description: remove a trigger +// Syntax: +// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptrigger.html + #[test] fn drop_trigger_parses() { - run_cases(&["DROP TRIGGER IF EXISTS my_trigger ON my_table"]); + run_cases(&[ + r#"DROP TRIGGER trg ON my_table"#, + r#"DROP TRIGGER IF EXISTS trg ON my_table CASCADE"#, + ]); } diff --git a/tests/test_drop_type.rs b/tests/test_drop_type.rs index 220b9d2..32904da 100644 --- a/tests/test_drop_type.rs +++ b/tests/test_drop_type.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP TYPE +// Description: remove a data type +// Syntax: +// DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-droptype.html + #[test] fn drop_type_parses() { - run_cases(&["DROP TYPE IF EXISTS my_type"]); + run_cases(&[ + r#"DROP TYPE my_type"#, + r#"DROP TYPE IF EXISTS my_type, my_type_old CASCADE"#, + r#"DROP TYPE IF EXISTS my_type RESTRICT"#, + ]); } diff --git a/tests/test_drop_user.rs b/tests/test_drop_user.rs index 5aab0de..471806d 100644 --- a/tests/test_drop_user.rs +++ b/tests/test_drop_user.rs @@ -2,7 +2,17 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP USER +// Description: remove a database role +// Syntax: +// DROP USER [ IF EXISTS ] name [, ...] +// +// URL: https://www.postgresql.org/docs/18/sql-dropuser.html + #[test] fn drop_user_parses() { - run_cases(&["DROP USER IF EXISTS my_user"]); + run_cases(&[ + r#"DROP USER app_user"#, + r#"DROP USER IF EXISTS app_user, app_user_old"#, + ]); } diff --git a/tests/test_drop_user_mapping.rs b/tests/test_drop_user_mapping.rs index f98df81..2a60e54 100644 --- a/tests/test_drop_user_mapping.rs +++ b/tests/test_drop_user_mapping.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP USER MAPPING +// Description: remove a user mapping for a foreign server +// Syntax: +// DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name +// +// URL: https://www.postgresql.org/docs/18/sql-dropusermapping.html + #[test] fn drop_user_mapping_parses() { - run_cases(&["DROP USER MAPPING IF EXISTS FOR my_user SERVER my_server"]); + run_cases(&[ + r#"DROP USER MAPPING FOR app_user SERVER my_server"#, + r#"DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER my_server"#, + r#"DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER my_server"#, + ]); } diff --git a/tests/test_drop_view.rs b/tests/test_drop_view.rs index 83b6e9e..2548a58 100644 --- a/tests/test_drop_view.rs +++ b/tests/test_drop_view.rs @@ -2,7 +2,18 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: DROP VIEW +// Description: remove a view +// Syntax: +// DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-dropview.html + #[test] fn drop_view_parses() { - run_cases(&["DROP VIEW IF EXISTS my_view"]); + run_cases(&[ + r#"DROP VIEW v"#, + r#"DROP VIEW IF EXISTS v, v_old CASCADE"#, + r#"DROP VIEW IF EXISTS v RESTRICT"#, + ]); } diff --git a/tests/test_import_foreign_schema.rs b/tests/test_import_foreign_schema.rs index 638af5b..9747ebd 100644 --- a/tests/test_import_foreign_schema.rs +++ b/tests/test_import_foreign_schema.rs @@ -2,9 +2,22 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: IMPORT FOREIGN SCHEMA +// Description: import table definitions from a foreign server +// Syntax: +// IMPORT FOREIGN SCHEMA remote_schema +// [ { LIMIT TO | EXCEPT } ( table_name [, ...] ) ] +// FROM SERVER server_name +// INTO local_schema +// [ OPTIONS ( option 'value' [, ... ] ) ] +// +// URL: https://www.postgresql.org/docs/18/sql-importforeignschema.html + #[test] fn import_foreign_schema_parses() { run_cases(&[ - "IMPORT FOREIGN SCHEMA remote_schema LIMIT TO (remote_table) FROM SERVER my_server INTO public", + r#"IMPORT FOREIGN SCHEMA public FROM SERVER my_server INTO local_schema"#, + r#"IMPORT FOREIGN SCHEMA public LIMIT TO (t1, t2) FROM SERVER my_server INTO local_schema OPTIONS (import_default 'true')"#, + r#"IMPORT FOREIGN SCHEMA public EXCEPT (t1, t2) FROM SERVER my_server INTO local_schema"#, ]); } diff --git a/tests/test_insert_grammar.rs b/tests/test_insert_grammar.rs index 3bd0ffd..d6862f7 100644 --- a/tests/test_insert_grammar.rs +++ b/tests/test_insert_grammar.rs @@ -77,9 +77,15 @@ fn insert_returning_variations() { "INSERT INTO users DEFAULT VALUES RETURNING *", "INSERT INTO users (id) VALUES (1) RETURNING id", "INSERT INTO users (id) VALUES (1) RETURNING id AS inserted_id, email new_email", + "INSERT INTO users (id) VALUES (1) RETURNING WITH (OLD AS old_row) id", + "INSERT INTO users (id) VALUES (1) RETURNING WITH (NEW AS new_row) new_row.id", + "INSERT INTO users (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.id AS old_id, new_row.id AS new_id", ]); } +// Command: INSERT +// Description: create new rows in a table +// Syntax: // [ WITH [ RECURSIVE ] with_query [, ...] ] // INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ] // [ OVERRIDING { SYSTEM | USER } VALUE ] @@ -101,3 +107,5 @@ fn insert_returning_variations() { // ( column_name [, ...] ) = ( sub-SELECT ) // } [, ...] // [ WHERE condition ] +// +// URL: https://www.postgresql.org/docs/18/sql-insert.html diff --git a/tests/test_refresh_materialized_view.rs b/tests/test_refresh_materialized_view.rs index 5244a8c..99c04cc 100644 --- a/tests/test_refresh_materialized_view.rs +++ b/tests/test_refresh_materialized_view.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: REFRESH MATERIALIZED VIEW +// Description: replace the contents of a materialized view +// Syntax: +// REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name +// [ WITH [ NO ] DATA ] +// +// URL: https://www.postgresql.org/docs/18/sql-refreshmaterializedview.html + #[test] fn refresh_materialized_view_parses() { - run_cases(&["REFRESH MATERIALIZED VIEW my_matview"]); + run_cases(&[ + r#"REFRESH MATERIALIZED VIEW mv"#, + r#"REFRESH MATERIALIZED VIEW CONCURRENTLY mv WITH NO DATA"#, + r#"REFRESH MATERIALIZED VIEW mv WITH DATA"#, + ]); } diff --git a/tests/test_reindex.rs b/tests/test_reindex.rs index 1d83ae1..bc85396 100644 --- a/tests/test_reindex.rs +++ b/tests/test_reindex.rs @@ -2,7 +2,28 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: REINDEX +// Description: rebuild indexes +// Syntax: +// 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 ] +// +// URL: https://www.postgresql.org/docs/18/sql-reindex.html + #[test] fn reindex_parses() { - run_cases(&["REINDEX INDEX my_index"]); + run_cases(&[ + r#"REINDEX INDEX my_index"#, + r#"REINDEX TABLE CONCURRENTLY my_table"#, + r#"REINDEX SCHEMA public"#, + r#"REINDEX DATABASE mydb"#, + r#"REINDEX SYSTEM mydb"#, + r#"REINDEX (VERBOSE true, TABLESPACE fastspace) INDEX CONCURRENTLY my_index"#, + ]); } diff --git a/tests/test_security_label.rs b/tests/test_security_label.rs index 64ab761..27dcd05 100644 --- a/tests/test_security_label.rs +++ b/tests/test_security_label.rs @@ -2,7 +2,47 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: SECURITY LABEL +// Description: define or change a security label applied to an object +// Syntax: +// 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 [ , ... ] +// +// URL: https://www.postgresql.org/docs/18/sql-security-label.html + #[test] fn security_label_parses() { - run_cases(&["SECURITY LABEL ON TABLE my_table IS 'classified'"]); + run_cases(&[ + r#"SECURITY LABEL ON TABLE my_table IS 'classified'"#, + r#"SECURITY LABEL FOR selinux ON COLUMN my_table.id IS 'system_u:object_r:sepgsql_table_t:s0'"#, + r#"SECURITY LABEL ON FUNCTION my_function(integer) IS NULL"#, + ]); } diff --git a/tests/test_select_grammar.rs b/tests/test_select_grammar.rs index 2652f6c..866452d 100644 --- a/tests/test_select_grammar.rs +++ b/tests/test_select_grammar.rs @@ -16,7 +16,9 @@ fn select_clause_variations() { "SELECT id FROM users WHERE active AND age >= 18", "SELECT department, count(*) FROM employees GROUP BY department HAVING count(*) > 1", "SELECT sum(salary) OVER w FROM employees WINDOW w AS (PARTITION BY department ORDER BY hired_at)", + "SELECT sum(salary) OVER w, avg(salary) OVER v FROM employees WINDOW w AS (PARTITION BY department), v AS (ORDER BY hired_at)", "SELECT id FROM users ORDER BY created_at ASC NULLS LAST, id DESC NULLS FIRST", + "SELECT id FROM users ORDER BY created_at NULLS FIRST", "SELECT id FROM users ORDER BY name USING < NULLS FIRST", "SELECT id FROM users LIMIT 10", "SELECT id FROM users LIMIT ALL", @@ -26,6 +28,7 @@ fn select_clause_variations() { "SELECT id FROM users FETCH FIRST ROW ONLY", "SELECT id FROM users FETCH FIRST 10 ROWS ONLY", "SELECT id FROM users FETCH NEXT 10 ROW ONLY", + "SELECT id FROM users FETCH NEXT ROWS ONLY", "SELECT id FROM users ORDER BY id FETCH NEXT 10 ROWS WITH TIES", "SELECT id FROM users ORDER BY id FETCH NEXT ROW WITH TIES", "SELECT id FROM users WHERE active GROUP BY id HAVING count(*) > 0 WINDOW w AS (ORDER BY id) ORDER BY id LIMIT 5 OFFSET 1 ROWS", @@ -79,6 +82,7 @@ fn from_item_variations() { "SELECT * FROM json_to_record('{\"a\":1}') x(a int)", "SELECT * FROM LATERAL json_to_record('{\"a\":1}') AS (a int)", "SELECT * FROM ROWS FROM (generate_series(1, 3), generate_series(4, 6))", + "SELECT * FROM ROWS FROM (json_to_record('{\"a\":1}') AS (a int))", "SELECT * FROM LATERAL ROWS FROM (generate_series(1, 3)) AS r(n)", "SELECT * FROM ROWS FROM (json_to_record('{\"a\":1}') AS (a int), generate_series(1, 3)) WITH ORDINALITY AS r(a, b, ordinality)", "SELECT * FROM users JOIN orders ON users.id = orders.user_id", @@ -177,8 +181,9 @@ fn parameter_variations() { ]); } -// SELECT grammar: -// +// Command: SELECT +// Description: retrieve rows from a table or view +// Syntax: // [ WITH [ RECURSIVE ] with_query [, ...] ] // SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] // [ { * | expression [ [ AS ] output_name ] } [, ...] ] @@ -227,3 +232,4 @@ fn parameter_variations() { // TABLE [ ONLY ] table_name [ * ] // +// URL: https://www.postgresql.org/docs/18/sql-select.html diff --git a/tests/test_select_into.rs b/tests/test_select_into.rs index 75fac8b..e999cb0 100644 --- a/tests/test_select_into.rs +++ b/tests/test_select_into.rs @@ -2,7 +2,32 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: SELECT INTO +// Description: define a new table from the results of a query +// Syntax: +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] +// [ { * | expression [ [ AS ] output_name ] } [, ...] ] +// INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] new_table +// [ FROM from_item [, ...] ] +// [ WHERE condition ] +// [ GROUP BY expression [, ...] ] +// [ HAVING condition ] +// [ WINDOW window_name AS ( window_definition ) [, ...] ] +// [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] +// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] +// [ LIMIT { count | ALL } ] +// [ OFFSET start [ ROW | ROWS ] ] +// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] +// [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] +// +// URL: https://www.postgresql.org/docs/18/sql-selectinto.html + #[test] fn select_into_parses() { - run_cases(&["SELECT 1 AS id INTO my_table"]); + run_cases(&[ + r#"SELECT 1 AS id INTO new_table"#, + r#"SELECT 1 AS id INTO TEMP TABLE new_table"#, + r#"SELECT 1 AS id INTO UNLOGGED TABLE new_table FROM source_table WHERE id > 0"#, + ]); } diff --git a/tests/test_truncate.rs b/tests/test_truncate.rs index 9ccd7c1..8369395 100644 --- a/tests/test_truncate.rs +++ b/tests/test_truncate.rs @@ -2,7 +2,19 @@ mod common; use common::run_parse_debug_cases as run_cases; +// Command: TRUNCATE +// Description: empty a table or set of tables +// Syntax: +// TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ] +// [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ] +// +// URL: https://www.postgresql.org/docs/18/sql-truncate.html + #[test] fn truncate_parses() { - run_cases(&["TRUNCATE TABLE my_table"]); + run_cases(&[ + r#"TRUNCATE my_table"#, + r#"TRUNCATE TABLE ONLY my_table, other_table RESTART IDENTITY CASCADE"#, + r#"TRUNCATE TABLE my_table CONTINUE IDENTITY RESTRICT"#, + ]); } diff --git a/tests/test_update_grammar.rs b/tests/test_update_grammar.rs index ca4aa6d..90688fc 100644 --- a/tests/test_update_grammar.rs +++ b/tests/test_update_grammar.rs @@ -64,9 +64,15 @@ fn update_returning_variations() { "UPDATE users SET active = false RETURNING *", "UPDATE users SET active = false RETURNING id", "UPDATE users SET active = false RETURNING id AS updated_id, email new_email", + "UPDATE users SET active = false RETURNING WITH (OLD AS old_row) old_row.active", + "UPDATE users SET active = true RETURNING WITH (NEW AS new_row) new_row.active", + "UPDATE users SET active = true RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.active AS was_active, new_row.active AS is_active", ]); } +// Command: UPDATE +// Description: update rows of a table +// Syntax: // [ WITH [ RECURSIVE ] with_query [, ...] ] // UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ] // SET { column_name = { expression | DEFAULT } | @@ -77,3 +83,5 @@ fn update_returning_variations() { // [ WHERE condition | WHERE CURRENT OF cursor_name ] // [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] // { * | output_expression [ [ AS ] output_name ] } [, ...] ] +// +// URL: https://www.postgresql.org/docs/18/sql-update.html From 57fcb13313b2cda99770195c00f7f79b579af864 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 16 Jul 2026 17:02:23 -0700 Subject: [PATCH 3/5] ci --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0684fc2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: CI + +on: + push: + pull_request: + +jobs: + test: + name: cargo test + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y clang libclang-dev + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Run tests + run: cargo test From 6c0cb2128d9d7991bcf406f7dac6d47493b3990b Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 16 Jul 2026 17:03:48 -0700 Subject: [PATCH 4/5] fix workflow --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0684fc2..8d90a89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,8 @@ name: CI on: push: + branches: + - main pull_request: jobs: From 8a208a2640c01b86a0cb487667c0680864e0f604 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 16 Jul 2026 20:58:49 -0700 Subject: [PATCH 5/5] removed grammar comments --- tests/test_alter_aggregate.rs | 16 - tests/test_alter_collation.rs | 11 - tests/test_alter_conversion.rs | 9 - tests/test_alter_database.rs | 26 -- tests/test_alter_default_privileges.rs | 80 ----- tests/test_alter_domain.rs | 29 -- tests/test_alter_event_trigger.rs | 10 - tests/test_alter_extension.rs | 47 --- tests/test_alter_foreign_data_wrapper.rs | 12 - tests/test_alter_foreign_table.rs | 40 --- tests/test_alter_function.rs | 31 -- tests/test_alter_group.rs | 17 - tests/test_alter_index.rs | 16 - tests/test_alter_language.rs | 8 - tests/test_alter_large_object.rs | 7 - tests/test_alter_materialized_view.rs | 33 -- tests/test_alter_operator.rs | 20 -- tests/test_alter_operator_class.rs | 14 - tests/test_alter_operator_family.rs | 26 -- tests/test_alter_policy.rs | 12 - tests/test_alter_procedure.rs | 24 -- tests/test_alter_publication.rs | 26 -- tests/test_alter_role.rs | 34 -- tests/test_alter_routine.rs | 29 -- tests/test_alter_rule.rs | 7 - tests/test_alter_schema.rs | 8 - tests/test_alter_sequence.rs | 19 -- tests/test_alter_server.rs | 10 - tests/test_alter_statistics.rs | 10 - tests/test_alter_subscription.rs | 17 - tests/test_alter_system.rs | 10 - tests/test_alter_table.rs | 127 ------- tests/test_alter_tablespace.rs | 10 - tests/test_alter_text_search_configuration.rs | 19 -- tests/test_alter_text_search_dictionary.rs | 12 - tests/test_alter_text_search_parser.rs | 8 - tests/test_alter_text_search_template.rs | 8 - tests/test_alter_trigger.rs | 8 - tests/test_alter_type.rs | 20 -- tests/test_alter_user.rs | 34 -- tests/test_alter_user_mapping.rs | 9 - tests/test_alter_view.rs | 14 - tests/test_comment.rs | 58 ---- tests/test_create_access_method.rs | 9 - tests/test_create_aggregate.rs | 66 ---- tests/test_create_cast.rs | 17 - tests/test_create_collation.rs | 16 - tests/test_create_conversion.rs | 8 - tests/test_create_database.rs | 24 -- tests/test_create_domain.rs | 15 - tests/test_create_event_trigger.rs | 10 - tests/test_create_extension.rs | 10 - tests/test_create_foreign_data_wrapper.rs | 10 - tests/test_create_foreign_table.rs | 53 --- tests/test_create_function.rs | 26 -- tests/test_create_group.rs | 26 -- tests/test_create_index.rs | 13 - tests/test_create_language.rs | 9 - tests/test_create_materialized_view.rs | 13 - tests/test_create_operator.rs | 13 - tests/test_create_operator_class.rs | 12 - tests/test_create_operator_family.rs | 7 - tests/test_create_policy.rs | 12 - tests/test_create_procedure.rs | 16 - tests/test_create_publication.rs | 19 -- tests/test_create_role.rs | 24 -- tests/test_create_rule.rs | 13 - tests/test_create_schema.rs | 17 - tests/test_create_sequence.rs | 14 - tests/test_create_server.rs | 9 - tests/test_create_statistics.rs | 14 - tests/test_create_subscription.rs | 10 - tests/test_create_table.rs | 89 ----- tests/test_create_table_as.rs | 14 - tests/test_create_tablespace.rs | 10 - .../test_create_text_search_configuration.rs | 10 - tests/test_create_text_search_dictionary.rs | 10 - tests/test_create_text_search_parser.rs | 13 - tests/test_create_text_search_template.rs | 10 - tests/test_create_transform.rs | 10 - tests/test_create_trigger.rs | 21 -- tests/test_create_type.rs | 44 --- tests/test_create_user.rs | 26 -- tests/test_create_user_mapping.rs | 9 - tests/test_create_view.rs | 10 - tests/test_delete_grammar.rs | 12 - tests/test_drop.rs | 314 ------------------ tests/test_drop_access_method.rs | 7 - tests/test_drop_aggregate.rs | 13 - tests/test_drop_cast.rs | 7 - tests/test_drop_collation.rs | 7 - tests/test_drop_conversion.rs | 7 - tests/test_drop_database.rs | 11 - tests/test_drop_domain.rs | 7 - tests/test_drop_event_trigger.rs | 7 - tests/test_drop_extension.rs | 7 - tests/test_drop_foreign_data_wrapper.rs | 7 - tests/test_drop_foreign_table.rs | 7 - tests/test_drop_function.rs | 8 - tests/test_drop_group.rs | 7 - tests/test_drop_index.rs | 7 - tests/test_drop_language.rs | 7 - tests/test_drop_materialized_view.rs | 7 - tests/test_drop_operator.rs | 7 - tests/test_drop_operator_class.rs | 7 - tests/test_drop_operator_family.rs | 7 - tests/test_drop_owned.rs | 7 - tests/test_drop_policy.rs | 7 - tests/test_drop_procedure.rs | 8 - tests/test_drop_publication.rs | 7 - tests/test_drop_role.rs | 7 - tests/test_drop_routine.rs | 8 - tests/test_drop_rule.rs | 7 - tests/test_drop_schema.rs | 7 - tests/test_drop_sequence.rs | 7 - tests/test_drop_server.rs | 7 - tests/test_drop_statistics.rs | 7 - tests/test_drop_subscription.rs | 7 - tests/test_drop_table.rs | 7 - tests/test_drop_tablespace.rs | 7 - tests/test_drop_text_search_configuration.rs | 7 - tests/test_drop_text_search_dictionary.rs | 7 - tests/test_drop_text_search_parser.rs | 7 - tests/test_drop_text_search_template.rs | 7 - tests/test_drop_transform.rs | 7 - tests/test_drop_trigger.rs | 7 - tests/test_drop_type.rs | 7 - tests/test_drop_user.rs | 7 - tests/test_drop_user_mapping.rs | 7 - tests/test_drop_view.rs | 7 - tests/test_import_foreign_schema.rs | 11 - tests/test_insert_grammar.rs | 27 -- tests/test_refresh_materialized_view.rs | 8 - tests/test_reindex.rs | 14 - tests/test_security_label.rs | 36 -- tests/test_select_grammar.rs | 53 --- tests/test_select_into.rs | 21 -- tests/test_truncate.rs | 8 - tests/test_update_grammar.rs | 16 - 139 files changed, 2600 deletions(-) diff --git a/tests/test_alter_aggregate.rs b/tests/test_alter_aggregate.rs index 199dcbc..266d22a 100644 --- a/tests/test_alter_aggregate.rs +++ b/tests/test_alter_aggregate.rs @@ -2,22 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER AGGREGATE -// Description: change the definition of an aggregate function -// Syntax: -// 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 [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-alteraggregate.html - #[test] fn alter_aggregate_parses() { run_cases(&[ diff --git a/tests/test_alter_collation.rs b/tests/test_alter_collation.rs index d088689..3ea2949 100644 --- a/tests/test_alter_collation.rs +++ b/tests/test_alter_collation.rs @@ -2,17 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER COLLATION -// Description: change the definition of a collation -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altercollation.html - #[test] fn alter_collation_parses() { run_cases(&[ diff --git a/tests/test_alter_conversion.rs b/tests/test_alter_conversion.rs index 9852547..e2bff03 100644 --- a/tests/test_alter_conversion.rs +++ b/tests/test_alter_conversion.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER CONVERSION -// Description: change the definition of a conversion -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterconversion.html - #[test] fn alter_conversion_parses() { run_cases(&[ diff --git a/tests/test_alter_database.rs b/tests/test_alter_database.rs index e5894ab..2968e41 100644 --- a/tests/test_alter_database.rs +++ b/tests/test_alter_database.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER DATABASE -// Description: change a database -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterdatabase.html - #[test] fn alter_database_parses() { run_cases(&[ diff --git a/tests/test_alter_default_privileges.rs b/tests/test_alter_default_privileges.rs index 2a768d1..d11df23 100644 --- a/tests/test_alter_default_privileges.rs +++ b/tests/test_alter_default_privileges.rs @@ -2,86 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER DEFAULT PRIVILEGES -// Description: define default access privileges -// Syntax: -// 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 ] -// -// GRANT { { SELECT | UPDATE } -// [, ...] | ALL [ PRIVILEGES ] } -// ON LARGE OBJECTS -// 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 ] -// -// REVOKE [ GRANT OPTION FOR ] -// { { SELECT | UPDATE } -// [, ...] | ALL [ PRIVILEGES ] } -// ON LARGE OBJECTS -// FROM { [ GROUP ] role_name | PUBLIC } [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-alterdefaultprivileges.html - #[test] fn alter_default_privileges_parses() { run_cases(&[ diff --git a/tests/test_alter_domain.rs b/tests/test_alter_domain.rs index cf176b4..d5f7881 100644 --- a/tests/test_alter_domain.rs +++ b/tests/test_alter_domain.rs @@ -2,35 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER DOMAIN -// Description: change the definition of a domain -// Syntax: -// 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) } -// -// URL: https://www.postgresql.org/docs/18/sql-alterdomain.html - #[test] fn alter_domain_parses() { run_cases(&[ diff --git a/tests/test_alter_event_trigger.rs b/tests/test_alter_event_trigger.rs index 1fc0d17..e91bd53 100644 --- a/tests/test_alter_event_trigger.rs +++ b/tests/test_alter_event_trigger.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER EVENT TRIGGER -// Description: change the definition of an event trigger -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altereventtrigger.html - #[test] fn alter_event_trigger_parses() { run_cases(&[ diff --git a/tests/test_alter_extension.rs b/tests/test_alter_extension.rs index b270808..ddd871b 100644 --- a/tests/test_alter_extension.rs +++ b/tests/test_alter_extension.rs @@ -2,53 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER EXTENSION -// Description: change the definition of an extension -// Syntax: -// 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 [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-alterextension.html - #[test] fn alter_extension_parses() { run_cases(&[ diff --git a/tests/test_alter_foreign_data_wrapper.rs b/tests/test_alter_foreign_data_wrapper.rs index 95664d0..005d2be 100644 --- a/tests/test_alter_foreign_data_wrapper.rs +++ b/tests/test_alter_foreign_data_wrapper.rs @@ -2,18 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER FOREIGN DATA WRAPPER -// Description: change the definition of a foreign-data wrapper -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterforeigndatawrapper.html - #[test] fn alter_foreign_data_wrapper_parses() { run_cases(&[ diff --git a/tests/test_alter_foreign_table.rs b/tests/test_alter_foreign_table.rs index 9aee7d7..9a88aa5 100644 --- a/tests/test_alter_foreign_table.rs +++ b/tests/test_alter_foreign_table.rs @@ -2,46 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER FOREIGN TABLE -// Description: change the definition of a foreign table -// Syntax: -// 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 ] [ 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 ] -// 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'] [, ... ]) -// -// URL: https://www.postgresql.org/docs/18/sql-alterforeigntable.html - #[test] fn alter_foreign_table_parses() { run_cases(&[ diff --git a/tests/test_alter_function.rs b/tests/test_alter_function.rs index d36895a..a2173b9 100644 --- a/tests/test_alter_function.rs +++ b/tests/test_alter_function.rs @@ -2,37 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER FUNCTION -// Description: change the definition of a function -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterfunction.html - #[test] fn alter_function_parses() { run_cases(&[ diff --git a/tests/test_alter_group.rs b/tests/test_alter_group.rs index 9ad3efc..e3ececa 100644 --- a/tests/test_alter_group.rs +++ b/tests/test_alter_group.rs @@ -2,23 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER GROUP -// Description: change role name or membership -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altergroup.html - #[test] fn alter_group_parses() { run_cases(&[ diff --git a/tests/test_alter_index.rs b/tests/test_alter_index.rs index a6d6886..2022837 100644 --- a/tests/test_alter_index.rs +++ b/tests/test_alter_index.rs @@ -2,22 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER INDEX -// Description: change the definition of an index -// Syntax: -// ALTER INDEX [ IF EXISTS ] name RENAME TO new_name -// ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name -// ALTER INDEX name ATTACH PARTITION index_name -// ALTER INDEX name [ NO ] DEPENDS ON EXTENSION extension_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 -// ALTER INDEX ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ] -// SET TABLESPACE new_tablespace [ NOWAIT ] -// -// URL: https://www.postgresql.org/docs/18/sql-alterindex.html - #[test] fn alter_index_parses() { run_cases(&[ diff --git a/tests/test_alter_language.rs b/tests/test_alter_language.rs index 7bc9115..ebed319 100644 --- a/tests/test_alter_language.rs +++ b/tests/test_alter_language.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER LANGUAGE -// Description: change the definition of a procedural language -// Syntax: -// ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO new_name -// ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } -// -// URL: https://www.postgresql.org/docs/18/sql-alterlanguage.html - #[test] fn alter_language_parses() { run_cases(&[ diff --git a/tests/test_alter_large_object.rs b/tests/test_alter_large_object.rs index 1c5887a..359204c 100644 --- a/tests/test_alter_large_object.rs +++ b/tests/test_alter_large_object.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER LARGE OBJECT -// Description: change the definition of a large object -// Syntax: -// ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } -// -// URL: https://www.postgresql.org/docs/18/sql-alterlargeobject.html - #[test] fn alter_large_object_parses() { run_cases(&[r#"ALTER LARGE OBJECT 12345 OWNER TO CURRENT_USER"#]); diff --git a/tests/test_alter_materialized_view.rs b/tests/test_alter_materialized_view.rs index 03598a8..e4f573c 100644 --- a/tests/test_alter_materialized_view.rs +++ b/tests/test_alter_materialized_view.rs @@ -2,39 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER MATERIALIZED VIEW -// Description: change the definition of a materialized view -// Syntax: -// 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 } -// -// URL: https://www.postgresql.org/docs/18/sql-altermaterializedview.html - #[test] fn alter_materialized_view_parses() { run_cases(&[ diff --git a/tests/test_alter_operator.rs b/tests/test_alter_operator.rs index 8ef5633..1d06e4f 100644 --- a/tests/test_alter_operator.rs +++ b/tests/test_alter_operator.rs @@ -2,26 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER OPERATOR -// Description: change the definition of an operator -// Syntax: -// 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 -// } [, ... ] ) -// -// URL: https://www.postgresql.org/docs/18/sql-alteroperator.html - #[test] fn alter_operator_parses() { run_cases(&[ diff --git a/tests/test_alter_operator_class.rs b/tests/test_alter_operator_class.rs index 30d581a..472ddc2 100644 --- a/tests/test_alter_operator_class.rs +++ b/tests/test_alter_operator_class.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER OPERATOR CLASS -// Description: change the definition of an operator class -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alteropclass.html - #[test] fn alter_operator_class_parses() { run_cases(&[ diff --git a/tests/test_alter_operator_family.rs b/tests/test_alter_operator_family.rs index 8db219d..3ff49f0 100644 --- a/tests/test_alter_operator_family.rs +++ b/tests/test_alter_operator_family.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER OPERATOR FAMILY -// Description: change the definition of an operator family -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alteropfamily.html - #[test] fn alter_operator_family_parses() { run_cases(&[ diff --git a/tests/test_alter_policy.rs b/tests/test_alter_policy.rs index e1d59a7..57fb229 100644 --- a/tests/test_alter_policy.rs +++ b/tests/test_alter_policy.rs @@ -2,18 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER POLICY -// Description: change the definition of a row-level security policy -// Syntax: -// 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 ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-alterpolicy.html - #[test] fn alter_policy_parses() { run_cases(&[ diff --git a/tests/test_alter_procedure.rs b/tests/test_alter_procedure.rs index 5bc2061..d8d0ebd 100644 --- a/tests/test_alter_procedure.rs +++ b/tests/test_alter_procedure.rs @@ -2,30 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER PROCEDURE -// Description: change the definition of a procedure -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterprocedure.html - #[test] fn alter_procedure_parses() { run_cases(&[ diff --git a/tests/test_alter_publication.rs b/tests/test_alter_publication.rs index 851cb09..cb75602 100644 --- a/tests/test_alter_publication.rs +++ b/tests/test_alter_publication.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER PUBLICATION -// Description: change the definition of a publication -// Syntax: -// ALTER PUBLICATION name ADD publication_object [, ...] -// ALTER PUBLICATION name SET publication_object [, ...] -// ALTER PUBLICATION name DROP publication_drop_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 table_and_columns [, ... ] -// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] -// -// and publication_drop_object is one of: -// -// TABLE [ ONLY ] table_name [ * ] [, ... ] -// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] -// -// and table_and_columns is: -// -// [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-alterpublication.html - #[test] fn alter_publication_parses() { run_cases(&[ diff --git a/tests/test_alter_role.rs b/tests/test_alter_role.rs index 420b398..421b228 100644 --- a/tests/test_alter_role.rs +++ b/tests/test_alter_role.rs @@ -2,40 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER ROLE -// Description: change a database role -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterrole.html - #[test] fn alter_role_parses() { run_cases(&[ diff --git a/tests/test_alter_routine.rs b/tests/test_alter_routine.rs index e9818a8..b58be1c 100644 --- a/tests/test_alter_routine.rs +++ b/tests/test_alter_routine.rs @@ -2,35 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER ROUTINE -// Description: change the definition of a routine -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterroutine.html - #[test] fn alter_routine_parses() { run_cases(&[ diff --git a/tests/test_alter_rule.rs b/tests/test_alter_rule.rs index 9771b45..0c1f55c 100644 --- a/tests/test_alter_rule.rs +++ b/tests/test_alter_rule.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER RULE -// Description: change the definition of a rule -// Syntax: -// ALTER RULE name ON table_name RENAME TO new_name -// -// URL: https://www.postgresql.org/docs/18/sql-alterrule.html - #[test] fn alter_rule_parses() { run_cases(&[r#"ALTER RULE my_rule ON my_table RENAME TO my_rule_new"#]); diff --git a/tests/test_alter_schema.rs b/tests/test_alter_schema.rs index 7f1d9f4..91d1a73 100644 --- a/tests/test_alter_schema.rs +++ b/tests/test_alter_schema.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER SCHEMA -// Description: change the definition of a schema -// Syntax: -// ALTER SCHEMA name RENAME TO new_name -// ALTER SCHEMA name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } -// -// URL: https://www.postgresql.org/docs/18/sql-alterschema.html - #[test] fn alter_schema_parses() { run_cases(&[ diff --git a/tests/test_alter_sequence.rs b/tests/test_alter_sequence.rs index be640cf..001cacf 100644 --- a/tests/test_alter_sequence.rs +++ b/tests/test_alter_sequence.rs @@ -2,25 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER SEQUENCE -// Description: change the definition of a sequence generator -// Syntax: -// ALTER SEQUENCE [ IF EXISTS ] name -// [ AS data_type ] -// [ INCREMENT [ BY ] increment ] -// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] -// [ [ NO ] CYCLE ] -// [ START [ WITH ] start ] -// [ RESTART [ [ WITH ] restart ] ] -// [ CACHE cache ] -// [ 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altersequence.html - #[test] fn alter_sequence_parses() { run_cases(&[ diff --git a/tests/test_alter_server.rs b/tests/test_alter_server.rs index 168e9db..fd9eecf 100644 --- a/tests/test_alter_server.rs +++ b/tests/test_alter_server.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER SERVER -// Description: change the definition of a foreign server -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alterserver.html - #[test] fn alter_server_parses() { run_cases(&[ diff --git a/tests/test_alter_statistics.rs b/tests/test_alter_statistics.rs index a31fd9b..5979166 100644 --- a/tests/test_alter_statistics.rs +++ b/tests/test_alter_statistics.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER STATISTICS -// Description: change the definition of an extended statistics object -// Syntax: -// 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 } -// -// URL: https://www.postgresql.org/docs/18/sql-alterstatistics.html - #[test] fn alter_statistics_parses() { run_cases(&[ diff --git a/tests/test_alter_subscription.rs b/tests/test_alter_subscription.rs index e8bf75c..aabd367 100644 --- a/tests/test_alter_subscription.rs +++ b/tests/test_alter_subscription.rs @@ -2,23 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER SUBSCRIPTION -// Description: change the definition of a subscription -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altersubscription.html - #[test] fn alter_subscription_parses() { run_cases(&[ diff --git a/tests/test_alter_system.rs b/tests/test_alter_system.rs index 33b4822..8c6049c 100644 --- a/tests/test_alter_system.rs +++ b/tests/test_alter_system.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER SYSTEM -// Description: change a server configuration parameter -// Syntax: -// ALTER SYSTEM SET configuration_parameter { TO | = } { value [, ...] | DEFAULT } -// -// ALTER SYSTEM RESET configuration_parameter -// ALTER SYSTEM RESET ALL -// -// URL: https://www.postgresql.org/docs/18/sql-altersystem.html - #[test] fn alter_system_parses() { run_cases(&[ diff --git a/tests/test_alter_table.rs b/tests/test_alter_table.rs index ab191ab..789e982 100644 --- a/tests/test_alter_table.rs +++ b/tests/test_alter_table.rs @@ -2,133 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TABLE -// Description: change the definition of a table -// Syntax: -// ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] -// action [, ... ] -// 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 ] -// -// 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 ] [ ENFORCED | NOT ENFORCED ] -// ALTER CONSTRAINT constraint_name [ INHERIT | NO INHERIT ] -// 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 } -// -// 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 ) -// -// and column_constraint is: -// -// [ CONSTRAINT constraint_name ] -// { NOT NULL [ NO INHERIT ] | -// NULL | -// CHECK ( expression ) [ NO INHERIT ] | -// DEFAULT default_expr | -// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | -// 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 ] [ ENFORCED | NOT ENFORCED ] -// -// and table_constraint is: -// -// [ CONSTRAINT constraint_name ] -// { CHECK ( expression ) [ NO INHERIT ] | -// NOT NULL column_name [ NO INHERIT ] | -// UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | -// PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | -// EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | -// FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] -// [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -// -// and table_constraint_using_index is: -// -// [ CONSTRAINT constraint_name ] -// { UNIQUE | PRIMARY KEY } USING INDEX index_name -// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -// -// index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: -// -// [ INCLUDE ( column_name [, ... ] ) ] -// [ WITH ( storage_parameter [= value] [, ... ] ) ] -// [ USING INDEX TABLESPACE tablespace_name ] -// -// exclude_element in an EXCLUDE constraint is: -// -// { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -// -// referential_action in a FOREIGN KEY/REFERENCES constraint is: -// -// { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } -// -// URL: https://www.postgresql.org/docs/18/sql-altertable.html - #[test] fn alter_table_parses() { run_cases(&[ diff --git a/tests/test_alter_tablespace.rs b/tests/test_alter_tablespace.rs index 285f44f..b95458f 100644 --- a/tests/test_alter_tablespace.rs +++ b/tests/test_alter_tablespace.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TABLESPACE -// Description: change the definition of a tablespace -// Syntax: -// 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 [, ... ] ) -// -// URL: https://www.postgresql.org/docs/18/sql-altertablespace.html - #[test] fn alter_tablespace_parses() { run_cases(&[ diff --git a/tests/test_alter_text_search_configuration.rs b/tests/test_alter_text_search_configuration.rs index def5ffd..5c04230 100644 --- a/tests/test_alter_text_search_configuration.rs +++ b/tests/test_alter_text_search_configuration.rs @@ -3,25 +3,6 @@ mod common; use common::run_parse_debug_case as run_case; use pg_raw_parse::{Node, parse}; -// Command: ALTER TEXT SEARCH CONFIGURATION -// Description: change the definition of a text search configuration -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altertsconfig.html - #[test] fn alter_text_search_configuration_add_mapping() { run_case(r#"ALTER TEXT SEARCH CONFIGURATION my_config ADD MAPPING FOR asciiword WITH simple"#); diff --git a/tests/test_alter_text_search_dictionary.rs b/tests/test_alter_text_search_dictionary.rs index 54e11ad..3ef5bff 100644 --- a/tests/test_alter_text_search_dictionary.rs +++ b/tests/test_alter_text_search_dictionary.rs @@ -2,18 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TEXT SEARCH DICTIONARY -// Description: change the definition of a text search dictionary -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-altertsdictionary.html - #[test] fn alter_text_search_dictionary_parses() { run_cases(&[ diff --git a/tests/test_alter_text_search_parser.rs b/tests/test_alter_text_search_parser.rs index c56fd06..4f0a64d 100644 --- a/tests/test_alter_text_search_parser.rs +++ b/tests/test_alter_text_search_parser.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TEXT SEARCH PARSER -// Description: change the definition of a text search parser -// Syntax: -// ALTER TEXT SEARCH PARSER name RENAME TO new_name -// ALTER TEXT SEARCH PARSER name SET SCHEMA new_schema -// -// URL: https://www.postgresql.org/docs/18/sql-altertsparser.html - #[test] fn alter_text_search_parser_parses() { run_cases(&[ diff --git a/tests/test_alter_text_search_template.rs b/tests/test_alter_text_search_template.rs index bca49c9..5e0f05a 100644 --- a/tests/test_alter_text_search_template.rs +++ b/tests/test_alter_text_search_template.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TEXT SEARCH TEMPLATE -// Description: change the definition of a text search template -// Syntax: -// ALTER TEXT SEARCH TEMPLATE name RENAME TO new_name -// ALTER TEXT SEARCH TEMPLATE name SET SCHEMA new_schema -// -// URL: https://www.postgresql.org/docs/18/sql-altertstemplate.html - #[test] fn alter_text_search_template_parses() { run_cases(&[ diff --git a/tests/test_alter_trigger.rs b/tests/test_alter_trigger.rs index a4931dd..c873834 100644 --- a/tests/test_alter_trigger.rs +++ b/tests/test_alter_trigger.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TRIGGER -// Description: change the definition of a trigger -// Syntax: -// ALTER TRIGGER name ON table_name RENAME TO new_name -// ALTER TRIGGER name ON table_name [ NO ] DEPENDS ON EXTENSION extension_name -// -// URL: https://www.postgresql.org/docs/18/sql-altertrigger.html - #[test] fn alter_trigger_parses() { run_cases(&[ diff --git a/tests/test_alter_type.rs b/tests/test_alter_type.rs index 3c0562d..547132c 100644 --- a/tests/test_alter_type.rs +++ b/tests/test_alter_type.rs @@ -2,26 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER TYPE -// Description: change the definition of a type -// Syntax: -// 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-altertype.html - #[test] fn alter_type_parses() { run_cases(&[ diff --git a/tests/test_alter_user.rs b/tests/test_alter_user.rs index 20a6713..f55d01e 100644 --- a/tests/test_alter_user.rs +++ b/tests/test_alter_user.rs @@ -2,40 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER USER -// Description: change a database role -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-alteruser.html - #[test] fn alter_user_parses() { run_cases(&[ diff --git a/tests/test_alter_user_mapping.rs b/tests/test_alter_user_mapping.rs index a90f031..ee4a973 100644 --- a/tests/test_alter_user_mapping.rs +++ b/tests/test_alter_user_mapping.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER USER MAPPING -// Description: change the definition of a user mapping -// Syntax: -// ALTER USER MAPPING FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC } -// SERVER server_name -// OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) -// -// URL: https://www.postgresql.org/docs/18/sql-alterusermapping.html - #[test] fn alter_user_mapping_parses() { run_cases(&[ diff --git a/tests/test_alter_view.rs b/tests/test_alter_view.rs index dca326c..994bed0 100644 --- a/tests/test_alter_view.rs +++ b/tests/test_alter_view.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: ALTER VIEW -// Description: change the definition of a view -// Syntax: -// 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 [, ... ] ) -// -// URL: https://www.postgresql.org/docs/18/sql-alterview.html - #[test] fn alter_view_parses() { run_cases(&[ diff --git a/tests/test_comment.rs b/tests/test_comment.rs index d56f505..9d3f841 100644 --- a/tests/test_comment.rs +++ b/tests/test_comment.rs @@ -2,64 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: COMMENT -// Description: define or change the comment of an object -// Syntax: -// 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 [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-comment.html - #[test] fn comment_parses() { run_cases(&[ diff --git a/tests/test_create_access_method.rs b/tests/test_create_access_method.rs index 9db4b41..f6a275d 100644 --- a/tests/test_create_access_method.rs +++ b/tests/test_create_access_method.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE ACCESS METHOD -// Description: define a new access method -// Syntax: -// CREATE ACCESS METHOD name -// TYPE access_method_type -// HANDLER handler_function -// -// URL: https://www.postgresql.org/docs/18/sql-create-access-method.html - #[test] fn create_access_method_parses() { run_cases(&[ diff --git a/tests/test_create_aggregate.rs b/tests/test_create_aggregate.rs index 2043fef..0d279f6 100644 --- a/tests/test_create_aggregate.rs +++ b/tests/test_create_aggregate.rs @@ -2,72 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE AGGREGATE -// Description: define a new aggregate function -// Syntax: -// 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 ] -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createaggregate.html - #[test] fn create_aggregate_parses() { run_cases(&[ diff --git a/tests/test_create_cast.rs b/tests/test_create_cast.rs index 18ec092..bd24225 100644 --- a/tests/test_create_cast.rs +++ b/tests/test_create_cast.rs @@ -2,23 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE CAST -// Description: define a new cast -// Syntax: -// 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-createcast.html - #[test] fn create_cast_parses() { run_cases(&[ diff --git a/tests/test_create_collation.rs b/tests/test_create_collation.rs index 7155a69..72c5096 100644 --- a/tests/test_create_collation.rs +++ b/tests/test_create_collation.rs @@ -2,22 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE COLLATION -// Description: define a new collation -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createcollation.html - #[test] fn create_collation_parses() { run_cases(&[ diff --git a/tests/test_create_conversion.rs b/tests/test_create_conversion.rs index 6a82aa2..e44d517 100644 --- a/tests/test_create_conversion.rs +++ b/tests/test_create_conversion.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE CONVERSION -// Description: define a new encoding conversion -// Syntax: -// CREATE [ DEFAULT ] CONVERSION name -// FOR source_encoding TO dest_encoding FROM function_name -// -// URL: https://www.postgresql.org/docs/18/sql-createconversion.html - #[test] fn create_conversion_parses() { run_cases(&[ diff --git a/tests/test_create_database.rs b/tests/test_create_database.rs index 37277fd..ff9405a 100644 --- a/tests/test_create_database.rs +++ b/tests/test_create_database.rs @@ -2,30 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE DATABASE -// Description: create a new database -// Syntax: -// 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-createdatabase.html - #[test] fn create_database_parses() { run_cases(&[ diff --git a/tests/test_create_domain.rs b/tests/test_create_domain.rs index 63125ff..651dbe7 100644 --- a/tests/test_create_domain.rs +++ b/tests/test_create_domain.rs @@ -2,21 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE DOMAIN -// Description: define a new domain -// Syntax: -// CREATE DOMAIN name [ AS ] data_type -// [ COLLATE collation ] -// [ DEFAULT expression ] -// [ domain_constraint [ ... ] ] -// -// where domain_constraint is: -// -// [ CONSTRAINT constraint_name ] -// { NOT NULL | NULL | CHECK (expression) } -// -// URL: https://www.postgresql.org/docs/18/sql-createdomain.html - #[test] fn create_domain_parses() { run_cases(&[ diff --git a/tests/test_create_event_trigger.rs b/tests/test_create_event_trigger.rs index 94091b3..0441efc 100644 --- a/tests/test_create_event_trigger.rs +++ b/tests/test_create_event_trigger.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE EVENT TRIGGER -// Description: define a new event trigger -// Syntax: -// CREATE EVENT TRIGGER name -// ON event -// [ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ] -// EXECUTE { FUNCTION | PROCEDURE } function_name() -// -// URL: https://www.postgresql.org/docs/18/sql-createeventtrigger.html - #[test] fn create_event_trigger_parses() { run_cases(&[ diff --git a/tests/test_create_extension.rs b/tests/test_create_extension.rs index 3cfe76e..9d39a69 100644 --- a/tests/test_create_extension.rs +++ b/tests/test_create_extension.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE EXTENSION -// Description: install an extension -// Syntax: -// CREATE EXTENSION [ IF NOT EXISTS ] extension_name -// [ WITH ] [ SCHEMA schema_name ] -// [ VERSION version ] -// [ CASCADE ] -// -// URL: https://www.postgresql.org/docs/18/sql-createextension.html - #[test] fn create_extension_parses() { run_cases(&[ diff --git a/tests/test_create_foreign_data_wrapper.rs b/tests/test_create_foreign_data_wrapper.rs index 8d6e341..e6cf948 100644 --- a/tests/test_create_foreign_data_wrapper.rs +++ b/tests/test_create_foreign_data_wrapper.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE FOREIGN DATA WRAPPER -// Description: define a new foreign-data wrapper -// Syntax: -// CREATE FOREIGN DATA WRAPPER name -// [ HANDLER handler_function | NO HANDLER ] -// [ VALIDATOR validator_function | NO VALIDATOR ] -// [ OPTIONS ( option 'value' [, ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createforeigndatawrapper.html - #[test] fn create_foreign_data_wrapper_parses() { run_cases(&[ diff --git a/tests/test_create_foreign_table.rs b/tests/test_create_foreign_table.rs index 450e33d..46f858d 100644 --- a/tests/test_create_foreign_table.rs +++ b/tests/test_create_foreign_table.rs @@ -2,59 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE FOREIGN TABLE -// Description: define a new foreign table -// Syntax: -// CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ -// { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ] -// | table_constraint -// | LIKE source_table [ like_option ... ] } -// [, ... ] -// ] ) -// [ 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 [ NO INHERIT ] | -// NULL | -// CHECK ( expression ) [ NO INHERIT ] | -// DEFAULT default_expr | -// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] } -// [ ENFORCED | NOT ENFORCED ] -// -// and table_constraint is: -// -// [ CONSTRAINT constraint_name ] -// { NOT NULL column_name [ NO INHERIT ] | -// CHECK ( expression ) [ NO INHERIT ] } -// [ ENFORCED | NOT ENFORCED ] -// -// and like_option is: -// -// { INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL } -// -// 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 ) -// -// URL: https://www.postgresql.org/docs/18/sql-createforeigntable.html - #[test] fn create_foreign_table_parses() { run_cases(&[ diff --git a/tests/test_create_function.rs b/tests/test_create_function.rs index 44900ab..36a5a6a 100644 --- a/tests/test_create_function.rs +++ b/tests/test_create_function.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE FUNCTION -// Description: define a new function -// Syntax: -// 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 -// } ... -// -// URL: https://www.postgresql.org/docs/18/sql-createfunction.html - #[test] fn create_function_parses() { run_cases(&[ diff --git a/tests/test_create_group.rs b/tests/test_create_group.rs index d6fe0e6..e1de69e 100644 --- a/tests/test_create_group.rs +++ b/tests/test_create_group.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE GROUP -// Description: define a new database role -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-creategroup.html - #[test] fn create_group_parses() { run_cases(&[ diff --git a/tests/test_create_index.rs b/tests/test_create_index.rs index 11cdefc..f03e65a 100644 --- a/tests/test_create_index.rs +++ b/tests/test_create_index.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE INDEX -// Description: define a new index -// Syntax: -// 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-createindex.html - #[test] fn create_index_parses() { run_cases(&[ diff --git a/tests/test_create_language.rs b/tests/test_create_language.rs index d8d1729..a1bc51b 100644 --- a/tests/test_create_language.rs +++ b/tests/test_create_language.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE LANGUAGE -// Description: define a new procedural language -// Syntax: -// CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name -// HANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ] -// CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name -// -// URL: https://www.postgresql.org/docs/18/sql-createlanguage.html - #[test] fn create_language_parses() { run_cases(&[ diff --git a/tests/test_create_materialized_view.rs b/tests/test_create_materialized_view.rs index a28751a..1a975f7 100644 --- a/tests/test_create_materialized_view.rs +++ b/tests/test_create_materialized_view.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE MATERIALIZED VIEW -// Description: define a new materialized view -// Syntax: -// CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name -// [ (column_name [, ...] ) ] -// [ USING method ] -// [ WITH ( storage_parameter [= value] [, ... ] ) ] -// [ TABLESPACE tablespace_name ] -// AS query -// [ WITH [ NO ] DATA ] -// -// URL: https://www.postgresql.org/docs/18/sql-creatematerializedview.html - #[test] fn create_materialized_view_parses() { run_cases(&[ diff --git a/tests/test_create_operator.rs b/tests/test_create_operator.rs index eec9c03..553244f 100644 --- a/tests/test_create_operator.rs +++ b/tests/test_create_operator.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE OPERATOR -// Description: define a new operator -// Syntax: -// 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 ] -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createoperator.html - #[test] fn create_operator_parses() { run_cases(&[ diff --git a/tests/test_create_operator_class.rs b/tests/test_create_operator_class.rs index 4c4816c..8d2edee 100644 --- a/tests/test_create_operator_class.rs +++ b/tests/test_create_operator_class.rs @@ -2,18 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE OPERATOR CLASS -// Description: define a new operator class -// Syntax: -// 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 -// } [, ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-createopclass.html - #[test] fn create_operator_class_parses() { run_cases(&[ diff --git a/tests/test_create_operator_family.rs b/tests/test_create_operator_family.rs index c3ad50b..ee868b6 100644 --- a/tests/test_create_operator_family.rs +++ b/tests/test_create_operator_family.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE OPERATOR FAMILY -// Description: define a new operator family -// Syntax: -// CREATE OPERATOR FAMILY name USING index_method -// -// URL: https://www.postgresql.org/docs/18/sql-createopfamily.html - #[test] fn create_operator_family_parses() { run_cases(&[r#"CREATE OPERATOR FAMILY my_family USING btree"#]); diff --git a/tests/test_create_policy.rs b/tests/test_create_policy.rs index 26f7dac..e871ac2 100644 --- a/tests/test_create_policy.rs +++ b/tests/test_create_policy.rs @@ -2,18 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE POLICY -// Description: define a new row-level security policy for a table -// Syntax: -// 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 ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createpolicy.html - #[test] fn create_policy_parses() { run_cases(&[ diff --git a/tests/test_create_procedure.rs b/tests/test_create_procedure.rs index 4bb5b6d..6fc57bf 100644 --- a/tests/test_create_procedure.rs +++ b/tests/test_create_procedure.rs @@ -2,22 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE PROCEDURE -// Description: define a new procedure -// Syntax: -// 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 -// } ... -// -// URL: https://www.postgresql.org/docs/18/sql-createprocedure.html - #[test] fn create_procedure_parses() { run_cases(&[ diff --git a/tests/test_create_publication.rs b/tests/test_create_publication.rs index babf66e..181efde 100644 --- a/tests/test_create_publication.rs +++ b/tests/test_create_publication.rs @@ -2,25 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE PUBLICATION -// Description: define a new publication -// Syntax: -// CREATE PUBLICATION name -// [ FOR ALL TABLES -// | FOR publication_object [, ... ] ] -// [ WITH ( publication_parameter [= value] [, ... ] ) ] -// -// where publication_object is one of: -// -// TABLE table_and_columns [, ... ] -// TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] -// -// and table_and_columns is: -// -// [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createpublication.html - #[test] fn create_publication_parses() { run_cases(&[ diff --git a/tests/test_create_role.rs b/tests/test_create_role.rs index ed585c1..86c5434 100644 --- a/tests/test_create_role.rs +++ b/tests/test_create_role.rs @@ -2,30 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE ROLE -// Description: define a new database role -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createrole.html - #[test] fn create_role_parses() { run_cases(&[ diff --git a/tests/test_create_rule.rs b/tests/test_create_rule.rs index 2d01ddc..3826329 100644 --- a/tests/test_create_rule.rs +++ b/tests/test_create_rule.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE RULE -// Description: define a new rewrite rule -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createrule.html - #[test] fn create_rule_parses() { run_cases(&[ diff --git a/tests/test_create_schema.rs b/tests/test_create_schema.rs index 4396a8a..57923f6 100644 --- a/tests/test_create_schema.rs +++ b/tests/test_create_schema.rs @@ -2,23 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE SCHEMA -// Description: define a new schema -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createschema.html - #[test] fn create_schema_parses() { run_cases(&[ diff --git a/tests/test_create_sequence.rs b/tests/test_create_sequence.rs index 3e4f566..15c5535 100644 --- a/tests/test_create_sequence.rs +++ b/tests/test_create_sequence.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE SEQUENCE -// Description: define a new sequence generator -// Syntax: -// CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name -// [ AS data_type ] -// [ INCREMENT [ BY ] increment ] -// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] -// [ [ NO ] CYCLE ] -// [ START [ WITH ] start ] -// [ CACHE cache ] -// [ OWNED BY { table_name.column_name | NONE } ] -// -// URL: https://www.postgresql.org/docs/18/sql-createsequence.html - #[test] fn create_sequence_parses() { run_cases(&[ diff --git a/tests/test_create_server.rs b/tests/test_create_server.rs index 3336c7e..71e6897 100644 --- a/tests/test_create_server.rs +++ b/tests/test_create_server.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE SERVER -// Description: define a new foreign server -// Syntax: -// CREATE SERVER [ IF NOT EXISTS ] server_name [ TYPE 'server_type' ] [ VERSION 'server_version' ] -// FOREIGN DATA WRAPPER fdw_name -// [ OPTIONS ( option 'value' [, ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createserver.html - #[test] fn create_server_parses() { run_cases(&[ diff --git a/tests/test_create_statistics.rs b/tests/test_create_statistics.rs index 5387dab..7269e71 100644 --- a/tests/test_create_statistics.rs +++ b/tests/test_create_statistics.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE STATISTICS -// Description: define extended statistics -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createstatistics.html - #[test] fn create_statistics_parses() { run_cases(&[ diff --git a/tests/test_create_subscription.rs b/tests/test_create_subscription.rs index 206d9a6..450ac71 100644 --- a/tests/test_create_subscription.rs +++ b/tests/test_create_subscription.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE SUBSCRIPTION -// Description: define a new subscription -// Syntax: -// CREATE SUBSCRIPTION subscription_name -// CONNECTION 'conninfo' -// PUBLICATION publication_name [, ...] -// [ WITH ( subscription_parameter [= value] [, ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createsubscription.html - #[test] fn create_subscription_parses() { run_cases(&[ diff --git a/tests/test_create_table.rs b/tests/test_create_table.rs index 44a0369..a918c65 100644 --- a/tests/test_create_table.rs +++ b/tests/test_create_table.rs @@ -237,92 +237,3 @@ fn create_table_partition_of_range_with_options() { "CREATE TABLE users_2024 PARTITION OF users FOR VALUES FROM ('2024-01-01') TO ('2025-01-01') USING heap WITH (fillfactor = 70) TABLESPACE fastspace", ); } - -// 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 ] - -// where column_constraint is: - -// [ CONSTRAINT constraint_name ] -// { NOT NULL [ NO INHERIT ] | -// NULL | -// CHECK ( expression ) [ NO INHERIT ] | -// DEFAULT default_expr | -// GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | -// 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 ] [ ENFORCED | NOT ENFORCED ] - -// and table_constraint is: - -// [ CONSTRAINT constraint_name ] -// { CHECK ( expression ) [ NO INHERIT ] | -// NOT NULL column_name [ NO INHERIT ] | -// UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | -// PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | -// EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | -// FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] -// [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -// [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] - -// and like_option is: - -// { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } - -// 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 ) - -// index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: - -// [ INCLUDE ( column_name [, ... ] ) ] -// [ WITH ( storage_parameter [= value] [, ... ] ) ] -// [ USING INDEX TABLESPACE tablespace_name ] - -// exclude_element in an EXCLUDE constraint is: - -// { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] - -// referential_action in a FOREIGN KEY/REFERENCES constraint is: - -// { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } diff --git a/tests/test_create_table_as.rs b/tests/test_create_table_as.rs index fd9612d..28b9483 100644 --- a/tests/test_create_table_as.rs +++ b/tests/test_create_table_as.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TABLE AS -// Description: define a new table from the results of a query -// Syntax: -// CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name -// [ (column_name [, ...] ) ] -// [ USING method ] -// [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] -// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] -// [ TABLESPACE tablespace_name ] -// AS query -// [ WITH [ NO ] DATA ] -// -// URL: https://www.postgresql.org/docs/18/sql-createtableas.html - #[test] fn create_table_as_parses() { run_cases(&[ diff --git a/tests/test_create_tablespace.rs b/tests/test_create_tablespace.rs index 48af316..2379d07 100644 --- a/tests/test_create_tablespace.rs +++ b/tests/test_create_tablespace.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TABLESPACE -// Description: define a new tablespace -// Syntax: -// CREATE TABLESPACE tablespace_name -// [ OWNER { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ] -// LOCATION 'directory' -// [ WITH ( tablespace_option = value [, ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createtablespace.html - #[test] fn create_tablespace_parses() { run_cases(&[ diff --git a/tests/test_create_text_search_configuration.rs b/tests/test_create_text_search_configuration.rs index 2d3c19d..306f2fe 100644 --- a/tests/test_create_text_search_configuration.rs +++ b/tests/test_create_text_search_configuration.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TEXT SEARCH CONFIGURATION -// Description: define a new text search configuration -// Syntax: -// CREATE TEXT SEARCH CONFIGURATION name ( -// PARSER = parser_name | -// COPY = source_config -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createtsconfig.html - #[test] fn create_text_search_configuration_parses() { run_cases(&[ diff --git a/tests/test_create_text_search_dictionary.rs b/tests/test_create_text_search_dictionary.rs index 3f193f6..53446fa 100644 --- a/tests/test_create_text_search_dictionary.rs +++ b/tests/test_create_text_search_dictionary.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TEXT SEARCH DICTIONARY -// Description: define a new text search dictionary -// Syntax: -// CREATE TEXT SEARCH DICTIONARY name ( -// TEMPLATE = template -// [, option = value [, ... ]] -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createtsdictionary.html - #[test] fn create_text_search_dictionary_parses() { run_cases(&[ diff --git a/tests/test_create_text_search_parser.rs b/tests/test_create_text_search_parser.rs index 3880d27..cf80e53 100644 --- a/tests/test_create_text_search_parser.rs +++ b/tests/test_create_text_search_parser.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TEXT SEARCH PARSER -// Description: define a new text search parser -// Syntax: -// CREATE TEXT SEARCH PARSER name ( -// START = start_function , -// GETTOKEN = gettoken_function , -// END = end_function , -// LEXTYPES = lextypes_function -// [, HEADLINE = headline_function ] -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createtsparser.html - #[test] fn create_text_search_parser_parses() { run_cases(&[ diff --git a/tests/test_create_text_search_template.rs b/tests/test_create_text_search_template.rs index c4081eb..c22a47a 100644 --- a/tests/test_create_text_search_template.rs +++ b/tests/test_create_text_search_template.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TEXT SEARCH TEMPLATE -// Description: define a new text search template -// Syntax: -// CREATE TEXT SEARCH TEMPLATE name ( -// [ INIT = init_function , ] -// LEXIZE = lexize_function -// ) -// -// URL: https://www.postgresql.org/docs/18/sql-createtstemplate.html - #[test] fn create_text_search_template_parses() { run_cases(&[ diff --git a/tests/test_create_transform.rs b/tests/test_create_transform.rs index 9f34b6b..aa4b139 100644 --- a/tests/test_create_transform.rs +++ b/tests/test_create_transform.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TRANSFORM -// Description: define a new transform -// Syntax: -// 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 [, ...]) ] -// ); -// -// URL: https://www.postgresql.org/docs/18/sql-createtransform.html - #[test] fn create_transform_parses() { run_cases(&[ diff --git a/tests/test_create_trigger.rs b/tests/test_create_trigger.rs index dc5d543..62214cc 100644 --- a/tests/test_create_trigger.rs +++ b/tests/test_create_trigger.rs @@ -2,27 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TRIGGER -// Description: define a new trigger -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createtrigger.html - #[test] fn create_trigger_parses() { run_cases(&[ diff --git a/tests/test_create_type.rs b/tests/test_create_type.rs index 503091c..313af1e 100644 --- a/tests/test_create_type.rs +++ b/tests/test_create_type.rs @@ -2,50 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE TYPE -// Description: define a new data type -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createtype.html - #[test] fn create_type_parses() { run_cases(&[ diff --git a/tests/test_create_user.rs b/tests/test_create_user.rs index 291230d..1284b5b 100644 --- a/tests/test_create_user.rs +++ b/tests/test_create_user.rs @@ -2,32 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE USER -// Description: define a new database role -// Syntax: -// 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 -// -// URL: https://www.postgresql.org/docs/18/sql-createuser.html - #[test] fn create_user_parses() { run_cases(&[ diff --git a/tests/test_create_user_mapping.rs b/tests/test_create_user_mapping.rs index f1f22c8..cc5532b 100644 --- a/tests/test_create_user_mapping.rs +++ b/tests/test_create_user_mapping.rs @@ -2,15 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE USER MAPPING -// Description: define a new mapping of a user to a foreign server -// Syntax: -// CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } -// SERVER server_name -// [ OPTIONS ( option 'value' [ , ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-createusermapping.html - #[test] fn create_user_mapping_parses() { run_cases(&[ diff --git a/tests/test_create_view.rs b/tests/test_create_view.rs index b8b8926..3694b3c 100644 --- a/tests/test_create_view.rs +++ b/tests/test_create_view.rs @@ -2,16 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: CREATE VIEW -// Description: define a new view -// Syntax: -// CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW name [ ( column_name [, ...] ) ] -// [ WITH ( view_option_name [= view_option_value] [, ... ] ) ] -// AS query -// [ WITH [ CASCADED | LOCAL ] CHECK OPTION ] -// -// URL: https://www.postgresql.org/docs/18/sql-createview.html - #[test] fn create_view_parses() { run_cases(&[ diff --git a/tests/test_delete_grammar.rs b/tests/test_delete_grammar.rs index 438d27a..00b7a27 100644 --- a/tests/test_delete_grammar.rs +++ b/tests/test_delete_grammar.rs @@ -57,15 +57,3 @@ fn delete_returning_variations() { "DELETE FROM users RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.id AS old_id, new_row.id AS new_id", ]); } - -// Command: DELETE -// Description: delete rows of a table -// Syntax: -// [ WITH [ RECURSIVE ] with_query [, ...] ] -// DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] -// [ USING from_item [, ...] ] -// [ WHERE condition | WHERE CURRENT OF cursor_name ] -// [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] -// { * | output_expression [ [ AS ] output_name ] } [, ...] ] -// -// URL: https://www.postgresql.org/docs/18/sql-delete.html diff --git a/tests/test_drop.rs b/tests/test_drop.rs index 2dc610f..717f440 100644 --- a/tests/test_drop.rs +++ b/tests/test_drop.rs @@ -2,320 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP ACCESS METHOD -// Description: remove an access method -// Syntax: -// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-drop-access-method.html -// -// Command: DROP AGGREGATE -// Description: remove an aggregate function -// Syntax: -// DROP AGGREGATE [ IF EXISTS ] name ( aggregate_signature ) [, ...] [ CASCADE | RESTRICT ] -// -// where aggregate_signature is: -// -// * | -// [ argmode ] [ argname ] argtype [ , ... ] | -// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropaggregate.html -// -// Command: DROP CAST -// Description: remove a cast -// Syntax: -// DROP CAST [ IF EXISTS ] (source_type AS target_type) [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropcast.html -// -// Command: DROP COLLATION -// Description: remove a collation -// Syntax: -// DROP COLLATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropcollation.html -// -// Command: DROP CONVERSION -// Description: remove a conversion -// Syntax: -// DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropconversion.html -// -// Command: DROP DATABASE -// Description: remove a database -// Syntax: -// DROP DATABASE [ IF EXISTS ] name [ [ WITH ] ( option [, ...] ) ] -// -// where option can be: -// -// FORCE -// -// URL: https://www.postgresql.org/docs/18/sql-dropdatabase.html -// -// Command: DROP DOMAIN -// Description: remove a domain -// Syntax: -// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropdomain.html -// -// Command: DROP EVENT TRIGGER -// Description: remove an event trigger -// Syntax: -// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropeventtrigger.html -// -// Command: DROP EXTENSION -// Description: remove an extension -// Syntax: -// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropextension.html -// -// Command: DROP FOREIGN DATA WRAPPER -// Description: remove a foreign-data wrapper -// Syntax: -// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropforeigndatawrapper.html -// -// Command: DROP FOREIGN TABLE -// Description: remove a foreign table -// Syntax: -// DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropforeigntable.html -// -// Command: DROP FUNCTION -// Description: remove a function -// Syntax: -// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropfunction.html -// -// Command: DROP GROUP -// Description: remove a database role -// Syntax: -// DROP GROUP [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-dropgroup.html -// -// Command: DROP INDEX -// Description: remove an index -// Syntax: -// DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropindex.html -// -// Command: DROP LANGUAGE -// Description: remove a procedural language -// Syntax: -// DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droplanguage.html -// -// Command: DROP MATERIALIZED VIEW -// Description: remove a materialized view -// Syntax: -// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropmaterializedview.html -// -// Command: DROP OPERATOR -// Description: remove an operator -// Syntax: -// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropoperator.html -// -// Command: DROP OPERATOR CLASS -// Description: remove an operator class -// Syntax: -// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropopclass.html -// -// Command: DROP OPERATOR FAMILY -// Description: remove an operator family -// Syntax: -// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropopfamily.html -// -// Command: DROP OWNED -// Description: remove database objects owned by a database role -// Syntax: -// DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-drop-owned.html -// -// Command: DROP POLICY -// Description: remove a row-level security policy from a table -// Syntax: -// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droppolicy.html -// -// Command: DROP PROCEDURE -// Description: remove a procedure -// Syntax: -// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropprocedure.html -// -// Command: DROP PUBLICATION -// Description: remove a publication -// Syntax: -// DROP PUBLICATION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droppublication.html -// -// Command: DROP ROLE -// Description: remove a database role -// Syntax: -// DROP ROLE [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-droprole.html -// -// Command: DROP ROUTINE -// Description: remove a routine -// Syntax: -// DROP ROUTINE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droproutine.html -// -// Command: DROP RULE -// Description: remove a rewrite rule -// Syntax: -// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droprule.html -// -// Command: DROP SCHEMA -// Description: remove a schema -// Syntax: -// DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropschema.html -// -// Command: DROP SEQUENCE -// Description: remove a sequence -// Syntax: -// DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropsequence.html -// -// Command: DROP SERVER -// Description: remove a foreign server descriptor -// Syntax: -// DROP SERVER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropserver.html -// -// Command: DROP STATISTICS -// Description: remove extended statistics -// Syntax: -// DROP STATISTICS [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropstatistics.html -// -// Command: DROP SUBSCRIPTION -// Description: remove a subscription -// Syntax: -// DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropsubscription.html -// -// Command: DROP TABLE -// Description: remove a table -// Syntax: -// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptable.html -// -// Command: DROP TABLESPACE -// Description: remove a tablespace -// Syntax: -// DROP TABLESPACE [ IF EXISTS ] name -// -// URL: https://www.postgresql.org/docs/18/sql-droptablespace.html -// -// Command: DROP TEXT SEARCH CONFIGURATION -// Description: remove a text search configuration -// Syntax: -// DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsconfig.html -// -// Command: DROP TEXT SEARCH DICTIONARY -// Description: remove a text search dictionary -// Syntax: -// DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsdictionary.html -// -// Command: DROP TEXT SEARCH PARSER -// Description: remove a text search parser -// Syntax: -// DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsparser.html -// -// Command: DROP TEXT SEARCH TEMPLATE -// Description: remove a text search template -// Syntax: -// DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptstemplate.html -// -// Command: DROP TRANSFORM -// Description: remove a transform -// Syntax: -// DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptransform.html -// -// Command: DROP TRIGGER -// Description: remove a trigger -// Syntax: -// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptrigger.html -// -// Command: DROP TYPE -// Description: remove a data type -// Syntax: -// DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptype.html -// -// Command: DROP USER -// Description: remove a database role -// Syntax: -// DROP USER [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-dropuser.html -// -// Command: DROP USER MAPPING -// Description: remove a user mapping for a foreign server -// Syntax: -// DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name -// -// URL: https://www.postgresql.org/docs/18/sql-dropusermapping.html -// -// Command: DROP VIEW -// Description: remove a view -// Syntax: -// DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropview.html - #[test] fn drop_parses() { run_cases(&[ diff --git a/tests/test_drop_access_method.rs b/tests/test_drop_access_method.rs index ac7e943..fd319da 100644 --- a/tests/test_drop_access_method.rs +++ b/tests/test_drop_access_method.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP ACCESS METHOD -// Description: remove an access method -// Syntax: -// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-drop-access-method.html - #[test] fn drop_access_method_parses() { run_cases(&[ diff --git a/tests/test_drop_aggregate.rs b/tests/test_drop_aggregate.rs index d81bd6e..76525ab 100644 --- a/tests/test_drop_aggregate.rs +++ b/tests/test_drop_aggregate.rs @@ -2,19 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP AGGREGATE -// Description: remove an aggregate function -// Syntax: -// DROP AGGREGATE [ IF EXISTS ] name ( aggregate_signature ) [, ...] [ CASCADE | RESTRICT ] -// -// where aggregate_signature is: -// -// * | -// [ argmode ] [ argname ] argtype [ , ... ] | -// [ [ argmode ] [ argname ] argtype [ , ... ] ] ORDER BY [ argmode ] [ argname ] argtype [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropaggregate.html - #[test] fn drop_aggregate_parses() { run_cases(&[ diff --git a/tests/test_drop_cast.rs b/tests/test_drop_cast.rs index 10754ec..05a093f 100644 --- a/tests/test_drop_cast.rs +++ b/tests/test_drop_cast.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP CAST -// Description: remove a cast -// Syntax: -// DROP CAST [ IF EXISTS ] (source_type AS target_type) [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropcast.html - #[test] fn drop_cast_parses() { run_cases(&[ diff --git a/tests/test_drop_collation.rs b/tests/test_drop_collation.rs index 23257ae..3879a2c 100644 --- a/tests/test_drop_collation.rs +++ b/tests/test_drop_collation.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP COLLATION -// Description: remove a collation -// Syntax: -// DROP COLLATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropcollation.html - #[test] fn drop_collation_parses() { run_cases(&[ diff --git a/tests/test_drop_conversion.rs b/tests/test_drop_conversion.rs index 2fd4612..43d15f4 100644 --- a/tests/test_drop_conversion.rs +++ b/tests/test_drop_conversion.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP CONVERSION -// Description: remove a conversion -// Syntax: -// DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropconversion.html - #[test] fn drop_conversion_parses() { run_cases(&[ diff --git a/tests/test_drop_database.rs b/tests/test_drop_database.rs index 351925b..ad93bd7 100644 --- a/tests/test_drop_database.rs +++ b/tests/test_drop_database.rs @@ -2,17 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP DATABASE -// Description: remove a database -// Syntax: -// DROP DATABASE [ IF EXISTS ] name [ [ WITH ] ( option [, ...] ) ] -// -// where option can be: -// -// FORCE -// -// URL: https://www.postgresql.org/docs/18/sql-dropdatabase.html - #[test] fn drop_database_parses() { run_cases(&[ diff --git a/tests/test_drop_domain.rs b/tests/test_drop_domain.rs index 3162ceb..ce76f55 100644 --- a/tests/test_drop_domain.rs +++ b/tests/test_drop_domain.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP DOMAIN -// Description: remove a domain -// Syntax: -// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropdomain.html - #[test] fn drop_domain_parses() { run_cases(&[ diff --git a/tests/test_drop_event_trigger.rs b/tests/test_drop_event_trigger.rs index 832662b..46b1a05 100644 --- a/tests/test_drop_event_trigger.rs +++ b/tests/test_drop_event_trigger.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP EVENT TRIGGER -// Description: remove an event trigger -// Syntax: -// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropeventtrigger.html - #[test] fn drop_event_trigger_parses() { run_cases(&[ diff --git a/tests/test_drop_extension.rs b/tests/test_drop_extension.rs index b003c22..5ccf5e4 100644 --- a/tests/test_drop_extension.rs +++ b/tests/test_drop_extension.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP EXTENSION -// Description: remove an extension -// Syntax: -// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropextension.html - #[test] fn drop_extension_parses() { run_cases(&[ diff --git a/tests/test_drop_foreign_data_wrapper.rs b/tests/test_drop_foreign_data_wrapper.rs index 546de5b..0ac1c26 100644 --- a/tests/test_drop_foreign_data_wrapper.rs +++ b/tests/test_drop_foreign_data_wrapper.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP FOREIGN DATA WRAPPER -// Description: remove a foreign-data wrapper -// Syntax: -// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropforeigndatawrapper.html - #[test] fn drop_foreign_data_wrapper_parses() { run_cases(&[ diff --git a/tests/test_drop_foreign_table.rs b/tests/test_drop_foreign_table.rs index 883279a..c8547cb 100644 --- a/tests/test_drop_foreign_table.rs +++ b/tests/test_drop_foreign_table.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP FOREIGN TABLE -// Description: remove a foreign table -// Syntax: -// DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropforeigntable.html - #[test] fn drop_foreign_table_parses() { run_cases(&[ diff --git a/tests/test_drop_function.rs b/tests/test_drop_function.rs index 8e859de..52f755a 100644 --- a/tests/test_drop_function.rs +++ b/tests/test_drop_function.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP FUNCTION -// Description: remove a function -// Syntax: -// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropfunction.html - #[test] fn drop_function_parses() { run_cases(&[ diff --git a/tests/test_drop_group.rs b/tests/test_drop_group.rs index 068b22c..699ac15 100644 --- a/tests/test_drop_group.rs +++ b/tests/test_drop_group.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP GROUP -// Description: remove a database role -// Syntax: -// DROP GROUP [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-dropgroup.html - #[test] fn drop_group_parses() { run_cases(&[ diff --git a/tests/test_drop_index.rs b/tests/test_drop_index.rs index 0f5fa5c..463f9a4 100644 --- a/tests/test_drop_index.rs +++ b/tests/test_drop_index.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP INDEX -// Description: remove an index -// Syntax: -// DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropindex.html - #[test] fn drop_index_parses() { run_cases(&[ diff --git a/tests/test_drop_language.rs b/tests/test_drop_language.rs index 1d626dd..a637e02 100644 --- a/tests/test_drop_language.rs +++ b/tests/test_drop_language.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP LANGUAGE -// Description: remove a procedural language -// Syntax: -// DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droplanguage.html - #[test] fn drop_language_parses() { run_cases(&[ diff --git a/tests/test_drop_materialized_view.rs b/tests/test_drop_materialized_view.rs index 40be3cc..48f8f4f 100644 --- a/tests/test_drop_materialized_view.rs +++ b/tests/test_drop_materialized_view.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP MATERIALIZED VIEW -// Description: remove a materialized view -// Syntax: -// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropmaterializedview.html - #[test] fn drop_materialized_view_parses() { run_cases(&[ diff --git a/tests/test_drop_operator.rs b/tests/test_drop_operator.rs index be30ac4..95d4c5a 100644 --- a/tests/test_drop_operator.rs +++ b/tests/test_drop_operator.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP OPERATOR -// Description: remove an operator -// Syntax: -// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropoperator.html - #[test] fn drop_operator_parses() { run_cases(&[ diff --git a/tests/test_drop_operator_class.rs b/tests/test_drop_operator_class.rs index 8a75ded..ace6972 100644 --- a/tests/test_drop_operator_class.rs +++ b/tests/test_drop_operator_class.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP OPERATOR CLASS -// Description: remove an operator class -// Syntax: -// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropopclass.html - #[test] fn drop_operator_class_parses() { run_cases(&[ diff --git a/tests/test_drop_operator_family.rs b/tests/test_drop_operator_family.rs index bf6f23e..56cb3cc 100644 --- a/tests/test_drop_operator_family.rs +++ b/tests/test_drop_operator_family.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP OPERATOR FAMILY -// Description: remove an operator family -// Syntax: -// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropopfamily.html - #[test] fn drop_operator_family_parses() { run_cases(&[ diff --git a/tests/test_drop_owned.rs b/tests/test_drop_owned.rs index 435375c..fe76d08 100644 --- a/tests/test_drop_owned.rs +++ b/tests/test_drop_owned.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP OWNED -// Description: remove database objects owned by a database role -// Syntax: -// DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-drop-owned.html - #[test] fn drop_owned_parses() { run_cases(&[ diff --git a/tests/test_drop_policy.rs b/tests/test_drop_policy.rs index 043b5ca..c4d22c0 100644 --- a/tests/test_drop_policy.rs +++ b/tests/test_drop_policy.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP POLICY -// Description: remove a row-level security policy from a table -// Syntax: -// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droppolicy.html - #[test] fn drop_policy_parses() { run_cases(&[ diff --git a/tests/test_drop_procedure.rs b/tests/test_drop_procedure.rs index 09f9490..544654f 100644 --- a/tests/test_drop_procedure.rs +++ b/tests/test_drop_procedure.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP PROCEDURE -// Description: remove a procedure -// Syntax: -// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropprocedure.html - #[test] fn drop_procedure_parses() { run_cases(&[ diff --git a/tests/test_drop_publication.rs b/tests/test_drop_publication.rs index 996a4d1..899156c 100644 --- a/tests/test_drop_publication.rs +++ b/tests/test_drop_publication.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP PUBLICATION -// Description: remove a publication -// Syntax: -// DROP PUBLICATION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droppublication.html - #[test] fn drop_publication_parses() { run_cases(&[ diff --git a/tests/test_drop_role.rs b/tests/test_drop_role.rs index 51f509e..94c7d24 100644 --- a/tests/test_drop_role.rs +++ b/tests/test_drop_role.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP ROLE -// Description: remove a database role -// Syntax: -// DROP ROLE [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-droprole.html - #[test] fn drop_role_parses() { run_cases(&[ diff --git a/tests/test_drop_routine.rs b/tests/test_drop_routine.rs index afca9c7..d58d685 100644 --- a/tests/test_drop_routine.rs +++ b/tests/test_drop_routine.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP ROUTINE -// Description: remove a routine -// Syntax: -// DROP ROUTINE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] -// [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droproutine.html - #[test] fn drop_routine_parses() { run_cases(&[ diff --git a/tests/test_drop_rule.rs b/tests/test_drop_rule.rs index a743ef9..5f227e5 100644 --- a/tests/test_drop_rule.rs +++ b/tests/test_drop_rule.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP RULE -// Description: remove a rewrite rule -// Syntax: -// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droprule.html - #[test] fn drop_rule_parses() { run_cases(&[ diff --git a/tests/test_drop_schema.rs b/tests/test_drop_schema.rs index aa3b2cd..73c895f 100644 --- a/tests/test_drop_schema.rs +++ b/tests/test_drop_schema.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP SCHEMA -// Description: remove a schema -// Syntax: -// DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropschema.html - #[test] fn drop_schema_parses() { run_cases(&[ diff --git a/tests/test_drop_sequence.rs b/tests/test_drop_sequence.rs index a993bec..d8b1081 100644 --- a/tests/test_drop_sequence.rs +++ b/tests/test_drop_sequence.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP SEQUENCE -// Description: remove a sequence -// Syntax: -// DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropsequence.html - #[test] fn drop_sequence_parses() { run_cases(&[ diff --git a/tests/test_drop_server.rs b/tests/test_drop_server.rs index 7d9d12d..31fd820 100644 --- a/tests/test_drop_server.rs +++ b/tests/test_drop_server.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP SERVER -// Description: remove a foreign server descriptor -// Syntax: -// DROP SERVER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropserver.html - #[test] fn drop_server_parses() { run_cases(&[ diff --git a/tests/test_drop_statistics.rs b/tests/test_drop_statistics.rs index cbee752..ee0080c 100644 --- a/tests/test_drop_statistics.rs +++ b/tests/test_drop_statistics.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP STATISTICS -// Description: remove extended statistics -// Syntax: -// DROP STATISTICS [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropstatistics.html - #[test] fn drop_statistics_parses() { run_cases(&[ diff --git a/tests/test_drop_subscription.rs b/tests/test_drop_subscription.rs index d31b5a3..bdaab96 100644 --- a/tests/test_drop_subscription.rs +++ b/tests/test_drop_subscription.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP SUBSCRIPTION -// Description: remove a subscription -// Syntax: -// DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropsubscription.html - #[test] fn drop_subscription_parses() { run_cases(&[ diff --git a/tests/test_drop_table.rs b/tests/test_drop_table.rs index d9f63ec..eeec558 100644 --- a/tests/test_drop_table.rs +++ b/tests/test_drop_table.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TABLE -// Description: remove a table -// Syntax: -// DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptable.html - #[test] fn drop_table_parses() { run_cases(&[ diff --git a/tests/test_drop_tablespace.rs b/tests/test_drop_tablespace.rs index 1fcb4e4..45bc86a 100644 --- a/tests/test_drop_tablespace.rs +++ b/tests/test_drop_tablespace.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TABLESPACE -// Description: remove a tablespace -// Syntax: -// DROP TABLESPACE [ IF EXISTS ] name -// -// URL: https://www.postgresql.org/docs/18/sql-droptablespace.html - #[test] fn drop_tablespace_parses() { run_cases(&[ diff --git a/tests/test_drop_text_search_configuration.rs b/tests/test_drop_text_search_configuration.rs index cbdb401..417fd11 100644 --- a/tests/test_drop_text_search_configuration.rs +++ b/tests/test_drop_text_search_configuration.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TEXT SEARCH CONFIGURATION -// Description: remove a text search configuration -// Syntax: -// DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsconfig.html - #[test] fn drop_text_search_configuration_parses() { run_cases(&[ diff --git a/tests/test_drop_text_search_dictionary.rs b/tests/test_drop_text_search_dictionary.rs index f60e817..c5a4972 100644 --- a/tests/test_drop_text_search_dictionary.rs +++ b/tests/test_drop_text_search_dictionary.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TEXT SEARCH DICTIONARY -// Description: remove a text search dictionary -// Syntax: -// DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsdictionary.html - #[test] fn drop_text_search_dictionary_parses() { run_cases(&[ diff --git a/tests/test_drop_text_search_parser.rs b/tests/test_drop_text_search_parser.rs index 2d312a7..d13ab73 100644 --- a/tests/test_drop_text_search_parser.rs +++ b/tests/test_drop_text_search_parser.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TEXT SEARCH PARSER -// Description: remove a text search parser -// Syntax: -// DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptsparser.html - #[test] fn drop_text_search_parser_parses() { run_cases(&[ diff --git a/tests/test_drop_text_search_template.rs b/tests/test_drop_text_search_template.rs index 729a5e4..3098b71 100644 --- a/tests/test_drop_text_search_template.rs +++ b/tests/test_drop_text_search_template.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TEXT SEARCH TEMPLATE -// Description: remove a text search template -// Syntax: -// DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptstemplate.html - #[test] fn drop_text_search_template_parses() { run_cases(&[ diff --git a/tests/test_drop_transform.rs b/tests/test_drop_transform.rs index 5684097..e33bdd0 100644 --- a/tests/test_drop_transform.rs +++ b/tests/test_drop_transform.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TRANSFORM -// Description: remove a transform -// Syntax: -// DROP TRANSFORM [ IF EXISTS ] FOR type_name LANGUAGE lang_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptransform.html - #[test] fn drop_transform_parses() { run_cases(&[ diff --git a/tests/test_drop_trigger.rs b/tests/test_drop_trigger.rs index 88a37d1..220e828 100644 --- a/tests/test_drop_trigger.rs +++ b/tests/test_drop_trigger.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TRIGGER -// Description: remove a trigger -// Syntax: -// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptrigger.html - #[test] fn drop_trigger_parses() { run_cases(&[ diff --git a/tests/test_drop_type.rs b/tests/test_drop_type.rs index 32904da..914df29 100644 --- a/tests/test_drop_type.rs +++ b/tests/test_drop_type.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP TYPE -// Description: remove a data type -// Syntax: -// DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-droptype.html - #[test] fn drop_type_parses() { run_cases(&[ diff --git a/tests/test_drop_user.rs b/tests/test_drop_user.rs index 471806d..1e00754 100644 --- a/tests/test_drop_user.rs +++ b/tests/test_drop_user.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP USER -// Description: remove a database role -// Syntax: -// DROP USER [ IF EXISTS ] name [, ...] -// -// URL: https://www.postgresql.org/docs/18/sql-dropuser.html - #[test] fn drop_user_parses() { run_cases(&[ diff --git a/tests/test_drop_user_mapping.rs b/tests/test_drop_user_mapping.rs index 2a60e54..3610cd0 100644 --- a/tests/test_drop_user_mapping.rs +++ b/tests/test_drop_user_mapping.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP USER MAPPING -// Description: remove a user mapping for a foreign server -// Syntax: -// DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name -// -// URL: https://www.postgresql.org/docs/18/sql-dropusermapping.html - #[test] fn drop_user_mapping_parses() { run_cases(&[ diff --git a/tests/test_drop_view.rs b/tests/test_drop_view.rs index 2548a58..808ca4f 100644 --- a/tests/test_drop_view.rs +++ b/tests/test_drop_view.rs @@ -2,13 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: DROP VIEW -// Description: remove a view -// Syntax: -// DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-dropview.html - #[test] fn drop_view_parses() { run_cases(&[ diff --git a/tests/test_import_foreign_schema.rs b/tests/test_import_foreign_schema.rs index 9747ebd..98839e2 100644 --- a/tests/test_import_foreign_schema.rs +++ b/tests/test_import_foreign_schema.rs @@ -2,17 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: IMPORT FOREIGN SCHEMA -// Description: import table definitions from a foreign server -// Syntax: -// IMPORT FOREIGN SCHEMA remote_schema -// [ { LIMIT TO | EXCEPT } ( table_name [, ...] ) ] -// FROM SERVER server_name -// INTO local_schema -// [ OPTIONS ( option 'value' [, ... ] ) ] -// -// URL: https://www.postgresql.org/docs/18/sql-importforeignschema.html - #[test] fn import_foreign_schema_parses() { run_cases(&[ diff --git a/tests/test_insert_grammar.rs b/tests/test_insert_grammar.rs index d6862f7..3a28f21 100644 --- a/tests/test_insert_grammar.rs +++ b/tests/test_insert_grammar.rs @@ -82,30 +82,3 @@ fn insert_returning_variations() { "INSERT INTO users (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.id AS old_id, new_row.id AS new_id", ]); } - -// Command: INSERT -// Description: create new rows in a table -// Syntax: -// [ 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 [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] -// { * | 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-insert.html diff --git a/tests/test_refresh_materialized_view.rs b/tests/test_refresh_materialized_view.rs index 99c04cc..08a9981 100644 --- a/tests/test_refresh_materialized_view.rs +++ b/tests/test_refresh_materialized_view.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: REFRESH MATERIALIZED VIEW -// Description: replace the contents of a materialized view -// Syntax: -// REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name -// [ WITH [ NO ] DATA ] -// -// URL: https://www.postgresql.org/docs/18/sql-refreshmaterializedview.html - #[test] fn refresh_materialized_view_parses() { run_cases(&[ diff --git a/tests/test_reindex.rs b/tests/test_reindex.rs index bc85396..4d53433 100644 --- a/tests/test_reindex.rs +++ b/tests/test_reindex.rs @@ -2,20 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: REINDEX -// Description: rebuild indexes -// Syntax: -// 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 ] -// -// URL: https://www.postgresql.org/docs/18/sql-reindex.html - #[test] fn reindex_parses() { run_cases(&[ diff --git a/tests/test_security_label.rs b/tests/test_security_label.rs index 27dcd05..80216e3 100644 --- a/tests/test_security_label.rs +++ b/tests/test_security_label.rs @@ -2,42 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: SECURITY LABEL -// Description: define or change a security label applied to an object -// Syntax: -// 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 [ , ... ] -// -// URL: https://www.postgresql.org/docs/18/sql-security-label.html - #[test] fn security_label_parses() { run_cases(&[ diff --git a/tests/test_select_grammar.rs b/tests/test_select_grammar.rs index 866452d..5c1f3f7 100644 --- a/tests/test_select_grammar.rs +++ b/tests/test_select_grammar.rs @@ -180,56 +180,3 @@ fn parameter_variations() { "SELECT id FROM users ORDER BY id FETCH NEXT $1 ROWS WITH TIES", ]); } - -// Command: SELECT -// Description: retrieve rows from a table or view -// Syntax: -// [ WITH [ RECURSIVE ] with_query [, ...] ] -// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] -// [ { * | expression [ [ AS ] output_name ] } [, ...] ] -// [ FROM from_item [, ...] ] -// [ WHERE condition ] -// [ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ] -// [ HAVING condition ] -// [ WINDOW window_name AS ( window_definition ) [, ...] ] -// [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] -// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] -// [ LIMIT { count | ALL } ] -// [ OFFSET start [ ROW | ROWS ] ] -// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ] -// [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF from_reference [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ] - -// where from_item can be one of: - -// [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] -// [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] -// [ LATERAL ] ( select ) [ [ AS ] alias [ ( column_alias [, ...] ) ] ] -// 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 - -// and grouping_element can be one of: - -// ( ) -// expression -// ( expression [, ...] ) -// ROLLUP ( { expression | ( expression [, ...] ) } [, ...] ) -// CUBE ( { expression | ( expression [, ...] ) } [, ...] ) -// GROUPING SETS ( grouping_element [, ...] ) - -// and with_query is: - -// 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 ] - -// TABLE [ ONLY ] table_name [ * ] -// -// URL: https://www.postgresql.org/docs/18/sql-select.html diff --git a/tests/test_select_into.rs b/tests/test_select_into.rs index e999cb0..2c8ebf6 100644 --- a/tests/test_select_into.rs +++ b/tests/test_select_into.rs @@ -2,27 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: SELECT INTO -// Description: define a new table from the results of a query -// Syntax: -// [ WITH [ RECURSIVE ] with_query [, ...] ] -// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] -// [ { * | expression [ [ AS ] output_name ] } [, ...] ] -// INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] new_table -// [ FROM from_item [, ...] ] -// [ WHERE condition ] -// [ GROUP BY expression [, ...] ] -// [ HAVING condition ] -// [ WINDOW window_name AS ( window_definition ) [, ...] ] -// [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] -// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] -// [ LIMIT { count | ALL } ] -// [ OFFSET start [ ROW | ROWS ] ] -// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] -// [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] -// -// URL: https://www.postgresql.org/docs/18/sql-selectinto.html - #[test] fn select_into_parses() { run_cases(&[ diff --git a/tests/test_truncate.rs b/tests/test_truncate.rs index 8369395..82c46fd 100644 --- a/tests/test_truncate.rs +++ b/tests/test_truncate.rs @@ -2,14 +2,6 @@ mod common; use common::run_parse_debug_cases as run_cases; -// Command: TRUNCATE -// Description: empty a table or set of tables -// Syntax: -// TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ] -// [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ] -// -// URL: https://www.postgresql.org/docs/18/sql-truncate.html - #[test] fn truncate_parses() { run_cases(&[ diff --git a/tests/test_update_grammar.rs b/tests/test_update_grammar.rs index 90688fc..e2e77fd 100644 --- a/tests/test_update_grammar.rs +++ b/tests/test_update_grammar.rs @@ -69,19 +69,3 @@ fn update_returning_variations() { "UPDATE users SET active = true RETURNING WITH (OLD AS old_row, NEW AS new_row) old_row.active AS was_active, new_row.active AS is_active", ]); } - -// Command: UPDATE -// Description: update rows of a table -// Syntax: -// [ 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 [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] -// { * | output_expression [ [ AS ] output_name ] } [, ...] ] -// -// URL: https://www.postgresql.org/docs/18/sql-update.html