diff --git a/crates/pgls_statement_splitter/src/splitter/common.rs b/crates/pgls_statement_splitter/src/splitter/common.rs index 18703e592..f98b5cf84 100644 --- a/crates/pgls_statement_splitter/src/splitter/common.rs +++ b/crates/pgls_statement_splitter/src/splitter/common.rs @@ -224,6 +224,18 @@ pub(crate) fn unknown(p: &mut Splitter, exclude: &[SyntaxKind]) -> SplitterResul begin_end(p)?; } }, + // When WITH_KW is excluded (e.g. inside CREATE) and followed by + // an identifier or RECURSIVE, it starts a CTE. Parse it as such + // so the following DML keyword is not treated as a new statement. + t if t == SyntaxKind::WITH_KW + && exclude.contains(&SyntaxKind::WITH_KW) + && matches!( + p.look_ahead(true), + SyntaxKind::IDENT | SyntaxKind::RECURSIVE_KW + ) => + { + cte(p)?; + } t => match at_statement_start(t, exclude) { Some(SyntaxKind::SELECT_KW) => { let prev = p.look_back(true); diff --git a/crates/pgls_statement_splitter/tests/data/create_table_with_storage__1.sql b/crates/pgls_statement_splitter/tests/data/create_table_with_storage__1.sql new file mode 100644 index 000000000..98ed6429c --- /dev/null +++ b/crates/pgls_statement_splitter/tests/data/create_table_with_storage__1.sql @@ -0,0 +1 @@ +CREATE TABLE foo (id int) WITH (fillfactor=70); diff --git a/crates/pgls_statement_splitter/tests/data/create_view_with_cte__1.sql b/crates/pgls_statement_splitter/tests/data/create_view_with_cte__1.sql new file mode 100644 index 000000000..1e0191929 --- /dev/null +++ b/crates/pgls_statement_splitter/tests/data/create_view_with_cte__1.sql @@ -0,0 +1 @@ +CREATE OR REPLACE VIEW profile_view AS WITH user_cte AS (SELECT * FROM accounts) SELECT * FROM user_cte;