Skip to content

Commit 19d77ca

Browse files
committed
feat: parse PostgreSQL policies, statistics and foreign objects
Continue the native PostgreSQL grammar with CREATE/ALTER POLICY and extended statistics, preserving policy modes, commands, roles and predicates as AST children. Retain the distinction between statistics columns, function calls and parenthesized expressions, and reuse native FROM parsing for relations, aliases and joins. Support statistics targets and object identity changes. Add foreign data wrappers, servers, user mappings and foreign tables, plus IMPORT FOREIGN SCHEMA. Preserve handler/validator names, server type/version, mapping roles, inheritance and partition clauses, relation lists and generic option names/string values. CREATE option pairs and ALTER ADD/SET/DROP actions have validated productions. Extend shared column definitions for PostgreSQL STORAGE, COMPRESSION and OPTIONS syntax without a raw SQL tail fallback. Append IMPORT_FOREIGN_SCHEMA to the statement types and update compatibility mapping/name tests. Reuse guarded DDL nodes, keeping enum values, the 48-byte AST layout and MySQL behavior intact. Parsing these statements does not execute policies, collect statistics, contact foreign servers or import data. There is no PostgreSQL fallback or new production parser dependency. Add positive and malformed fixtures, structured AST traversal/editing, reconstruction, unsupported execution/parameterization and arena exhaustion checks. Fix the IMPORT allocation-failure null dereference exposed by the expanded arena sweep, and cover the grammar boundary cases found in review. Document supported forms and the remaining shared ALTER CONSTRAINT gap. Validation: - Forced full build and corpus executable: 1,483 passed; 37 tests requiring external databases skipped. - New grammar suites under ASan/UBSan: 11/11 passed. - Compatibility harness: 87 tests passed. - Same 51,415 PostgreSQL 18.4 source statements: 49,120 deeply supported (95.5%), +807 over 398450a, with no previously supported cases lost. - All 807 newly supported statements reconstruct to equivalent PostgreSQL raw ASTs after excluding source-position fields only. - Independent task and integrated grammar review, including targeted oracle checks for malformed options, roles and ALTER FOREIGN TABLE boundaries. The correctness snapshot follows in a separate commit. Benchmark files and benchmark-only README/.gitignore changes remain excluded.
1 parent 398450a commit 19d77ca

9 files changed

Lines changed: 715 additions & 8 deletions

File tree

‎Makefile‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ TEST_SRCS = $(TEST_DIR)/test_main.cpp \
5959
$(TEST_DIR)/test_pg_expression_continuation.cpp \
6060
$(TEST_DIR)/test_pg_object_ddl.cpp \
6161
$(TEST_DIR)/test_pg_definitions.cpp \
62+
$(TEST_DIR)/test_pg_policy_statistics.cpp \
63+
$(TEST_DIR)/test_pg_foreign_ddl.cpp \
6264
$(TEST_DIR)/test_pg_admin_commands.cpp \
6365
$(TEST_DIR)/test_pg_session_commands.cpp \
6466
$(TEST_DIR)/test_pg_dml_extensions.cpp \

‎docs/postgresql-analysis-features.md‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,27 @@ change a database session. Integer positions in the new role, cursor and
168168
operator-class productions validate PostgreSQL bounds, base prefixes and digit
169169
separators.
170170

171+
Policies retain permissive/restrictive mode, command and role lists, USING and
172+
WITH CHECK predicates, and ALTER/RENAME/DROP forms. Extended statistics retain
173+
their optional name and kinds, column/function/expression parameters and FROM
174+
relations, including aliases and joins. ALTER STATISTICS supports target,
175+
owner, schema and name changes. These are native structured DDL productions;
176+
they do not enable local policy enforcement or statistics collection.
177+
178+
Foreign-object DDL includes wrappers and handler/validator options, servers,
179+
user mappings, foreign tables and IMPORT FOREIGN SCHEMA. CREATE option pairs
180+
and ALTER ADD/SET/DROP options retain names and string literals as AST children.
181+
Foreign tables support columns, inheritance and partition forms through the
182+
supported table/constraint grammar. IMPORT retains LIMIT TO/EXCEPT relation
183+
lists and schema/server names; its appended statement type is
184+
`IMPORT_FOREIGN_SCHEMA`. Column STORAGE, COMPRESSION and OPTIONS also follow
185+
the shared PostgreSQL column-definition grammar on ordinary tables. Parsing
186+
does not connect to foreign servers or import database objects.
187+
171188
Coverage is still a subset of PostgreSQL. Remaining examples include embedded
172189
CREATE SCHEMA elements, CREATE DATABASE options, other object-specific ALTER
173-
commands, foreign-table and policy/publication DDL, rules, unquoted SQL function
190+
commands, further ALTER TABLE/FOREIGN TABLE actions such as ALTER CONSTRAINT,
191+
publication DDL, rules, unquoted SQL function
174192
bodies, exclusion constraints, less common DDL options, assignment slices and
175193
full ON CONFLICT index-inference options. Less common equivalent type spellings
176194
in ordered variadic signatures, `%TYPE` definition arguments and modifying
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# PostgreSQL policy, statistics and foreign-object grammar plan
2+
3+
> **For agentic workers:** Use superpowers:subagent-driven-development for sequential grammar implementation and independent review; root owns integration and publication.
4+
5+
**Goal:** Continue the approved native PostgreSQL grammar expansion with policies, extended statistics and foreign objects.
6+
**Architecture:** Extend validated PgDdlParser productions, reusing structural clause/list/name/type/expression nodes and existing execution guards. No opaque SQL tails or PostgreSQL runtime fallback.
7+
**Tech stack:** C++17, GoogleTest, pinned PostgreSQL 18.4 source grammar and development oracle.
8+
**Spec:** Continuation of the user's approved native grammar design and explicit request to continue filling remaining gaps.
9+
10+
## Global constraints
11+
12+
- Use existing branch feat/postgresql-coverage-and-ast-apis and PR #67; detailed commits, no benchmark files or benchmark-only README/.gitignore edits.
13+
- Preserve MySQL behavior, existing enum values and the 48-byte AST layout.
14+
- Production parsing stays native; PostgreSQL/libpg_query is only a development oracle.
15+
- Baseline 398450a: 48,313 / 51,415 deeply supported; inspect every lost case.
16+
- Keep names, options, expressions and literals traversable; allocation failure cannot silently omit operands.
17+
- Root owns Makefile, statement-type mapping, documentation, corpus refresh and commits. Implementers do not commit or spawn subagents.
18+
19+
## Review focus
20+
21+
- Keyword categories and quoted identifiers follow PostgreSQL grammar.
22+
- Parenthesized statistics expressions preserve raw-AST meaning through emission.
23+
- Foreign OPTIONS distinguish CREATE string pairs from ALTER ADD/SET/DROP actions.
24+
- Table constraints, partition forms and column options cannot absorb malformed input.
25+
- Successful constrained-arena parses retain all required AST children; unsupported engine/parameterization paths remain guarded.
26+
27+
### Task 1: Policies and extended statistics
28+
29+
**Files:** Modify include/sql_parser/pg_ddl_parser.h; create tests/test_pg_policy_statistics.cpp.
30+
**Interfaces:** Existing PgDdlParser CREATE/ALTER/DROP dispatch, clause/list nodes, expression callback, object-identity helpers. No new public enum/node types required.
31+
32+
- [x] Add failing tests for CREATE POLICY (AS, FOR, TO, USING, WITH CHECK), ALTER POLICY (roles/predicates/rename), DROP POLICY; CREATE STATISTICS (optional name, IF NOT EXISTS, kinds, columns/functions/parenthesized expressions, FROM relations), ALTER STATISTICS target/owner/schema/rename and DROP STATISTICS.
33+
- [x] Check exact productions in /tmp/parsersql-coverage/postgresql/postgresql-18.4/src/backend/parser/gram.y, not documentation simplifications. Implement scoped helpers with validated options and keyword categories.
34+
- [x] Positive and malformed fixtures include quoted names, clause order, missing operands, expressions/subqueries, target integer bounds, multiple relations, no-name statistics and semicolons.
35+
- [x] Verify traversal/editing/emission and existing execution/parameterization rejection; sweep constrained arenas and compare successful node counts.
36+
- [x] Build focused tests with a fresh parser object; validate relevant upstream cases and every positive/negative fixture using /tmp/parsersql-coverage/libpg_query/target/libpg_query.a. Strip only source-position fields when comparing raw AST JSON.
37+
- [x] Report test-first evidence, commands/results, scope and limitations. Root runs full suite after integration. No commits, Makefile edits, benchmark edits or subagents.
38+
39+
### Task 2: Foreign tables, wrappers, servers and mappings
40+
41+
**Files:** Modify include/sql_parser/pg_ddl_parser.h; create tests/test_pg_foreign_ddl.cpp.
42+
**Interfaces:** Builds on task 1 after review; existing CREATE/ALTER/DROP dispatch and structured table/column/constraint productions. Root handles IMPORT statement classification if introduced.
43+
44+
- [x] Add failing fixtures for CREATE/ALTER/DROP FOREIGN DATA WRAPPER, SERVER and USER MAPPING, CREATE/ALTER/DROP FOREIGN TABLE, and IMPORT FOREIGN SCHEMA (ALL, LIMIT TO, EXCEPT).
45+
- [x] Implement exact pinned PG18 grammar for generic option string pairs and ALTER ADD/SET/DROP options; preserve names, handler/validator, type/version, roles and option literals structurally.
46+
- [x] Reuse table/partition/constraint helpers for foreign tables where grammar permits, including column OPTIONS and INHERITS, partition bounds, server and generic options. Keep ordinary tables' acceptance boundaries intact. No blanket table-parser rewrite.
47+
- [x] Cover positive/negative keyword, quoting, option ordering, partition/column/table constraint and identity cases. Validate allocation failure, traversal/emission and unsupported execution.
48+
- [x] Build focused tests with a fresh parser object; compare relevant corpus and positive/negative fixtures with pinned raw parser. Document genuine remaining positive gaps rather than accepting arbitrary tails.
49+
- [x] Report test-first evidence and commands/results. No commits, Makefile edits, benchmark edits or subagents.
50+
51+
### Task 3: Integration and publication
52+
53+
**Files:** Makefile, tools/pg_compat/statement_type_map.cpp and tests/pg_compat/statement_type_cases.cpp if needed, docs/postgresql-analysis-features.md, correctness snapshot files.
54+
55+
- [ ] Register test files and add necessary accurate statement mappings. Review each task's diff independently and fix substantive findings.
56+
- [ ] Forced full build/test and corpus executable; ASan/UBSan for new suites; Python compatibility harness; full replay with zero unexplained regressions.
57+
- [ ] Verify raw-AST equivalence for every newly supported corpus statement; update native coverage docs and remaining examples.
58+
- [ ] Detailed implementation commit, refresh correctness snapshot, compare all refreshed results with reviewed replay, verify full corpus/CI cases, detailed snapshot commit.
59+
- [ ] Push existing branch and update PR #67. Preserve all benchmark-only local changes.
60+
61+
## Verification results
62+
63+
- Forced full build and corpus executable, then library rebuild and full suite after review fixes: 1,483 passed, 37 external-backend tests skipped.
64+
- New grammar suites under ASan/UBSan: 11/11 passed, including constrained arenas.
65+
- Compatibility harness: 87 tests passed.
66+
- Same PostgreSQL 18.4 source corpus: 49,120 / 51,415 deeply supported (95.5%), +807 with no previously supported cases lost.
67+
- Every newly supported statement reconstructs to the same PostgreSQL raw AST, excluding source-position fields only (807/807).
68+
- All 298 policy/statistics and 615 of 616 foreign-object original corpus statements roundtrip exactly; the remaining foreign case requires the shared ALTER CONSTRAINT production.
69+
- Independent review approved the five foreign-grammar fixes. Final full-corpus replay and all 807 new raw-AST comparisons pass; correctness snapshot publication follows.

‎include/sql_parser/common.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ enum class StmtType : uint8_t {
133133
UNLISTEN,
134134
DISCARD,
135135
CHECKPOINT,
136+
IMPORT_FOREIGN_SCHEMA,
136137
};
137138

138139
// -- AST node types --

0 commit comments

Comments
 (0)