---
phase: 59-architectural-unification
plan: 01
type: retroactive-reconstruction
wave: 1
depends_on: [58-transactional-ddl]
autonomous: false
requirements: [UNIFY-01, UNIFY-02]
source_commits:
  - 1e7e92b  # refactor(v0.8.1): full architectural unification — parser_override is the sole DDL entry point
files_modified:
  - build.rs
  - cpp/include/parser_extension_compat.hpp
  - cpp/src/shim.cpp
  - src/catalog.rs
  - src/ddl/alter.rs    # deleted
  - src/ddl/define.rs
  - src/ddl/drop.rs     # deleted
  - src/ddl/mod.rs
  - src/ddl/persist.rs  # deleted
  - src/lib.rs
  - src/parse.rs
---

# Phase 59: Architectural Unification

> Reconstructed retroactively on 2026-05-05. Single source commit: `1e7e92b` (2026-05-02). No RESEARCH.md / DISCUSS.md.

## Goal

`parser_override` becomes the **sole** DDL entry point. The legacy `parse_function` / `sv_ddl_internal` table-function fallback is retired. One execution path → uniform transactional semantics, uniform error reporting, uniform PEG/Bison compatibility.

## Approach

Phase 58 introduced `parser_override` for the four `CREATE` forms plus `DROP` / `ALTER`. The rest of the DDL surface (`DESCRIBE`, `SHOW SEMANTIC *`, `GET_DDL`, `READ_YAML_FROM_SEMANTIC_VIEW`) still went through the older `parse_function` extension hook, which rewrote into table-function calls executed on a separate connection. That dual entry meant:

- two parsing paths to keep in sync,
- the `parse_function` path could not participate in transactions,
- PEG-vs-Bison divergence had to be patched in two places (the `peg_compat.test` carve-out for `DESCRIBE`),
- `DESCRIBE` / `SHOW` ran on `catalog_conn`, not the caller's connection — read-after-write visibility was murky.

This phase rewrites every recognised form through a single Rust dispatch (`validate_and_rewrite` → `rewrite_*`) and re-parses each rewritten statement on the caller's connection. Net diff: **+513 / −1614 lines** (~1500 LOC removed).

Files deleted (functionality folded into the unified rewrite path):

- `src/ddl/alter.rs` — ALTER table-function logic.
- `src/ddl/drop.rs` — DROP table-function logic.
- `src/ddl/persist.rs` — separate persistence helpers (now inlined into the rewrite layer).

Files significantly reshaped:

- `cpp/src/shim.cpp` (−491 / +0 net to the file's share of the diff) — the `parse_function` registration block is removed; only `parser_override` remains.
- `src/parse.rs` — central dispatch grows to handle all forms; `DdlKind` simplified.
- `src/lib.rs` — table-function VTab registration calls deleted along with their backing modules.
- `src/ddl/define.rs` — heavily slimmed.

## Known regression introduced (intentional, fixed in Phase 62)

DuckDB silently drops `DISPLAY_EXTENSION_ERROR` from `parser_override` under `allow_parser_override_extension='FALLBACK'` (verified against `.amalgamation/v1.5.2/duckdb.cpp` `ParseInternal`). With the `parse_function` fallback retired, validation errors that used to render with `LINE 1: … ^` caret positions now disappear — the user instead sees the default parser's generic `Parser Error: syntax error at or near "SEMANTIC"`. Phase 60 ships a workaround (synthesised `SELECT error('<msg>')`); Phase 62 will restore caret rendering structurally by re-introducing `parse_function` purely as the error-reporting layer. Tracked as TECH-DEBT item 22.

## Tests

- `test/sql/peg_compat.test` updated: every DDL form (including `DESCRIBE` and `SHOW`) now works under PEG because `parser_override` fires before whichever parser is active. The Bison-only carve-out for `DESCRIBE` is removed.
- Existing test suite (~820 tests) continues to pass — the rewrite is behaviour-preserving except for the documented error-rendering regression.
