Skip to content
PYD ENTERPRISES

Migration guide

Informix 4GL to Java: extracting rules from INPUT blocks, forms and SQL

Informix 4GL applications put validation in AFTER FIELD blocks, constraints in form files and data rules in embedded SQL. This guide shows how to gather all three into a specification for a Java rebuild.

Informix 4GLJava
DIFFICULTY
High
OUTPUT
Rule / schema JSON
SYNTAX TRAPS
5 covered
WORKFLOW
6 steps

By Pranav Kulkarni, Head of Language Engineering · Updated 15 Oct 2026

Technical syntax challenges

Where Informix 4GL migrations go wrong.

01

Validation inside INPUT blocks

INPUT BY NAME ... AFTER FIELD cust_num ... NEXT FIELD cust_num validates one field at a time, often with a SELECT in the middle. Each AFTER FIELD block is a rule with a precondition (the cursor left the field), and the order of fields can matter when later checks use earlier values.

02

Form files carry constraints

The .per form's ATTRIBUTES section sets REQUIRED, NOENTRY, UPSHIFT, INCLUDE = (0.01 TO 99999.99), FORMAT and DEFAULT per field. These are input constraints the program never repeats, so extraction must read the form alongside the 4GL source.

03

NULL comparisons pass silently

In 4GL, as in SQL, a comparison with NULL is not true, so IF r_ord.ship_date < TODAY does not fire when the date is NULL. Unless the form field is REQUIRED, a blank date passes the check. The spec has to state this explicitly.

04

WHENEVER ERROR and status checks

WHENEVER ERROR CONTINUE turns SQL errors into a value in status or SQLCA.SQLCODE that the code may or may not test. NOTFOUND (100) is a business branch; other negative codes may be ignored entirely in that scope.

05

RECORD LIKE and CONSTRUCT

DEFINE r RECORD LIKE orders.* types variables from the database schema at compile time, so types live in the catalog. CONSTRUCT builds WHERE clauses from user query-by-example input, which becomes a search API with defined filter semantics.

Extraction workflow

6 steps from source to signed-off spec.

The sequence a PYD ENTERPRISES Discovery Scan runs for this stack. Every output links back to source file and line range.

  1. 1

    Collect 4GL modules, forms and schema

    Ingest .4gl modules, .per form specifications, GLOBALS files, the makefiles that link programs and the Informix schema for tables referenced with LIKE.

  2. 2

    Resolve LIKE declarations against the schema

    PYD ENTERPRISES types every RECORD LIKE and LIKE column variable from the schema, including DECIMAL(p,s), MONEY, DATE and DATETIME qualifiers.

  3. 3

    Bind forms to INPUT and DISPLAY statements

    Form field attributes are linked to the program variables bound in INPUT BY NAME, INPUT ARRAY and DISPLAY ARRAY, so each field has its full constraint set.

  4. 4

    Trace field-level control flow

    BEFORE FIELD, AFTER FIELD, ON KEY and NEXT FIELD jumps are modeled as a state machine per screen, with SQL calls and status checks along each path.

  5. 5

    Extract validations and decisions

    Each validation becomes a rule with its message text, and calculations become DMN tables, all linked to 4GL and form line numbers.

  6. 6

    Export contracts for the Java team

    Request schemas with merged constraints, OpenAPI 3.1 operations for each screen action and fixtures, including NULL and boundary cases, are exported.

Legacy in, specification out

The source, and what PYD ENTERPRISES extracts from it.

Left: the Informix 4GL construct as it sits in production. Right: the reviewed artifact your Java engineers build against. PYD ENTERPRISES produces the spec and the tests; your team writes the service.

LEGACY SOURCE

ordent.4glText
1# ordent.per: order_amt = orders.order_amt, REQUIRED,
2# INCLUDE = (0.01 TO 99999.99), FORMAT = "$$$,$$$.&&";
3DEFINE r_ord RECORD LIKE orders.*
4DEFINE l_hold CHAR(1)
5
6INPUT BY NAME r_ord.cust_num, r_ord.ship_date, r_ord.order_amt
7 AFTER FIELD cust_num
8 SELECT credit_hold INTO l_hold FROM customer
9 WHERE customer_num = r_ord.cust_num
10 IF status = NOTFOUND THEN
11 ERROR "Unknown customer"
12 NEXT FIELD cust_num
13 END IF
14 IF l_hold = "Y" THEN
15 ERROR "Customer on credit hold"
16 NEXT FIELD cust_num
17 END IF
18 AFTER FIELD ship_date
19 IF r_ord.ship_date < TODAY
20 OR r_ord.ship_date > TODAY + 90 THEN
21 ERROR "Ship date must be within 90 days"
22 NEXT FIELD ship_date
23 END IF
24END INPUT

EXTRACTED ARTIFACT

ORDENT.validation.jsonJSON
1{
2 "screen": "Order entry (ordent)",
3 "source": ["ordent.4gl:3-24", "ordent.per:18-19"],
4 "fields": {
5 "custNum": { "type": "integer", "required": false },
6 "shipDate": { "type": "string", "format": "date", "required": false },
7 "orderAmt": { "type": "number", "minimum": 0.01, "maximum": 99999.99,
8 "required": true, "scale": 2 }
9 },
10 "rules": [
11 { "id": "ORD-V1", "when": "customer not found", "reject": "Unknown customer" },
12 { "id": "ORD-V2", "when": "customer.credit_hold = 'Y'", "reject": "Customer on credit hold" },
13 { "id": "ORD-V3", "when": "shipDate < today or shipDate > today + 90 days",
14 "reject": "Ship date must be within 90 days" }
15 ],
16 "review": [
17 "shipDate NULL: ORD-V3 does not fire; field is not REQUIRED in the form",
18 "custNum NULL: SELECT returns NOTFOUND, ORD-V1 fires"
19 ]
20}

Architectural best practices

Build the Java side to the spec, not to the old shape.

  • Merge form attributes and AFTER FIELD logic into one validation contract per operation; the Java API should enforce all of it.
  • Decide NULL handling for every field explicitly and record it with the rule.
  • Turn CONSTRUCT screens into search endpoints with a documented, limited filter language rather than free-form SQL.
  • Keep error message texts with their rules; users and support staff recognize them and they make review faster.
  • Model multi-field screens as a single validated request in the API, even if the old UI validated field by field.

Informix estates are smaller and denser

Informix 4GL systems are rarely the size of a mainframe estate, but they are dense: a single module can hold screen flow, validation, SQL and reporting for a whole business function. Many still run order entry, inventory or policy administration at mid-sized companies, maintained by a shrinking group of people who know the language. That makes extraction urgent and also tractable, because the forms and the schema give the analyzer strong type information.

PYD ENTERPRISES extracts the rules, contracts and fixtures and links each one to .4gl and .per lines. It does not convert 4GL into Java. Your Java team builds services and screens against the reviewed spec.

Reading the order entry example

Three validations come out cleanly: unknown customer, credit hold and the 90-day ship window. The review items are where the value is. The ship date is not REQUIRED in the form, so a blank date passes ORD-V3 and the order is saved without one. Whether that is a feature (ship when ready) or a defect is a business question. The analyzer also notes that the credit hold check runs only when the cursor leaves the customer field; if the user never enters that field after a hold is placed in another session, the order still saves. A server-side API that validates the whole request removes that gap, and the spec makes the change visible.

FAQ

Informix 4GL to Java questions

Which Informix 4GL variants are supported?

Informix 4GL source is parsed, including INFORMIX-4GL and the compatible syntax used by later 4GL compilers. Vendor-specific extensions are flagged if not recognized, rather than skipped.

Are report blocks (REPORT ... FORMAT) analyzed?

Yes. Report functions are parsed; calculations and aggregates in them are extracted as rules, and layout logic is classified as presentation.

Do we need a running Informix database?

No. A schema export is enough to resolve LIKE declarations. A test database helps when running the generated fixtures against the existing programs.

Get the spec for your Informix 4GL estate.

Request a codebase scan and review extracted rules, contracts and fixtures for your own Informix 4GL estate, inside your VPC.