Client Compatibility Baseline
Operator baseline for client/ORM compatibility.
Canonical source: this runbook in angarabook/src/operations/.
Supported Framework Matrix (RM-0.6.5.7)
| Framework / Driver | Version | Status | Notes |
|---|---|---|---|
| psql | any | ✅ Supported | baseline |
| psycopg3 | 3.3.4 | ✅ Supported | Fixed in v0.6.5.3: EQP cast/arithmetic, date/timestamp encoding, IS NULL, = ANY(ARRAY). Fixed in v0.6.5.5: correct OID mapping and UTC serialization. Fixed in v0.6.5.7: DATE type (OID 1082, binary i32), bool comparison (1=2 → false), FK DDL accept (NOT ENFORCED), multi-col CREATE INDEX accept |
| Django ORM + psycopg3 | 5.x | ✅ Supported | Basic migrations PASS; EQP gaps fixed in v0.6.5.3. Fixed in v0.6.5.5: set_config/obj_description stubs unblock introspection. |
| Odoo 19 (community) | 19.x | ✅ Supported | Fixed in v0.6.5.3: IS NULL, = ANY(ARRAY), pg_class filter, pg_index, CREATE SEQUENCE. Fixed in v0.6.5.5: GAP-C2 (UPDATE SET func), GAP-C5 (date_trunc). |
| sqlx | 0.8.6 | ✅ Supported | Fixed in v0.6.5.3: ParameterDescription in Describe(S) |
| tokio-postgres (simple query) | 0.7.17 | ✅ Supported | Simple query protocol |
| tokio-postgres (extended query) | 0.7.17 | ✅ Supported | Fixed in v0.6.5.3: ParameterDescription in Describe(S). Fixed in v0.6.5.7: binary encode for DATE/TIMESTAMP, binary param decode OID 1114/1184, ParameterDescription returns real OIDs from Parse |
Goal
Maintain a repeatable compatibility baseline for:
psql- DBeaver
- Odoo-shaped probes
and track regressions through pinned reproducible checks.
Phase A focus (Odoo)
- Runtime smoke without critical SQL errors.
- Stable trace replay without shape/protocol regressions.
- Explicit boundary between acceptable shape stubs and unacceptable semantic-unsafe stubs.
Pinned tooling
tools/pg_catalog_trace/run_odoo_stages_angara.shtools/pg_catalog_trace/extract_angara_trace.pytools/pg_catalog_trace/replay_angara_trace.shtools/compat_suite/run.sh --nightly --runs 3tools/compat_suite/run.sh --odoo --runs 3
High-signal checks
- SQLSTATE mapping (
42601,0A000) is stable. - Catalog/info_schema response shapes are stable for the probe set.
- Odoo/DBeaver smoke path is not broken by changes in
pg_catalog.
Regression triage
Compat-suite artifacts:
summary.jsoniter_<N>/summary.jsoniter_<N>/test_<name>.log
Function Compatibility (RM-0.6.5.5)
The following functions were added to support ORM (Django, Odoo):
set_config(name, value, is_local): Stub, returnsvalue. Allows Django to configureTimeZoneandsearch_pathwithout errors.obj_description(oid, catalog): Stub, returnsNULL. Allows Django to perform database introspection.date_trunc(field, timestamp): Full implementation. Supports all standard fields (year,month,day,hour, etc.).NOW(),CURRENT_TIMESTAMP: Return the current time in UTC.
DML Compatibility (RM-0.6.5.5)
UPDATE SET col = func_call(): Functions (for example,write_date = NOW()) and explicit type casts (col = val::type) are now supported in theSETclause. This is critical for Odoo 19.
Query Execution & Bug Fixes (RM-0.6.5.7)
- Bool comparison: Comparing constants of different types now correctly coerces to boolean.
Example:
SELECT 1 = 2;returnsf(previously could cause a type error).
Supported Types (RM-0.6.5.7)
date: Native type. OID 1082. Binary mode: BE i32 (days since 2000-01-01). Text mode: ISO-8601 (YYYY-MM-DD).current_dateis supported. Example:SELECT '2026-05-08'::date;timestamp: Native type. OID 1114 (without time zone) / 1184 (with time zone). Binary mode: BE i64 (microseconds since 2000-01-01). Casting string literals in ISO-8601 format is supported. Example:SELECT '2026-05-08 12:00:00'::timestamp;
DDL Compatibility (RM-0.6.5.7)
Foreign Key Constraints
The REFERENCES and FOREIGN KEY ... REFERENCES syntax is accepted by the parser (v0.6.5.7+).
Constraints are not enforced (NOT ENFORCED). The server logs [FK constraint] ... accepted as NOT ENFORCED.
Example:
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT REFERENCES users(id) -- NOT ENFORCED
);
Multi-Column Indexes
CREATE INDEX ON t(a, b, c) is accepted (v0.6.5.7+). The index is built only on the first column.
Remaining columns are preserved in metadata. The server logs a warning.
Example:
CREATE INDEX idx_multi ON my_table (col1, col2, col3); -- Built only on col1
Known Limitations (RM-0.6.6.3)
SQL-level PREPARE / EXECUTE / DEALLOCATE
SQL syntax PREPARE stmt AS ... / EXECUTE stmt(...) / DEALLOCATE stmt
is not supported in AngaraBase v0.6. It returns feature_not_supported.
What to use instead: extended query protocol (Parse/Bind/Execute pgwire messages), which is used automatically by all supported drivers:
# psycopg3 — EQP automatically (prepare=True by default)
with conn.cursor() as cur:
cur.execute("SELECT $1::int", (42,)) # → PREPARE + BIND + EXECUTE under the hood
// JDBC
PreparedStatement ps = conn.prepareStatement("SELECT ?::int");
ps.setInt(1, 42);
# psql — uses simple query protocol; PREPARE as SQL does NOT work.
# For interactive testing, use \bind (psql 16+):
psql> SELECT $1::int \bind 42 \g
pg_sleep()
The pg_sleep(seconds) function is not implemented in v0.6.
To test timeouts, use a heavy query:
SET statement_timeout = 10; -- 10 ms
SELECT count(*) FROM large_table a CROSS JOIN large_table b; -- → ERROR 57014
Protocol Compatibility (RM-0.6.5.7)
- Binary encode DATE/TS:
dateandtimestamptypes are encoded in binary format as BE i32 and BE i64 respectively. - Binary param decode: Binary parameter decoding is supported for OID 1114 (
timestamp) and 1184 (timestamptz). - ParameterDescription OID: The
ParameterDescriptionmessage (Parse phase) now returns real parameter type OIDs instead of zeros.
Fast Path:
- find the failing test in summary;
- open the corresponding log;
- reproduce locally with the exact
cargo testor suite-runner command.