Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 / DriverVersionStatusNotes
psqlany✅ Supportedbaseline
psycopg33.3.4✅ SupportedFixed 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 + psycopg35.x✅ SupportedBasic 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✅ SupportedFixed 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).
sqlx0.8.6✅ SupportedFixed in v0.6.5.3: ParameterDescription in Describe(S)
tokio-postgres (simple query)0.7.17✅ SupportedSimple query protocol
tokio-postgres (extended query)0.7.17✅ SupportedFixed 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.sh
  • tools/pg_catalog_trace/extract_angara_trace.py
  • tools/pg_catalog_trace/replay_angara_trace.sh
  • tools/compat_suite/run.sh --nightly --runs 3
  • tools/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.json
  • iter_<N>/summary.json
  • iter_<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, returns value. Allows Django to configure TimeZone and search_path without errors.
  • obj_description(oid, catalog): Stub, returns NULL. 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 the SET clause. 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; returns f (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_date is 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: date and timestamp types 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 ParameterDescription message (Parse phase) now returns real parameter type OIDs instead of zeros.

Fast Path:

  1. find the failing test in summary;
  2. open the corresponding log;
  3. reproduce locally with the exact cargo test or suite-runner command.