| Capability | Detail |
| Compile SPL to C UDRs that register under the same name | No application changes, no callsite changes. The install SQL DROP PROCEDURE IF EXISTS <name> then CREATE PROCEDURE <name>(...) EXTERNAL NAME 'sqlmorph.so(<name>)' LANGUAGE C NOT VARIANT; existing EXECUTE FUNCTION and EXECUTE PROCEDURE calls continue to work transparently. |
| Translate FOREACH cursors to mi_prepare + ONI_EXEC_PREP + mi_get_result loops | Over a cached MI_CONNECTION. The connection is opened once via mi_open(NULL, NULL, NULL) and stashed in mi_fp_funcstate so subsequent calls on the same fparam reuse it; cursor SQL is normalised via oni_clean_sql() before mi_prepare so stray whitespace from SPL source doesn't trip the parser. |
| Iterator UDRs (WITH RESUME) compile to reentrant SET_INIT / SET_RETONE / SET_END scaffolds | With PER_COMMAND state. A per-procedure iter_state_t struct carries the phase counter, cached connection, every persisted DEFINE local, and one MI_STATEMENT *_curN_st per FOREACH cursor; multi-column iterators add an MI_ROW_DESC + MI_DATUM[] row buffer assembled per yield via mi_row_create. |
| One canonical Makefile builds every UDR in a directory into one sqlmorph.so | make compiles every *.c; make IFXDB=mydb install registers each procedure via dbaccess; make deploy copies the .so into $INFORMIXDIR/extend/sqlmorph/. Override the library name with LIBNAME=mycustom if you need something different. |