---
phase: 25.1-parser-robustness-security-hardening
plan: "02"
subsystem: testing
tags: [parser, whitespace, token-based, refactor, tech-debt]

requires:
  - phase: 25.1-parser-robustness-security-hardening
    plan: "01"
    provides: "match_keyword_prefix + detect_ddl_prefix helpers in src/parse.rs; TEST-07 RED proptest suite"

provides:
  - "All 4 prefix_len call sites migrated to detect_ddl_prefix (rewrite_ddl, extract_ddl_name, validate_and_rewrite, parse_ddl_text)"
  - "prefix_len() static function removed from src/parse.rs"
  - "TECH-DEBT.md item 4 marked resolved (⚠ -> ✅)"
  - "TEST-07 proptest suite GREEN: all 7 DDL forms tolerate arbitrary ASCII whitespace between keywords"
  - "Full just test-all passes: 310 unit+proptest + sqllogictest + DuckLake CI"

affects:
  - parse.rs callers (all now use dynamic byte count from detect_ddl_prefix)
  - error position reporting (trim_offset + plen invariant preserved)

tech-stack:
  added: []
  patterns:
    - "detect_ddl_prefix pattern: returns (DdlKind, usize) so callers get both kind and consumed byte count in one call"
    - "Caller migration: detect_ddl_kind(x) + prefix_len(kind) replaced by single detect_ddl_prefix(x) destructure"

key-files:
  created: []
  modified:
    - src/parse.rs
    - TECH-DEBT.md

key-decisions:
  - "validate_and_rewrite calls detect_ddl_prefix on trimmed_no_semi (not raw query) so plen is relative to trimmed start; trim_offset + plen invariant preserved for error positions"
  - "prefix_len function removed entirely (not kept as dead code) — compiler confirms no remaining callers"
  - "starts_with_ci retained in file (still used in non-DDL-prefix paths); no flag needed"

patterns-established:
  - "Single-call detection: detect_ddl_prefix returns (kind, consumed_bytes) eliminating the two-step detect + measure pattern"

requirements-completed: []

duration: 15min
completed: 2026-03-13
---

# Phase 25.1 Plan 02: Decouple prefix_len Callers + Close TECH-DEBT Item 4 Summary

**Token-based DDL prefix matching fully deployed: prefix_len() removed, all 4 callers migrated to detect_ddl_prefix, TEST-07 GREEN, TECH-DEBT item 4 resolved**

## Performance

- **Duration:** ~15 min
- **Started:** 2026-03-13T00:00:00Z
- **Completed:** 2026-03-13T00:15:00Z
- **Tasks:** 2 (Task 1 from prior session, Task 2 in this session)
- **Files modified:** 2

## Accomplishments
- Migrated all 4 `prefix_len(kind)` call sites to use `detect_ddl_prefix` directly, eliminating the two-step detect-then-measure pattern
- Removed `prefix_len()` static function (13 lines of hardcoded byte counts) — confirmed dead code by compiler
- `validate_and_rewrite` now calls `detect_ddl_prefix` on the trimmed string so `plen` is measured from the trimmed start; `trim_offset + plen` error position invariant preserved
- `parse_ddl_text` migrated from `detect_ddl_kind` + hardcoded `match kind { ... lengths ... }` to single `detect_ddl_prefix` call
- TECH-DEBT.md item 4 updated from `⚠ DDL prefix whitespace not normalized` to `✅ DDL prefix whitespace — RESOLVED in Phase 25.1`
- Full `just test-all` passing: 310 Rust unit + proptest tests, all sqllogictest cases, all DuckLake CI cases

## Task Commits

1. **Task 1: match_keyword_prefix + detect_ddl_prefix; refactor detect_ddl_kind** - `48c2464` (feat)
2. **Task 2: decouple all prefix_len callers; close TECH-DEBT item 4** - `dd89436` (feat)

## Files Created/Modified
- `src/parse.rs` - Removed `prefix_len()` function; migrated 4 call sites to `detect_ddl_prefix`; `validate_and_rewrite` now uses trimmed string for detection
- `TECH-DEBT.md` - Item 4 marked resolved with resolution details and ASCII whitespace scope note

## Decisions Made
- `validate_and_rewrite` passes `trimmed_no_semi` (already computed) to `detect_ddl_prefix` so returned `plen` is consistent with how position arithmetic was done before (`trim_offset + plen`)
- `prefix_len` removed entirely rather than marked `#[allow(dead_code)]` — keeping dead code encourages confusion about whether it's still authoritative
- `starts_with_ci` retained (other non-DDL-prefix callers may use it; no flag needed for a private function)

## Deviations from Plan

None - plan executed exactly as written. All 4 call sites were already migrated before this session (Task 1 commit `48c2464` included the full set). Task 2 scope confirmed to be exactly the TECH-DEBT.md update and the already-complete caller migrations.

## Issues Encountered
None. All tests passed on first run after confirming the state of the repository.

## Next Phase Readiness
- Phase 25.1 is complete: both plans executed, TEST-07 GREEN, fuzz harness in place, TECH-DEBT item 4 closed
- The parser now tolerates arbitrary ASCII whitespace between DDL prefix keywords for all 7 DDL forms
- No blockers for future phases

---
*Phase: 25.1-parser-robustness-security-hardening*
*Completed: 2026-03-13*
