Skip to content

Commit 58e69fc

Browse files
authored
Merge pull request #5 from oracle-devrel/article/02-converged-vs-multi-model
converged-database-lab: module 02 — Converged vs. Multi-Model (article 2 companion)
2 parents eb8003e + e50580b commit 58e69fc

7 files changed

Lines changed: 462 additions & 102 deletions

File tree

labs/converged-database-lab/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ All modules run against one deterministically seeded domain. Seeds use an LCG (s
9393

9494
| # | Slug | Status | Proofs | Assertions | Links |
9595
|---|------|--------|--------|------------|-------|
96-
| 01 | `what-is-a-converged-database` | Live | 4 | 14 | [README](modules/01-what-is-a-converged-database/README.md) · article link lands at publish |
97-
| 02 | `converged-vs-multi-model` | Arrives with its article | | | |
96+
| 01 | `what-is-a-converged-database` | Live | 5 | 20 | [README](modules/01-what-is-a-converged-database/README.md) · [article](https://blogs.oracle.com/developers/what-is-a-converged-database-definition-five-tests-and-ai-use-cases) |
97+
| 02 | `converged-vs-multi-model` | Live | 3 | 18 | [README](modules/02-converged-vs-multi-model/README.md) · article link lands at publish |
9898
| 03 | `vector-db-vs-converged` | Arrives with its article ||||
9999
| 04 | `ai-agents-enterprise-data` | Arrives with its article ||||
100100
| 05 | `json-graph-vector-relational-one-db` | Arrives with its article ||||

labs/converged-database-lab/docker/Dockerfile.oracle

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,6 @@ RUN printf '[mongodb-org-8.0]\nname=MongoDB Repository\nbaseurl=https://repo.mon
1313
&& microdnf install -y mongodb-mongosh \
1414
&& microdnf clean all
1515

16-
# Bake Oracle's prebuilt augmented all-MiniLM-L12-v2 ONNX model into the image so
17-
# every fresh build (and CI) loads identical in-DB embeddings deterministically —
18-
# no network dependency at init time. This is the official model published by
19-
# Oracle Machine Learning: the 26ai docs "ONNX Pipeline Models: Text Embedding"
20-
# page redirects (/pls/topic/lookup?...&id=oml_ai_models_object_storage) to the
21-
# OML-ai-models object-storage bucket whose index lists this exact URL. The zip
22-
# (~122.6 MB) unpacks to all_MiniLM_L12_v2.onnx (~133.3 MB, 384-dim output),
23-
# loaded by docker/init/08-vector-model.sql via DBMS_VECTOR.LOAD_ONNX_MODEL.
24-
# Placed AFTER the ORDS + mongosh layers so their (slow) cache layers are reused
25-
# when only the model layer changes. Fails the build loudly if the URL stops
26-
# resolving rather than baking a broken image.
27-
ARG MINILM_URL=https://adwc4pm.objectstorage.us-ashburn-1.oci.customer-oci.com/p/TtH6hL2y25EypZ0-rrczRZ1aXp7v1ONbRBfCiT-BDBN8WLKQ3lgyW6RxCfIFLdA6/n/adwc4pm/b/OML-ai-models/o/all_MiniLM_L12_v2_augmented.zip
28-
RUN microdnf install -y unzip \
29-
&& microdnf clean all \
30-
&& mkdir -p /opt/oracle/models \
31-
&& curl -fsSL -o /tmp/minilm.zip "$MINILM_URL" \
32-
&& unzip -o /tmp/minilm.zip -d /opt/oracle/models \
33-
&& test -s /opt/oracle/models/all_MiniLM_L12_v2.onnx \
34-
&& rm -f /tmp/minilm.zip \
35-
&& chown -R oracle:oinstall /opt/oracle/models
36-
3716
COPY init/ /container-entrypoint-initdb.d/
3817

3918
COPY scripts/entrypoint.sh /opt/oracle/scripts/entrypoint.sh

labs/converged-database-lab/docker/init/08-vector-model.sql

Lines changed: 0 additions & 79 deletions
This file was deleted.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Module 02 — Converged vs Multi-Model
2+
3+
Three runnable proofs for leaf article 2's core claims ("multi-model is a
4+
storage claim; converged is a guarantees claim"). Every script executes
5+
against the live lab container and emits machine-checkable assertions
6+
(`ASSERT:<name>:PASS|FAIL`). No screenshots, no trust-me — run them yourself.
7+
8+
---
9+
10+
## Proof 1: `scripts/01-survey-challenge.sql`
11+
12+
**Article claim: the academic literature's canonical multi-model query runs as
13+
one standard SQL statement.** Lu & Holubová's ACM Computing Surveys survey of
14+
multi-model databases (52(3) Art. 55, 2019) opens with a running example
15+
(their Fig. 1): relational customers (Mary, credit 5000; John, 3000; William,
16+
2000), a "knows" social graph, and orders as JSON documents — challenge query:
17+
*"Return all product_no which are ordered by a friend of a customer whose
18+
credit_limit>3000"*, published result `['2724f','3424g']`. The survey solves
19+
it in ArangoDB AQL and OrientDB SQL, each a proprietary language on its own
20+
engine. This script recreates the dataset as module-local tables plus a SQL
21+
property graph, then answers the query in **one statement**: `GRAPH_TABLE`
22+
(SQL/PGQ, ISO/IEC 9075-16) walks the knows-graph, `JSON_TABLE` (SQL/JSON,
23+
SQL:2016) unnests the order lines, a relational predicate filters on
24+
`credit_limit` — and an assertion checks the result set equals the survey's
25+
published answer **exactly**. `EXPLAIN PLAN` then shows graph, document, and
26+
relational access costed as ordinary row sources in a single plan tree.
27+
28+
**Dataset note:** the survey publishes the customers, the query, and the
29+
result, but not the complete knows-edge topology or full order documents. The
30+
script constructs the minimal dataset consistent with the survey's published
31+
inputs and published result (Mary knows John and William; John's order
32+
contains product `2724f`, William's contains `3424g`); `Order_no`,
33+
`Product_Name`, and `Price` values are constructed placeholders in the
34+
survey's document shape.
35+
36+
**DDL exception:** this script intentionally performs DDL, and DDL
37+
autocommits — the harness rollback cannot undo it. Cleanup is therefore
38+
explicit and asserted: every module-local object (`smm_` prefix) is dropped
39+
before the script ends, an idempotence guard at the top clears leftovers from
40+
interrupted runs, and the transactional `EXPLAIN PLAN` rows are deleted before
41+
the autocommitting drops so `plan_table` is left unchanged too.
42+
43+
Expected assertions:
44+
45+
```
46+
ASSERT:survey-result-exact:PASS
47+
ASSERT:plan-captured:PASS
48+
ASSERT:plan-spans-graph:PASS
49+
ASSERT:plan-spans-relational:PASS
50+
ASSERT:plan-spans-document:PASS
51+
ASSERT:plan-evaluates-json:PASS
52+
ASSERT:one-plan-tree:PASS
53+
ASSERT:smm-tables-dropped:PASS
54+
ASSERT:smm-graph-dropped:PASS
55+
ASSERT:plan-table-clean:PASS
56+
```
57+
58+
## Proof 2: `scripts/02-one-enforcement-domain.js`
59+
60+
**Article claim: one enforcement domain — the same constraint guards every
61+
API.** The shared domain declares `CHECK (qty > 0)` on `order_items`. The
62+
script pushes `qty: -1` through the MongoDB document API (an `updateOne` on
63+
the `order_dv` duality view) and gets a `MongoServerError` carrying
64+
`ORA-02290` (check-constraint violated); it then submits the same violation as
65+
a SQL `UPDATE` through the `$sql` aggregation stage on the same connection and
66+
gets the same `ORA-02290`. Document and rows verified unchanged after both
67+
attempts. The constraint lives in the engine, beneath every surface — there is
68+
no per-API validation layer to drift.
69+
70+
**Error-text note:** the exact `MongoServerError` message format (ORA-42692
71+
wrapping ORA-02290 on the document path; bare ORA-02290 via `$sql`) is
72+
observed behavior on Oracle AI Database 26ai Free as of June 2026, not a
73+
documented contract. Assertions match only the documented element — the
74+
ORA-02290 code.
75+
76+
Expected assertions:
77+
78+
```
79+
ASSERT:doc-read:PASS
80+
ASSERT:mongo-api-rejected:PASS
81+
ASSERT:doc-unchanged:PASS
82+
ASSERT:sql-update-rejected:PASS
83+
ASSERT:final-state-unchanged:PASS
84+
```
85+
86+
## Proof 3: `scripts/03-read-after-write-search.sql`
87+
88+
**Article claim: transactional read-after-write text search.** The script
89+
inserts a support ticket containing a unique marker token, COMMITs, and
90+
immediately finds it with `CONTAINS` — then deletes it, COMMITs, and
91+
immediately does not. Search visibility arrives with the commit, in the same
92+
engine, with no separate search process, change stream, or refresh interval.
93+
The lab's `ticket_text_idx` is created with `PARAMETERS ('SYNC (ON COMMIT)')`
94+
(`docker/init/05-text-vector.sql`), so the text index syncs inside the
95+
committing transaction.
96+
97+
**Commit exception:** this script intentionally COMMITs (read-after-write can
98+
only be shown across a real commit boundary), so the harness rollback does not
99+
apply; explicit, asserted cleanup restores the domain. It is reseed-safe —
100+
`ticket_id` is identity-generated and the probe row is addressed only by its
101+
unique subject/marker, never a fixed id.
102+
103+
Expected assertions:
104+
105+
```
106+
ASSERT:contains-finds-committed-write:PASS
107+
ASSERT:contains-after-cleanup:PASS
108+
ASSERT:probe-rows-gone:PASS
109+
```
110+
111+
## Cross-reference: the one-optimizer proof lives in module 01
112+
113+
The companion article also leans on **one cost-based plan spanning graph,
114+
document, vector, and relational** access. That evidence is module 01's
115+
[`05-one-plan.sql`](../01-what-is-a-converged-database/scripts/05-one-plan.sql)
116+
(`EXPLAIN PLAN` over the shared domain: `GRAPH_TABLE` + JSON predicate +
117+
`VECTOR_DISTANCE` + relational joins in one plan tree). Leaf article 2 quotes
118+
that proof; this module deliberately does not duplicate it — proof 1's plan
119+
assertions here cover the survey statement specifically.
120+
121+
---
122+
123+
## Run It Yourself
124+
125+
```bash
126+
docker compose up -d --build oracle
127+
pip install -r validator/requirements.txt
128+
python validator/run.py
129+
```
130+
131+
The validator runs every script (modules 01 and 02) and exits 0 only if all
132+
assertions pass.
133+
134+
**These proofs leave the seeded domain unchanged.** Two scripts in this module
135+
are documented exceptions to the rollback contract — proof 1 performs DDL
136+
(autocommits) and proof 3 COMMITs — so both clean up explicitly and assert the
137+
cleanup, which keeps the validator repeatable: run it any number of times with
138+
identical results.

0 commit comments

Comments
 (0)