Skip to content

Oracle 23ai database backend#1307

Merged
nicoloboschi merged 5 commits intomainfrom
feature/database-abstraction-clean
Apr 29, 2026
Merged

Oracle 23ai database backend#1307
nicoloboschi merged 5 commits intomainfrom
feature/database-abstraction-clean

Conversation

@DK09876
Copy link
Copy Markdown
Contributor

@DK09876 DK09876 commented Apr 28, 2026

Summary

  • Adds Oracle 23ai as a fully supported database backend alongside PostgreSQL
  • Implements a 3-tier abstraction layer: DatabaseBackendDataAccessOpsSQLDialect
  • Transparent PG→Oracle query rewriting via _rewrite_pg_to_oracle() (17+ regex patterns)
  • All 25 DataAccessOps abstract methods implemented for both backends
  • Oracle-specific: VECTOR_DISTANCE(), CONTAINS()/SCORE() (Oracle Text), UTL_MATCH.JARO_WINKLER_SIMILARITY(), LIST partition pruning, JSON_TABLE

Production hardening (final commit)

  • Fixed DPY-4008 bind placeholder error in Oracle Text BM25 fallback
  • Added Oracle ORA-00060 deadlock detection to retry logic
  • Fixed obs_sources_table derivation using fq_table() instead of fragile string replacement
  • Fixed ResultRow.__bool__ to delegate to underlying data
  • Improved entity resolver fallback logging
  • Fixed prepare_bm25_text empty token edge case

Test plan

  • Oracle integration tests: 82/82 passed (-n0)
  • PG tests: 746 passed, 7 pre-existing failures on origin/main (verified)
  • E2E smoke test: migrations → create bank → retain 3 docs → recall (9 results) → mental model CRUD �� cleanup — all passed
  • Lint (ruff check) + type check (ty check) pass
  • Pre-commit hooks pass
  • Coverage: blocked by pytest-cov/NumPy incompatibility (not a code issue)

🤖 Generated with Claude Code

DK09876 and others added 3 commits April 28, 2026 09:42
…layer

Add Oracle 23ai as a first-class database backend alongside PostgreSQL via
a clean DatabaseBackend / DataAccessOps / SQLDialect abstraction layer.

Key changes:
- DatabaseBackend ABC with PostgreSQL and Oracle implementations
- DataAccessOps for backend-specific multi-statement operations
- SQLDialect for stateless SQL fragment generation
- Oracle SQL rewriter: translates PG syntax at runtime ($N params, ::casts,
  ON CONFLICT, LIMIT/OFFSET, JSON operators, date_trunc, intervals, etc.)
- Multi-tenant schema isolation via ALTER SESSION SET CURRENT_SCHEMA
- Oracle Text CONTAINS with graceful BM25 fallback
- FOR UPDATE SKIP LOCKED task claiming (Oracle-native)
- CLOB/JSON handling with automatic LOB-to-string conversion
- Comprehensive Oracle integration + HTTP E2E test suites (60 tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…acle retry handling

Remove stale causal_weight_threshold parameter from expand_observations
across all backends and link_expansion_retrieval. Add Oracle exception
handling (InterfaceError, OperationalError, IntegrityError) to retry
logic in memory_engine so Oracle connection/integrity errors trigger
proper retry/skip behavior. Strengthen Oracle integration test assertions
to verify non-empty results and handle known ORA-00060 deadlocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix DPY-4008 bind placeholder error in Oracle Text BM25 fallback by
  rebuilding semantic-only query with correct param indices when CONTAINS
  fails (DRG-10599)
- Add Oracle ORA-00060 deadlock detection to retry_with_backoff so Oracle
  deadlocks get the same exponential backoff as PG DeadlockDetectedError
- Use fq_table() for obs_sources_table in both Oracle and PG ops instead
  of fragile string replacement on mu_table
- Fix ResultRow.__bool__ to delegate to underlying data instead of always
  returning True
- Improve Oracle fuzzy entity resolution fallback logging to include the
  actual error message
- Fix OracleDialect.prepare_bm25_text to handle empty token list edge case
  with proper fallback to escaped query text
- Add E2E smoke test script for Oracle pipeline validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DK09876 and others added 2 commits April 28, 2026 21:34
The test_bool_always_true test expected ResultRow({}) to be truthy,
but we changed __bool__ to delegate to the underlying data. Update
the test to verify both truthy (non-empty) and falsy (empty) cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nicoloboschi nicoloboschi merged commit 50f559c into main Apr 29, 2026
57 of 59 checks passed
nicoloboschi added a commit that referenced this pull request Apr 29, 2026
…1312)

The Oracle PR (#1307) introduced subtle behavioral changes to two PG
query patterns during the abstraction refactor:

1. semantic_expanded CTE: the DISTINCT ON rewrite lost the global
   ORDER BY score DESC before LIMIT. When results exceeded the budget,
   the LIMIT applied in mu.id order instead of keeping the highest-
   scored rows. Fix: wrap DISTINCT ON in a subquery that re-sorts by
   score before applying LIMIT.

2. temporal neighbors: the ROW_NUMBER() OVER (PARTITION BY ... ORDER BY
   time_diff_hours) filter was dropped, doubling the returned rows per
   probe (K per direction × 2 instead of K closest overall). Fix:
   restore the ROW_NUMBER filter around the UNION ALL of both scan
   directions, for both PG and Oracle backends.

3. Migration chain: remove two empty merge migrations that were
   artifacts of the Oracle branch being developed in parallel
   (e6f7g8h9i0j1, j5k6l7m8n9o0) and linearize the chain:
   8c6fa6f7230b → d5y6z7a8b9c0 → i4j5k6l7m8n9 → k6l7m8n9o0p1
nicoloboschi added a commit that referenced this pull request Apr 29, 2026
Revert the two PG query changes introduced by the Oracle abstraction
PR (#1307) back to the exact v0.5.6 SQL:

1. Semantic dedup: restore GROUP BY + MAX(weight) + ORDER BY score DESC
   instead of DISTINCT ON. The Oracle PR rewrote this for portability,
   but the PG ops layer should emit the identical query shape.

2. Temporal neighbors: restore exact v0.5.6 query shape with
   src.unit_id::text AS from_id, ABS(EXTRACT(...)), combined.*,
   ROW_NUMBER PARTITION BY src.unit_id.

The only accepted query difference vs 0.5.6 is the observation_sources
junction table reads (new table for Oracle portability).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants