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.
Reading a BLOB
Section titled “Reading a BLOB”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.
Writing a BLOB
Section titled “Writing a BLOB”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=.
Reading a CLOB
Section titled “Reading a CLOB”text: str = cur.read_clob_column( "SELECT body FROM articles WHERE id = ?", (42,),)Returns a decoded str using the connection’s client_locale.
Writing a CLOB
Section titled “Writing a CLOB”cur.write_clob_column( "INSERT INTO articles VALUES (?, CLOB_PLACEHOLDER)", clob_data="long article text...", params=(42,),)Server-side prerequisites
Section titled “Server-side prerequisites”How it works (briefly)
Section titled “How it works (briefly)”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.