SlimeInformix — prove the “hidden dialect” of an Informix migration on real iron
When you migrate Informix (I4GL / ESQL/C / ESQL/COBOL) to PostgreSQL / Java, the scariest failure mode is “it looks like it works, but the answers quietly change.” We make a live Informix server the oracle, diff before vs after byte-for-byte, and machine-prove that behaviour did not change.
sql_pre / sql_emit) is in development.
What we can prove today is a catalogue of “hidden dialect traps” pinned on real Informix 15.0.1 Developer Edition, plus a
real-iron oracle kit (the Informix counterpart of how ocesql verifies DB2-style EXEC SQL). We do not write “Informix supported.”
When migrating an old Informix system to PostgreSQL/Java, the scariest thing is "it runs, but the answers quietly change" — dialect differences. With a live Informix as the "reference," we machine-verify that the answers stay the same before vs after (converter in development).
Informix and PostgreSQL quietly differ on integer division (is 100/8 12.5 or 12?) and decimal→int rounding. We pinned 51 probes on real Informix 15.0.1 ↔ real PostgreSQL 16 and confirmed 12 hidden dialect traps, catching what "95% automation" misses — measured.
Informix's int/int=float, CAST=truncate, NULL position in ORDER BY, silent over-length truncation etc. are N/N diffed against a live oracle to evidence the faithful conversion matches. Our initial "empty string = NULL" assumption was retracted after real iron refuted it (measured, not documented). Converter in development.
With real-iron (a live Informix Developer Edition) as the independent oracle, we keep only the SQL whose value/order diverges from PostgreSQL. Each trap has a bit-exact mapping (a/b→a::numeric/b, CAST→trunc()::int, ORDER BY→NULLS FIRST). Same shape as mirroring integer wrapping into Rust wrapping.
📋 "Ask your AI at this level" copies this page's explanation with an instruction matched to the level you picked. Paste it into your own AI (Claude · GPT · Gemini · Grok) to dig deeper at that resolution.
What we can prove today (honestly)
- Hidden dialect, pinnedWe ran 51 probes of the same SQL on real Informix 15.0.1 Developer Edition ⇄ real PostgreSQL 16, and kept only the 12 cases where the value/order actually diverged. Measured, not from the docs.
- Real-iron oracleA running Informix server is the independent reference; the migrated output is diffed N/N by byte/result. It starts with one Docker command and a third party can reproduce it locally.
- 4 unconditional silent trapsThe ★★★ rows below change the answer silently and unconditionally — exactly what “95% automation” misses most.
Why “95% automation” is dangerous — dialect traps confirmed on real iron
Places where the same SQL gives a different answer on Informix vs PostgreSQL. A naive “pass-through” conversion breaks here without raising any error. This is the SQL-layer counterpart of SlimeJava's integer-trap table (where naively copying Java wrapping breaks).
| Sev. | Dialect trap | Informix | PostgreSQL | Consequence |
|---|---|---|---|---|
| ★★★ | Integer division total/cnt (100/8) | 12.5 (float) | 12 (truncated) | averages / pro-rata / commissions silently truncated (money lost) |
| ★★★ | Decimal→int CAST(2.7 AS INT) | 2 (truncate) | 3 (round) | assignment into integer fields silently differs |
| ★★★ | NULL sort order ORDER BY x | NULLs first | NULLs last | top-N / pagination / “first row” changes |
| ★★★ | Over-length INSERT char(5)←8 chars | silently 'ABCDE' | ERROR | silent data loss / app stops after migration |
| ★★ | MOD(10.5,3) / SUBSTR negative / SMALLINT overflow / date format / trailing blanks | all confirmed divergent on real iron (6 more; conditions/type-dependence noted honestly) | ||
'' stays an empty string (not NULL), so we retracted it — that is what “measured, not documented” means.How we do it — proving “behaviour unchanged” with a real-iron oracle
Each trap is a place where the converter must mirror Informix's semantics. The faithful conversion matches live Informix, and emits the evidence:
| Trap | Form the converter must mirror (example) |
|---|---|
| integer division | a/b → a::numeric/b (promote to float) |
| decimal→int | CAST(x AS INT) → trunc(x)::int (truncate, not round) |
| NULL order | ORDER BY x → ORDER BY x NULLS FIRST |
| over-length | substr(v,1,n) to make Informix's silent truncation visible (data loss put on the record) |
This is the same idea as mirroring integer wrapping into Rust wrapping. The deliverable is a “certificate of behavioural invariance” — every trap diffed N/N against the live oracle, reproducible by a third party.
What we have NOT confirmed yet (no overstating)
- The converterThe Informix-dialect
sql_pre/sql_emit(auto-mirroring A/D/E/I) is in development. So we do not say “Informix conversion supported.” - Full ESQL oracleRunning the original ESQL through Informix's ESQL/C and ESQL/COBOL precompilers to capture host variables + indicators on real iron is the next step. Today we pin it at the SQL/storage layer.
- Large corpusWhole-of-corpus equivalence on public Informix code is not done. Today is trap confirmation + PoC scale.
Where it sits in the SlimeNENC family
SlimeInformix is the Informix track of SlimeCOBOL-ESQL, the embedded-SQL capability of SlimeCOBOL. The legacy side is COBOL / JCL / RPG; the DB side adds Informix (pinned by a live oracle) to DB2 (verified by the independent ocesql). Informix is not a z/OS mainframe but Unix mid-range enterprise legacy — an honest sibling track to the mainframe track, not part of it.
Contact us / discuss a PoC SlimeCOBOL-ESQL resource SlimeNENC family Other products
All figures are live values from real Informix 15.0.1 Developer Edition and real PostgreSQL 16 (2026-06). No claim is built from documentation.
