INTERVAL now carries its qualifier as a value. FglIntervalQualifier holds the
two fields it spans and how many digits the leading one has; FglInterval keeps
it, so a value knows how wide it prints without anything being passed alongside
it. The precision is part of the type in 4GL, not decoration - YEAR(4) TO MONTH
and YEAR(2) TO MONTH display the same magnitude differently - and it was being
dropped. Rendering writes the fields the qualifier actually spans and stops at
its last one, so HOUR TO MINUTE is "12:30" and not "12:30:00", and the value is
right-aligned in the width the qualifier gives it. The new interval fidelity
probe pins all of this against the C runtime.
Also on the temporal types: arithmetic on DATETIME and INTERVAL, DATE plus or
minus an INTERVAL (month arithmetic clamping to the target month's last day),
comparison operators for DATETIME, EXTEND, and an INTERVAL literal.
LOAD and UNLOAD are implemented, following Informix's delimited format - one
line per row, a trailing delimiter before the newline, NULL written as nothing,
and delimiter, newline and backslash escaped within a value. PUT and FLUSH on
an insert cursor. Neither has been run against a live database.
Missing builtins added: writeln, FGL_LASTKEY and FGL_KEYVAL (using the
numbering from A4GL_net_keyval and the A4GLKEY_ constants, so a program
comparing them sees the same values as under the C runtime), the UNITS
builtins, Pow, and PRINT with no argument. DAY, MONTH, YEAR, WEEKDAY and MDY
take object? and give back a nullable, so a NULL date propagates instead of
throwing, and they accept a DATETIME as 4GL allows. CompareString gained an
overload that compares a DATE as a date rather than as text - as strings
"01/01/1901" sorts before "12/31/1900".
STATUS is assignable, routed through a setter that keeps the status fields
consistent rather than writing SqlCode alone. CONTINUE moved to the dialog base
class, since 4GL spells it for every kind of dialog. f_open and readln take the
shape of the C entry points they replace, with their results as out parameters.
The client/server call layer still throws, but with the signatures its
prototypes describe rather than params object?[] guesses - the generator emits
out arguments for the values a function returns, and a params array cannot take
one.