Three findings, each caught by a different debugging technique,
documented in DECISION_LOG.md:
1. CURNAME+NFETCH PDU: trailing reserved field is SHORT not INT.
Caught by byte-diffing our 44-byte PDU against JDBC's 42-byte
reference under socat. The server tolerated the longer version
for INT-only SELECTs (silently consuming extra zeros) but
rejected it for VARCHAR queries. Lesson: server tolerance varies
by query type — always match JDBC byte-for-byte.
2. SQ_TUPLE payload pads to even byte alignment. An 11-byte
"syscolumns" VARCHAR payload had a trailing 0x00 between it and
the next SQ_TUPLE tag. JDBC's IfxRowColumn.readTuple consumes
this pad silently; we weren't, so any odd-length variable-width
row desynced the parser.
3. VARCHAR/NCHAR/NVCHAR in tuple data use a SINGLE-byte length
prefix (max 255 chars — IDS VARCHAR's hard limit). NOT a 2-byte
short as I'd initially assumed. CHAR is fixed-width per
encoded_length. LVARCHAR uses a 4-byte int prefix for >255 byte
values.
Module changes:
src/informix_db/_resultset.py — _LENGTH_PREFIXED_SHORT_TYPES set,
branched VARCHAR/NCHAR/NVCHAR (1-byte prefix) vs CHAR (fixed)
vs LVARCHAR (4-byte prefix); even-byte alignment pad consumed
after each SQ_TUPLE payload.
src/informix_db/cursors.py — CURNAME+NFETCH and standalone NFETCH
PDUs now write_short(0) for the reserved trailing field.
Tests: 40 unit + 18 integration (3 new VARCHAR tests) = 58 total,
all green, ruff clean. New tests cover:
- VARCHAR single-column SELECT
- Odd-length VARCHAR row (regression for the pad-byte bug)
- Mixed INT + VARCHAR + FLOAT three-column SELECT
Sample output:
SELECT FIRST 5 tabname FROM systables → ('systables',),
('syscolumns',), ('sysindices',), ('systabauth',), ('syscolauth',)
SELECT FIRST 3 tabname, tabid, nrows → ('systables', 1, 276.0), ...
VARCHAR was the last known gap from the Phase 2 commit. Phase 2
now reads INT, BIGINT, REAL, FLOAT, CHAR, VARCHAR end-to-end. Phase
6+ types (DATETIME, INTERVAL, DECIMAL, BLOBs) remain.
37 lines
4.5 KiB
Plaintext
37 lines
4.5 KiB
Plaintext
2026/05/04 07:40:07 socat[340723] N listening on AF=2 0.0.0.0:9090
|
|
2026/05/04 07:40:07 socat[340723] N accepting connection from AF=2 127.0.0.1:46824 on AF=2 127.0.0.1:9090
|
|
2026/05/04 07:40:07 socat[340723] N opening connection to 127.0.0.1:9088
|
|
2026/05/04 07:40:07 socat[340723] N opening connection to AF=2 127.0.0.1:9088
|
|
2026/05/04 07:40:07 socat[340723] N successfully connected from local address AF=2 127.0.0.1:49596
|
|
2026/05/04 07:40:07 socat[340723] N successfully connected to 127.0.0.1:9088
|
|
2026/05/04 07:40:07 socat[340723] N starting data transfer loop with FDs [6,6] and [5,5]
|
|
> 2026/05/04 07:40:07.516183 length=384 from=0 to=383
|
|
01 80 01 3c 00 00 00 64 00 65 00 00 00 3d 00 06 49 45 45 45 4d 00 00 6c 73 71 6c 65 78 65 63 00 00 00 00 00 00 06 39 2e 32 38 30 00 00 0c 52 44 53 23 52 30 30 30 30 30 30 00 00 05 73 71 6c 69 00 00 00 01 3c 00 00 00 00 00 00 00 00 00 01 00 09 69 6e 66 6f 72 6d 69 78 00 00 07 69 6e 34 6d 69 78 00 6f 6c 00 00 00 00 00 00 00 00 00 3d 74 6c 69 74 63 70 00 00 00 00 00 01 00 68 00 0b 00 00 00 03 00 09 69 6e 66 6f 72 6d 69 78 00 00 00 00 00 00 00 00 00 00 00 00 6a 00 06 00 07 44 42 50 41 54 48 00 00 02 2e 00 00 0e 43 4c 49 45 4e 54 5f 4c 4f 43 41 4c 45 00 00 0d 65 6e 5f 55 53 2e 38 38 35 39 2d 31 00 00 11 43 4c 4e 54 5f 50 41 4d 5f 43 41 50 41 42 4c 45 00 00 02 31 00 00 07 44 42 44 41 54 45 00 00 06 59 34 4d 44 2d 00 00 0c 49 46 58 5f 55 50 44 44 45 53 43 00 00 02 31 00 00 09 4e 4f 44 45 46 44 41 43 00 00 03 6e 6f 00 00 6b 00 00 00 00 00 05 33 01 00 00 00 00 00 0b 72 70 6d 2d 62 75 6c 6c 65 74 00 00 00 00 29 2f 68 6f 6d 65 2f 72 70 6d 2f 63 6c 61 75 64 65 2f 69 6e 66 6f 72 6d 69 78 2f 70 79 74 68 6f 6e 2d 6c 69 62 72 61 72 79 00 00 74 00 20 00 00 00 00 00 00 00 00 00 16 69 6e 66 6f 72 6d 69 78 2d 64 62 40 70 69 64 33 34 30 37 33 37 00 00 7f
|
|
< 2026/05/04 07:40:07.528122 length=276 from=0 to=275
|
|
01 14 02 3c 10 00 00 64 00 65 00 00 00 3d 00 06 49 45 45 45 49 00 00 6c 73 72 76 69 6e 66 78 00 00 00 00 00 00 2f 49 42 4d 20 49 6e 66 6f 72 6d 69 78 20 44 79 6e 61 6d 69 63 20 53 65 72 76 65 72 20 56 65 72 73 69 6f 6e 20 31 35 2e 30 2e 31 2e 30 2e 33 00 00 07 73 65 72 69 61 6c 00 00 09 69 6e 66 6f 72 6d 69 78 00 00 00 01 3c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6f 6e 00 00 00 00 00 00 00 00 00 3d 73 6f 63 74 63 70 00 00 00 00 00 00 00 66 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 6b 00 00 00 00 00 00 03 1a 00 00 00 00 00 0d 32 33 32 37 63 34 33 35 34 65 61 38 00 00 00 00 0f 2f 68 6f 6d 65 2f 69 6e 66 6f 72 6d 69 78 00 00 6e 00 04 00 00 00 00 00 74 00 33 00 00 00 c8 00 00 00 c8 00 29 2f 6f 70 74 2f 69 62 6d 2f 69 6e 66 6f 72 6d 69 78 2f 76 31 35 2e 30 2e 31 2e 30 2e 33 2f 62 69 6e 2f 6f 6e 69 6e 69 74 00 00 7f
|
|
> 2026/05/04 07:40:07.528386 length=14 from=384 to=397
|
|
00 7e 00 08 ff fc 7f fc 3c 8c aa 97 00 0c
|
|
< 2026/05/04 07:40:07.528522 length=16 from=276 to=291
|
|
00 7e 00 09 bd be 9f fe 7f b7 ff ef ff 00 00 0c
|
|
> 2026/05/04 07:40:07.528584 length=48 from=398 to=445
|
|
00 51 00 06 00 26 00 0c 00 04 00 06 44 42 54 45 4d 50 00 04 2f 74 6d 70 00 0b 53 55 42 51 43 41 43 48 45 53 5a 00 00 02 31 30 00 00 00 00 00 0c
|
|
< 2026/05/04 07:40:07.528662 length=2 from=292 to=293
|
|
00 0c
|
|
> 2026/05/04 07:40:07.528681 length=18 from=446 to=463
|
|
00 24 00 09 73 79 73 6d 61 73 74 65 72 00 00 00 00 0c
|
|
< 2026/05/04 07:40:07.528847 length=28 from=294 to=321
|
|
00 0f 00 15 00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00 00 01 00 00 00 01 00 0c
|
|
> 2026/05/04 07:40:07.528893 length=66 from=464 to=529
|
|
00 02 00 00 00 00 00 34 53 45 4c 45 43 54 20 46 49 52 53 54 20 32 20 74 61 62 6e 61 6d 65 20 46 52 4f 4d 20 73 79 73 74 61 62 6c 65 73 20 4f 52 44 45 52 20 42 59 20 74 61 62 69 64 00 16 00 31 00 0c
|
|
< 2026/05/04 07:40:07.529094 length=84 from=322 to=405
|
|
00 08 00 02 00 00 00 00 00 00 00 81 00 01 00 00 00 08 00 00 00 00 00 00 00 00 00 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 74 61 62 6e 61 6d 65 00 00 0f 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00 01 14 00 00 00 25 00 0c
|
|
> 2026/05/04 07:40:07.529204 length=44 from=530 to=573
|
|
00 04 00 00 00 03 00 12 5f 69 66 78 63 30 30 30 30 30 30 30 30 30 30 30 30 31 00 06 00 04 00 00 00 09 00 00 10 00 00 00 00 00 00 0c
|
|
< 2026/05/04 07:40:07.529311 length=66 from=406 to=471
|
|
00 0e 00 00 00 00 00 0a 09 73 79 73 74 61 62 6c 65 73 00 0e 00 00 00 00 00 0b 0a 73 79 73 63 6f 6c 75 6d 6e 73 00 00 0f 00 10 00 00 00 02 00 00 03 02 00 00 00 00 00 37 00 00 01 14 00 00 00 25 00 0c
|
|
> 2026/05/04 07:40:07.529416 length=2 from=574 to=575
|
|
00 38
|
|
2026/05/04 07:40:07 socat[340723] N socket 1 (fd 6) is at EOF
|
|
2026/05/04 07:40:07 socat[340723] N socket 2 (fd 5) is at EOF
|
|
2026/05/04 07:40:07 socat[340723] N exiting with status 0
|