Skip to content

BLOB / CLOB read & write

informix-driver reads and writes smart-LOB columns (BLOB and CLOB) end-to-end without any native machinery. The implementation uses Informix’s lotofile and filetoblob SQL functions, intercepted at the SQ_FILE (98) wire-protocol level.

data: bytes = cur.read_blob_column(
"SELECT data FROM photos WHERE id = ?",
(42,),
)

read_blob_column returns the raw bytes. For very large BLOBs (multi-GB), see the streaming variant below.

cur.write_blob_column(
"INSERT INTO photos VALUES (?, BLOB_PLACEHOLDER)",
blob_data=jpeg_bytes,
params=(42,),
)

The BLOB_PLACEHOLDER token in the SQL marks where the BLOB data goes. Other parameters are bound positionally to params=.

text: str = cur.read_clob_column(
"SELECT body FROM articles WHERE id = ?",
(42,),
)

Returns a decoded str using the connection’s client_locale.

cur.write_clob_column(
"INSERT INTO articles VALUES (?, CLOB_PLACEHOLDER)",
clob_data="long article text...",
params=(42,),
)

The lotofile server function returns a smart-LOB descriptor as a regular result column when called via SELECT. The driver intercepts the SQ_FILE (PDU 98) response that contains the LOB bytes and reassembles them client-side.

Writing reverses the flow: filetoblob is invoked via a placeholder pattern in the SQL, the driver sends the bytes via SQ_FILE PDUs, and the server stores them in the sbspace.

The architectural pivot from the heavier SQ_FPROUTINE + SQ_LODATA stack to this lighter SQ_FILE intercept is documented in Phase 10/11 of the decision log. The result is roughly 3× smaller than originally projected.