---
phase: 34-duckdb-1-5-upgrade-lts-branch
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - .duckdb-version
  - Cargo.toml
  - Cargo.lock
  - build.rs
  - cpp/src/shim.cpp
  - examples/basic_ddl_and_query.py
  - examples/advanced_features.py
  - test/integration/test_caret_position.py
  - test/integration/test_ducklake_ci.py
  - test/integration/test_vtab_crash.py
  - test/integration/test_ducklake.py
  - configure/setup_ducklake.py
  - test/sql/peg_compat.test
  - test/sql/TEST_LIST
autonomous: true
requirements:
  - DKDB-01
  - DKDB-05
must_haves:
  truths:
    - "Extension compiles against DuckDB 1.5.0 amalgamation (just build succeeds)"
    - "All Rust unit tests pass with duckdb-rs 1.10500.0 (cargo test succeeds)"
    - "All SQL logic tests pass against DuckDB 1.5.0 (just test-sql succeeds)"
    - "All integration tests pass with Python duckdb 1.5.0 (just test-all succeeds)"
    - ".duckdb-version reads v1.5.0"
    - "PEG parser compatibility is documented via a test file"
  artifacts:
    - path: ".duckdb-version"
      provides: "DuckDB version pin"
      contains: "v1.5.0"
    - path: "Cargo.toml"
      provides: "Rust dependency pins"
      contains: "=1.10500.0"
    - path: "test/sql/peg_compat.test"
      provides: "PEG parser compatibility smoke test"
      min_lines: 10
  key_links:
    - from: "Cargo.toml"
      to: "duckdb-rs crate"
      via: "version = \"=1.10500.0\""
      pattern: "duckdb.*=1\\.10500\\.0"
    - from: ".duckdb-version"
      to: "justfile update-headers"
      via: "cat .duckdb-version"
      pattern: "v1\\.5\\.0"
---

<objective>
Upgrade the extension from DuckDB 1.4.4 to DuckDB 1.5.0 on the current branch. Update all version pins (Cargo.toml, .duckdb-version, Python PEP 723 headers), download the new amalgamation, fix any C++ compilation or Rust API breaks, verify the full test suite passes, and add a PEG parser compatibility smoke test.

Purpose: DKDB-01 requires the extension to build and pass all tests against DuckDB 1.5.x. DKDB-05 requires .duckdb-version on main to track latest.
Output: Extension fully functional on DuckDB 1.5.0, all tests green, PEG compat documented.
</objective>

<execution_context>
@/Users/paul/.claude/get-shit-done/workflows/execute-plan.md
@/Users/paul/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-CONTEXT.md
@.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-RESEARCH.md

<interfaces>
<!-- Key files and patterns the executor needs -->

From Cargo.toml (lines 32-33, current state):
```toml
duckdb = { version = "=1.4.4", default-features = false }
libduckdb-sys = "=1.4.4"
```

From .duckdb-version (current):
```
v1.4.4
```

From build.rs (lines 198-227, Windows patch markers):
```rust
let patch1_before = "#endif // defined(_WIN32)\n\n// Platform-specific helpers";
let patch2_before = "#undef CreateDirectory\n#undef MoveFile\n#undef RemoveDirectory\n\n#endif\n\n#else\n#include <sys/mman.h>";
```

From cpp/src/shim.cpp (lines 265-290, parser hook registration):
```cpp
extern "C" {
    bool sv_register_parser_hooks(duckdb_database db_handle, duckdb_connection ddl_conn) {
        // ...
        auto *wrapper = reinterpret_cast<duckdb::DatabaseWrapper *>(
            db_handle->internal_ptr);
        auto &db = *wrapper->database->instance;
        // ...
        ParserExtension ext;
        ext.parse_function = sv_parse_stub;
        ext.plan_function = sv_plan_function;
        auto &config = DBConfig::GetConfig(db);
        config.parser_extensions.push_back(ext);
    }
}
```

From Python PEP 723 headers (all .py files):
```python
# /// script
# dependencies = ["duckdb==1.4.4"]
# requires-python = ">=3.9"
# ///
```

From test/sql/TEST_LIST (current):
```
test/sql/phase4_query.test
test/sql/phase20_extended_ddl.test
... (13 test files)
test/sql/phase33_cardinality_inference.test
```
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Update version pins and download DuckDB 1.5.0 amalgamation</name>
  <files>
    .duckdb-version
    Cargo.toml
    examples/basic_ddl_and_query.py
    examples/advanced_features.py
    test/integration/test_caret_position.py
    test/integration/test_ducklake_ci.py
    test/integration/test_vtab_crash.py
    test/integration/test_ducklake.py
    configure/setup_ducklake.py
  </files>
  <read_first>
    .duckdb-version
    Cargo.toml
    examples/basic_ddl_and_query.py
    examples/advanced_features.py
    test/integration/test_caret_position.py
    test/integration/test_ducklake_ci.py
    test/integration/test_vtab_crash.py
    test/integration/test_ducklake.py
    configure/setup_ducklake.py
    .planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-RESEARCH.md
  </read_first>
  <action>
    Update all version pins from DuckDB 1.4.4 to DuckDB 1.5.0:

    1. `.duckdb-version`: Change content from `v1.4.4` to `v1.5.0`

    2. `Cargo.toml` lines 32-33: Change version pins to use the new duckdb-rs versioning scheme:
       - `duckdb = { version = "=1.10500.0", default-features = false }` (was `"=1.4.4"`)
       - `libduckdb-sys = "=1.10500.0"` (was `"=1.4.4"`)
       NOTE: duckdb-rs v1.10500.0 encodes DuckDB 1.5.0 as `1.MAJOR_MINOR_PATCH.x`

    3. ALL Python files with PEP 723 headers: Update the dependency pin AND the Python version requirement.
       For each of these 7 files, change:
       - `# dependencies = ["duckdb==1.4.4"]` to `# dependencies = ["duckdb==1.5.0"]`
       - `# requires-python = ">=3.9"` to `# requires-python = ">=3.10"` (DuckDB 1.5.0 dropped Python 3.9)
       Files to update:
       - `examples/basic_ddl_and_query.py`
       - `examples/advanced_features.py`
       - `test/integration/test_caret_position.py`
       - `test/integration/test_ducklake_ci.py`
       - `test/integration/test_vtab_crash.py`
       - `test/integration/test_ducklake.py`
       - `configure/setup_ducklake.py`

    4. Download the new amalgamation: run `just update-headers` which reads `.duckdb-version` and downloads the matching DuckDB amalgamation (duckdb.hpp + duckdb.cpp) to `cpp/include/`.

    5. Run `cargo test` to verify Rust unit tests pass with duckdb-rs 1.10500.0. This uses the bundled feature (compiles DuckDB from source inside duckdb-rs), isolating Rust API compatibility from C++ amalgamation issues.

    If `cargo test` fails with compilation errors, investigate and fix:
    - Check if any duckdb-rs API signatures changed (e.g., Connection methods, VTab trait, VScalar trait)
    - Check for new/removed trait methods
    - Fix compile errors one at a time

    After `cargo test` passes, commit the version pin changes.
  </action>
  <verify>
    <automated>cd /Users/paul/Documents/Dev/Personal/duckdb-semantic-views && cat .duckdb-version && grep '=1.10500.0' Cargo.toml && grep 'duckdb==1.5.0' examples/basic_ddl_and_query.py && grep 'requires-python = ">=3.10"' examples/basic_ddl_and_query.py && cargo test 2>&1 | tail -5</automated>
  </verify>
  <acceptance_criteria>
    - `.duckdb-version` contains exactly `v1.5.0`
    - `Cargo.toml` contains `version = "=1.10500.0"` for duckdb dependency
    - `Cargo.toml` contains `libduckdb-sys = "=1.10500.0"`
    - All 7 Python files contain `duckdb==1.5.0` in their PEP 723 headers
    - All 7 Python files contain `requires-python = ">=3.10"` in their PEP 723 headers
    - `cargo test` exits 0 (all Rust unit tests pass)
    - `cpp/include/duckdb.hpp` and `cpp/include/duckdb.cpp` exist (amalgamation downloaded)
  </acceptance_criteria>
  <done>All version pins updated to DuckDB 1.5.0 / duckdb-rs 1.10500.0, amalgamation downloaded, cargo test passes</done>
</task>

<task type="auto">
  <name>Task 2: Fix C++ compilation, verify build.rs patches, run full test suite, add PEG test</name>
  <files>
    build.rs
    cpp/src/shim.cpp
    test/sql/peg_compat.test
    test/sql/TEST_LIST
  </files>
  <read_first>
    build.rs
    cpp/src/shim.cpp
    cpp/include/duckdb.hpp
    test/sql/TEST_LIST
    .planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-RESEARCH.md
  </read_first>
  <action>
    Build the extension against DuckDB 1.5.0 amalgamation and fix any issues:

    1. Run `just build` to compile the extension (triggers build.rs + cc crate compilation of duckdb.cpp + shim.cpp).

    2. If shim.cpp fails to compile, investigate and fix C++ API changes in DuckDB 1.5.0:
       - Check if `ParserExtension`, `ParserExtensionParseResult`, `ParserExtensionPlanResult`, `ParserExtensionParseData` types changed signatures
       - Check if `FunctionData`, `TableFunction`, `DataChunk`, `GlobalTableFunctionState` changed
       - Check if `DBConfig::GetConfig()` signature changed
       - Check if `DatabaseWrapper` internal layout changed (the `reinterpret_cast<duckdb::DatabaseWrapper *>(db_handle->internal_ptr)` in sv_register_parser_hooks)
       - Check if `make_uniq` was renamed or moved
       - Fix each compilation error by updating shim.cpp to match the new API
       - If `DatabaseWrapper` access pattern changed, search the new duckdb.hpp for the correct way to extract `DatabaseInstance&` from a C API handle

    3. Check build.rs Windows patch markers against new amalgamation:
       - Verify patch marker 1 still exists: grep for `#endif // defined(_WIN32)\n\n// Platform-specific helpers` in cpp/include/duckdb.cpp
       - Verify patch marker 2 still exists: grep for `#undef CreateDirectory\n#undef MoveFile\n#undef RemoveDirectory` in cpp/include/duckdb.cpp
       - If markers moved or changed, update the `patch1_before` and `patch2_before` strings in build.rs to match the new locations
       - If markers no longer exist (macros may have been fixed upstream in 1.5.0), consider whether the patches can be removed entirely

    4. Run `just test-sql` to verify SQL logic tests pass with the built extension.

    5. Run `just test-all` to verify the complete test suite (Rust + sqllogictest + DuckLake CI + vtab crash + caret position).

    6. Create PEG parser compatibility smoke test at `test/sql/peg_compat.test`:
       ```
       # name: test/sql/peg_compat.test
       # description: PEG parser compatibility smoke test
       # group: [semantic_views]

       require semantic_views

       # Create test data
       statement ok
       CREATE TABLE peg_test_data (id INTEGER, val DOUBLE);

       statement ok
       INSERT INTO peg_test_data VALUES (1, 10.0), (2, 20.0);

       # Verify extension works with default Bison parser
       statement ok
       CREATE SEMANTIC VIEW peg_bison_test (
           TABLES (
               t peg_test_data PRIMARY KEY (id)
           )
           DIMENSIONS (
               dim_id id
           )
           METRICS (
               total_val SUM(val)
           )
       );

       # Verify query works with Bison parser
       query IR
       SELECT * FROM semantic_view('peg_bison_test', dimensions := ['dim_id'], metrics := ['total_val']) ORDER BY dim_id;
       ----
       1	10.0
       2	20.0

       # Enable PEG parser and document behavior
       # PEG parser is opt-in in DuckDB 1.5.0. Parser extension hooks registered
       # via DBConfig::parser_extensions may not fire under PEG.
       # This test documents the actual behavior.
       statement ok
       CALL enable_peg_parser();

       # Attempt DDL with PEG active - expected to fail because PEG parser
       # does not consult Bison-era parser_extensions
       statement error
       CREATE SEMANTIC VIEW peg_demo_fail (
           TABLES (
               t2 peg_test_data PRIMARY KEY (id)
           )
           DIMENSIONS (
               dim_id2 id
           )
           METRICS (
               total_val2 SUM(val)
           )
       );
       ----
       Parser Error
       ```

       IMPORTANT: The exact error pattern for PEG may differ. After running `just test-sql`, if the PEG test fails because:
       - PEG actually DOES support parser extensions (unlikely but possible): change `statement error` to `statement ok` and add a query verification
       - PEG produces a different error message: update the `----` line to match the actual error prefix
       - `enable_peg_parser()` doesn't exist or is named differently: adjust the CALL statement

    7. Add the new test file to `test/sql/TEST_LIST`:
       Append `test/sql/peg_compat.test` as the last line.

    8. Run `just test-all` one final time to confirm everything passes including the PEG test.
  </action>
  <verify>
    <automated>cd /Users/paul/Documents/Dev/Personal/duckdb-semantic-views && just test-all 2>&1 | tail -20</automated>
  </verify>
  <acceptance_criteria>
    - `just build` exits 0 (extension compiles against DuckDB 1.5.0 amalgamation)
    - `just test-all` exits 0 (full quality gate passes)
    - `test/sql/peg_compat.test` exists with at least 15 lines
    - `test/sql/TEST_LIST` contains `test/sql/peg_compat.test`
    - If build.rs Windows patches needed updating: `build.rs` contains the new marker strings
    - If shim.cpp needed API fixes: `cpp/src/shim.cpp` compiles cleanly against DuckDB 1.5.0 amalgamation
    - No `cargo:warning=duckdb.cpp Win32 patch N skipped` warnings in build output (patches either match or are intentionally removed)
  </acceptance_criteria>
  <done>Extension builds, loads, and passes all tests against DuckDB 1.5.0. PEG compatibility is documented in test/sql/peg_compat.test. Full `just test-all` green.</done>
</task>

</tasks>

<verification>
Phase 34 Plan 01 is complete when:
1. `.duckdb-version` = `v1.5.0`
2. `Cargo.toml` pins duckdb and libduckdb-sys at `=1.10500.0`
3. All Python files pin `duckdb==1.5.0` and `requires-python = ">=3.10"`
4. `cargo test` passes (Rust unit tests against duckdb-rs 1.10500.0)
5. `just build` passes (C++ amalgamation compilation)
6. `just test-all` passes (full quality gate)
7. `test/sql/peg_compat.test` exists and documents PEG parser behavior
</verification>

<success_criteria>
- `just test-all` exits 0 on the current branch with DuckDB 1.5.0
- `.duckdb-version` contains `v1.5.0`
- `Cargo.toml` contains `=1.10500.0` for both duckdb and libduckdb-sys
- PEG compatibility test exists and runs as part of the test suite
</success_criteria>

<output>
After completion, create `.planning/phases/34-duckdb-1-5-upgrade-lts-branch/34-01-SUMMARY.md`
</output>
