Ryan Malloy 9048335462 Phase 12: ROW / COLLECTION type recognition
Composite UDTs (ROW=22, COLLECTION=23, SET=19, MULTISET=20, LIST=21)
now decode into typed wrapper objects (informix_db.RowValue,
informix_db.CollectionValue) that expose schema + raw payload bytes.

The wire format is the now-familiar [byte ind][int length][bytes]
pattern (same as UDTVAR(lvarchar) from Phase 10). The bytes are a
TEXTUAL representation of the value when selected without the
extended-binary opt-in JDBC uses:
  ROW value:  b"ROW('Alice',30         )"
  SET value:  b"SET{'red','green','blue'}"
  LIST value: b"LIST{10         ,20         ,30         }"

JDBC's binary-with-schema format runs ~30x larger (1420 bytes for a
2-field ROW vs. our 24). We don't request it — the textual form is
what the server returns by default and is sufficient for type
recognition.

Phase 12 ships type recognition only. Full recursive parsing into
Python tuples/lists/sets is deferred to Phase 13 (would require a
SQL-literal lexer + recursive type-driven decoding). Production
workloads that need typed field access today can project via SQL:

  cur.execute("SELECT id, r.name, r.age FROM tbl")

Tests: 8 integration tests in test_composite_types.py covering ROW
recognition, NULL, sub-field projection workaround, long values
(>255 bytes — verifies 4-byte length prefix), SET/MULTISET/LIST
recognition, and null collections.

Total: 64 unit + 134 integration = 198 tests.

Lesson reinforced: once one UDT-shaped type is implemented (UDTVAR
in Phase 10, smart-LOB in Phase 9), every subsequent UDT-shaped type
is mostly a copy of the existing decoder branch. The hard part is
payload semantics, not framing.
2026-05-04 14:30:44 -06:00

informix-db

Pure-Python driver for IBM Informix IDS, speaking the SQLI wire protocol over raw sockets. No IBM Client SDK. No JVM. No native libraries.

Status

🟢 Phase 1 complete. connect() / close() work end-to-end against a real Informix server. Cursor / execute / fetch land in Phase 2.

To our knowledge this is the first pure-socket Informix driver in any language — every other Informix driver (IfxPy, the legacy informixdb, ODBC bridges, Perl DBD::Informix) wraps either IBM's CSDK or the JDBC JAR.

Quick start

import informix_db

with informix_db.connect(
    host="127.0.0.1", port=9088,
    user="informix", password="in4mix",
    database="sysmaster", server="informix",
) as conn:
    # cursor() / execute() / fetchone() arrive in Phase 2
    pass

Test against the official Informix dev container

docker compose -f tests/docker-compose.yml up -d   # IBM Developer Edition, pinned by digest
uv sync --extra dev
uv run pytest                  # 34 unit tests (no Docker needed)
uv run pytest -m integration   # 6 integration tests (needs the container)

Phase 0 artifacts (still useful — they ARE the public reference)

License

MIT.

Description
Pure-Python driver for IBM Informix IDS — speaks the SQLI wire protocol over a raw socket. No CSDK, no JVM, no native libraries.
https://informix-db.warehack.ing
Readme MIT 716 KiB
Languages
Python 85.6%
MDX 8.1%
CSS 2.1%
Java 1.7%
Astro 1%
Other 1.4%