Skip to content

Oracle 9i (fv2): describe desyncs on NOT-NULL columns (null_ok byte misread as ub4 name-length) #217

Description

@lemenkov

Summary

decode_fv2_describe (the 9i field-version-2 describe-in-RPA path, PROTOCOL.md §19.1) misparses the per-column metadata for any NOT NULL column, garbling the column name and desyncing the stream.

Root cause

The per-column tail after the OAC is:

<OAC-fv2> null_ok(1B) namelen_bytes(1B) ub4(namelen_chars) DALC(name) 00 00

The decoder read the first two bytes as a ub4 name-length. The leading byte is actually null_ok (0x00 = NOT NULL, 0x01 = nullable):

  • A nullable column sends 0x01, which decode_ub4 reads as a width-1 integer whose value coincidentally equals the name length — so it looked correct.
  • A NOT NULL column sends 0x00, read as width-0/value-0 (consuming one byte). The stream slips: the name garbles (USERNAMEb'\x08USERNAM'), and a multi-column NOT-NULL fetch fails with ORA-03115 (garbled describe → bad define block).

Why it was missed

Every offline fixture (and the original RE captures) was SELECT <literal> AS name FROM dual. A literal/expression is always nullable, so null_ok was always 0x01 and the slip never triggered. Real dictionary/table columns (all_users.username, all_tables.table_name) are NOT NULL and reproduce it immediately.

Reproduction (live 9.2.0.4)

SELECT username FROM all_users        -- name decodes to '\x08USERNAM'
SELECT table_name, x FROM all_tables  -- ORA-03115 on fetch

Fix

Read null_ok + the 1-byte byte-length explicitly, then the genuine ub4 char-length. Also feeds null_ok into Cursor.description[6] — 9i column nullability was previously hardcoded to nullable.

Confirmed via a controlled experiment (two identical-length names differing only in NOT NULL vs nullable) and collaboration/cross-check with an independent 9i client implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions