Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d14b0a8
feature: forward BLOB methods through RpcDriver
aesslinger Jul 29, 2026
ab14827
feature: forward materialized view methods through RpcDriver
aesslinger Jul 29, 2026
e9e4df7
feature: resolve map_inferred_type from plugin manifest type_mappings
aesslinger Jul 30, 2026
7d3cb91
Merge branch 'plugins/forward-blob-methods' into phase-0-baseline-tests
aesslinger Jul 30, 2026
fb3ac5a
Merge branch 'plugins/forward-materialized-views' into phase-0-baseli…
aesslinger Jul 30, 2026
499daa8
Merge branch 'plugins/manifest-type-mappings' into phase-0-baseline-t…
aesslinger Jul 30, 2026
b7142e7
test: add Phase 0 PostgreSQL integration test infrastructure
aesslinger Jul 30, 2026
81650aa
test: add views, materialized views, routines, triggers, crud, multi-…
aesslinger Jul 30, 2026
67ba130
fix: correct API signatures in integration tests
aesslinger Jul 30, 2026
d35e4e1
test: complete Phase 0 integration test suite (72 tests)
aesslinger Jul 30, 2026
33eca80
fix: resolve all 72 integration test failures
aesslinger Jul 30, 2026
42e1c54
fix: tighten test assertions to strict TDD (no lenient passing)
aesslinger Jul 30, 2026
826653c
test: add golden file capture and 17 golden snapshot tests
aesslinger Jul 30, 2026
9ecd64a
test: un-ignore existing PostgreSQL integration tests
aesslinger Jul 30, 2026
05387d6
docs: add planning docs for postgres plugin migration
aesslinger Jul 30, 2026
ce2d25f
fix: address code review findings for CI reliability
aesslinger Jul 30, 2026
1c241b1
feature: forward BLOB methods through RpcDriver
aesslinger Jul 29, 2026
47be550
feature: forward materialized view methods through RpcDriver
aesslinger Jul 29, 2026
a95a781
feature: resolve map_inferred_type from plugin manifest type_mappings
aesslinger Jul 30, 2026
e619750
Merge branch 'plugins/rpc-extensions' into postgres-plugin-migration
aesslinger Jul 30, 2026
1e600bd
Merge remote-tracking branch 'upstream/main' into postgres-plugin-mig…
aesslinger Aug 4, 2026
bbd6cda
fix: retry transient pool errors in flaky integration tests
aesslinger Aug 4, 2026
09b3b1c
test: add parity test harness for dual-driver comparison
aesslinger Aug 4, 2026
bc91e50
fix: limit CI test parallelism to prevent pool exhaustion
aesslinger Aug 4, 2026
702936a
fix: run integration tests sequentially to eliminate pool flakiness
aesslinger Aug 4, 2026
9b0143a
fix: correct field name in parity_get_foreign_keys test
aesslinger Aug 4, 2026
1bc984f
test: add missing golden capture tests and CI artifact upload
aesslinger Aug 4, 2026
9c60f72
fix: handle known MV definition error in golden capture test
aesslinger Aug 4, 2026
3b3434b
test: commit generated golden files from CI
aesslinger Aug 4, 2026
c59b2a4
docs: mark Phase 0 complete, document golden file scope decisions
aesslinger Aug 4, 2026
1f52847
feature: scaffold postgres-plugin crate (Phase 1 Sprint 1)
aesslinger Aug 4, 2026
1561446
feature: implement client.rs with deadpool-postgres + TLS
aesslinger Aug 4, 2026
bad4393
feature: wire parity harness to spawn plugin driver
aesslinger Aug 4, 2026
e0de9c4
ci: build postgres-plugin and enable dual-driver parity testing
aesslinger Aug 4, 2026
655e090
fix: resolve compilation issues from Sprint 1 review
aesslinger Aug 4, 2026
432ee02
ci: separate parity tests from baseline (continue-on-error)
aesslinger Aug 4, 2026
4fd75f9
feature: implement get_databases, get_schemas, get_tables (Sprint 2)
aesslinger Aug 4, 2026
f4622c1
feature: implement get_columns, get_indexes, get_foreign_keys (Sprint 3)
aesslinger Aug 4, 2026
226cf2d
fix: match builtin driver's character_maximum_length extraction
aesslinger Aug 4, 2026
c399c84
feature: implement views, materialized views, routines, triggers (Spr…
aesslinger Aug 4, 2026
992d3c0
feature: implement execute_query, execute_query_batch, explain_query …
aesslinger Aug 4, 2026
604e448
fix: resolve compilation errors in Sprint 5
aesslinger Aug 4, 2026
b367d62
test: add 26 RED parity tests for full TDD coverage (Sprint 5)
aesslinger Aug 4, 2026
c4dc8dd
test: complete 80-test parity suite — full CP-4 TDD specification
aesslinger Aug 4, 2026
6961822
docs: update planning docs to reflect 80-test parity architecture
aesslinger Aug 4, 2026
9d44672
docs: note repo-extraction timing decision and open question
aesslinger Aug 5, 2026
d717639
feature: implement insert_record, update_record, delete_record (Sprin…
aesslinger Aug 5, 2026
40b5603
fix: correct 7 test-authoring bugs in the 80-test parity suite
aesslinger Aug 5, 2026
47bd5b2
fix: add missing BLOB wire-format decoding to binding cascade (regres…
aesslinger Aug 5, 2026
9e87cf7
fix: strip user LIMIT/OFFSET before appending pagination clause
aesslinger Aug 5, 2026
8dcaae9
fix: implement missing type extractors and truncated field (regression)
aesslinger Aug 5, 2026
74a0232
ci: run plugin unit tests (binding_tests, pagination_tests)
aesslinger Aug 5, 2026
3cfe752
fix: implement Debug for BoundValue so unit tests compile
aesslinger Aug 5, 2026
7b277c9
fix: cache connection pools by identity instead of rebuilding per call
aesslinger Aug 5, 2026
3be48ee
fix: exclude execution_time_ms from execute_batch parity comparison
aesslinger Aug 5, 2026
1f5bb58
fix: rewrite destructive-mutation parity tests to run per-target
aesslinger Aug 5, 2026
efaaaec
fix: add missing enum-CAST binding to CRUD (regression)
aesslinger Aug 5, 2026
b0eb4fe
feature: implement DDL generation methods (Sprint 7)
aesslinger Aug 5, 2026
23a5c95
feature: implement view and materialized view lifecycle (Sprint 8, ch…
aesslinger Aug 5, 2026
d95e007
feature: implement routine and trigger metadata/mutation (Sprint 8, c…
aesslinger Aug 5, 2026
ad765f3
feature: implement BLOB save/fetch (Sprint 8, chunk 3/3) — 82/82 parity
aesslinger Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/planning/.markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"MD013": false,
"MD024": { "siblings_only": true },
"MD060": false
}
1,238 changes: 1,238 additions & 0 deletions .github/planning/postgres-improvements.md

Large diffs are not rendered by default.

925 changes: 925 additions & 0 deletions .github/planning/postgres-plugin-migration-original.md

Large diffs are not rendered by default.

533 changes: 533 additions & 0 deletions .github/planning/postgres-plugin-migration.md

Large diffs are not rendered by default.

201 changes: 201 additions & 0 deletions .github/planning/postgres-plugin/00-prerequisites.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Prerequisites — Tabularis Core PRs

**Must be merged before Phase 0 testing or Phase 1 building can begin.**

## Overview

Three changes to the Tabularis host's `RpcDriver` adapter are required to enable
full feature parity for any PostgreSQL plugin. Without these, certain tests in
Phase 0 will always fail when pointed at a plugin driver, making parity
verification impossible.

These are small, non-breaking additions to existing code. They follow the same
patterns already used for other forwarded methods (triggers, views, etc.).

---

## PR 1: Forward BLOB Methods

### What

Extend `RpcDriver` in `src-tauri/src/plugins/driver.rs` to forward:

- `save_blob_to_file(params, table, column, pk_column, pk_value, file_path, schema)`
- `fetch_blob_as_data_url(params, table, column, pk_column, pk_value, schema)`

### Current Behavior

These methods inherit the trait default which returns:

```rust
Err("BLOB file export not supported by this driver".into())
```

### Proposed Implementation

```rust
async fn save_blob_to_file(&self, params: &ConnectionParams, table: &str,
column: &str, pk_column: &str, pk_value: &str,
file_path: &str, schema: Option<&str>) -> Result<(), String>
{
// Plugin returns base64-encoded blob data
let res = self.process.call("save_blob_to_file", json!({
"params": params, "table": table, "column": column,
"pk_column": pk_column, "pk_value": pk_value,
"file_path": file_path, "schema": schema
})).await?;
Ok(()) // Plugin writes to file_path directly (local process)
}

async fn fetch_blob_as_data_url(&self, params: &ConnectionParams, table: &str,
column: &str, pk_column: &str, pk_value: &str,
schema: Option<&str>) -> Result<String, String>
{
let res = self.process.call("fetch_blob_as_data_url", json!({
"params": params, "table": table, "column": column,
"pk_column": pk_column, "pk_value": pk_value, "schema": schema
})).await?;
serde_json::from_value(res).map_err(|e| e.to_string())
}
```

### Testing

- Verify existing BLOB tests pass with built-in driver (unchanged behavior)
- Verify a plugin returning base64 data works end-to-end

### Risk

None — purely additive. Existing plugins that don't implement these methods
will return `-32601` and the host falls back to the existing "not supported" error.

---

## PR 2: Forward Materialized View Methods

### What

Extend `RpcDriver` to forward:

- `get_materialized_views(params, schema)`
- `get_materialized_view_columns(params, view_name, schema)`
- `get_materialized_view_definition(params, view_name, schema)`
- `refresh_materialized_view(params, view_name, schema)`

### Current Behavior

These inherit defaults returning `Ok(vec![])` or
`Err("Materialized views are not supported...")`.

### Proposed Implementation

Same pattern as `get_views`, `get_triggers`, etc. — straightforward JSON-RPC
forwarding with `serde_json::from_value` deserialization.

### Risk

None — same pattern as existing forwarded methods.

---

## PR 3: Resolve `map_inferred_type` from Plugin Manifest

### What

The `map_inferred_type` method is **synchronous** (`fn`, not `async fn`) so it
cannot issue an RPC call. Currently returns the input unchanged for plugin drivers.

The built-in PG driver maps: `DATETIME` → `TIMESTAMP`, `JSON` → `JSONB`.

### Proposed Solution

Add an optional `type_mappings` field to `PluginManifest`:

```rust
// In driver_trait.rs, add to PluginManifest:
pub type_mappings: Option<HashMap<String, String>>,
```

The `RpcDriver` stores these at construction time and applies them in
`map_inferred_type`:

```rust
fn map_inferred_type(&self, kind: &str) -> String {
if let Some(mappings) = &self.manifest.type_mappings {
if let Some(mapped) = mappings.get(&kind.to_uppercase()) {
return mapped.clone();
}
}
kind.to_string()
}
```

Plugin manifest declares:

```json
{
"type_mappings": {
"DATETIME": "TIMESTAMP",
"JSON": "JSONB"
}
}
```

### Risk

Low — new optional field. Existing plugins without it behave unchanged.

---

## Approach

### Option A: One Combined PR

Submit all three changes in a single PR titled:
"feat(plugins): extend RpcDriver for BLOB, materialized views, and type mappings"

**Pros:** One review cycle, atomic merge, single CI run.
**Cons:** Larger diff, harder to review.

### Option B: Three Separate PRs

Submit sequentially, each small and focused.

**Pros:** Easy to review, bisectable, can merge independently.
**Cons:** Three review cycles.

### Recommendation

**Option A** — These are all small, non-breaking additions with zero risk of
conflict. A single PR with clear commit separation (one commit per feature)
gives the reviewer full context of why these are needed (PostgreSQL plugin
migration) without the overhead of three separate review cycles.

---

## Checkpoint: CP-1

**When:** After the prerequisites PR is merged into `main`.

**Verify:**

- [ ] `cargo test` passes (no regressions in existing drivers)
- [ ] Existing plugin drivers (DuckDB, D1) still work (methods return -32601 gracefully)
- [ ] No changes to MySQL or SQLite drivers
- [ ] New trait fields are `Option` / backward-compatible

**Communicate to team:**

- Prerequisites are in place
- Phase 0 can begin (test suite development)
- No user-facing changes yet

---

## Definition of Done

- [ ] PR merged to `main`
- [ ] CI green
- [ ] No existing test regressions
- [ ] CHANGELOG entry added (under "Plugin System" section)
- [ ] Core team acknowledged at CP-1
Loading
Loading