This page describes product changes you must be aware of when upgrading from version 2.1x to version 2.2x of Genero BDL.
Warning: This is an incremental upgrade guide that covers only topics related to a specific version of Genero. Also check prior upgrade guides if you migrate from an earlier version.
Summary:
Some 2.2x bug fixes needed modifications inside the runtime system (fglrun) and front-ends (gdc, gwc). Therefore, if you upgrade the runtime system to the latest 2.2x version, we strongly recommend that you upgrade your workstations with the latest front-end version 2.2x as well.
As a general rule, when upgrading to a major or minor version like 2.10 to 2.20 or 2.20 to 2.21, you must recompile all your .4gl modules and .per form files. Re-compilation is not required when upgrading to a new maintenance release like 2.20.01 to 2.20.02.
See also Installation and Setup.
Starting with version 2.20, the navigation actions prevrow, nextrow, firstrow, and lastrow are now front-end local actions. In versions 2.1x, these actions were created by the runtime system as implicit dialog actions. The 2.2x runtime system will only create these actions when you use a DISPLAY ARRAY or INPUT ARRAY on a singular row screen record.
The programs will behave as in 2.1x. However, this modification makes the 2.1x migration issue "New firstrow/lastrow implicit actions" obsolete.
If these navigation actions have been used in dialog methods such as DIALOG.setActionActive(), you must review the code and remove these lines; otherwise an -8089 runtime error will be raised.
Starting with version 2.20, the built-in sort is now available during INPUT ARRAY. If you want to avoid sorts in a Table, use the UNSORTABLECOLUMNS attribute.
Before version 2.20, cell attributes were synchronized quite often by the runtime system, and this was not very efficient. As a result, there was not much difference between using buffered or unbuffered mode; when changing cell attributes, the result was immediate even in buffered mode.
Now with 2.20, it is recommended that you use the UNBUFFERED mode when setting cell attributes; otherwise, the colors will not be synchronized on the front-end.
Starting with Genero 2.20 (or when using multiple dialogs in 2.11.08 and higher), DIALOG class methods like setFieldActive() need the correct field specification with the screen-record name prefix if the field was explicitly bound with the FROM clause of INPUT or INPUT ARRAY. In previous versions, the field was found by these methods even if the prefix was invalid. (Actually, the prefix was just ignored and only the fieldname was used.)
For more details about field identification, see Identifying fields with dialog class methods.
Starting with Genero BDL version 2.20, program variable identification in static SQL statements is more strict than older Genero versions and Four Js BDS; if you define a variable with the same name as a SQL object (i.e. table name, table alias), the Genero BDL compiler will raise an error because it will consider the program variable first. For example, if the variable name matches the table or alias identifier, using table.column in the SQL statement will be resolved as variable.member, which does not exist.
The next code example will not compile because the program defines a variable using the same name as the table alias c:
01
MAIN02
DATABASE stores03
DEFINE c INTEGER04
SELECT COUNT(*) INTO c FROM customer c05
WHERE c.fname IS NULL06
END MAIN
The above code also fails to compile with Informix 4gl 7.32, but it did compile with BDS and older Genero versions.
To work around this, you must either rename the program variable, or explicitly identify SQL objects with the @ prefix in the SQL statement:
01
MAIN02
DATABASE stores03
DEFINE c INTEGER04
SELECT COUNT(*) INTO c FROM customer c05
WHERE @c.fname IS NULL06
END MAIN
Just recompile all your programs to find the conflicts.
Before Genero BDL version 2.20, is was impossible for a non-Informix driver to return SQL Warning information in SQLCA, SQLSTATE and SQLERRMESSAGE. SQL Warnings are now propagated for all database drivers, and can set the SQLCA.SQLAWARN, SQLSTATE and SQLERRMESSAGE registers.
This new behavior will have no impact if you test SQL Errors with STATUS or SQLCA.SQLCODE, as these registers remain zero if an SQL Warning is raised. However, if you are using SQLSTATE to check for SQL Errors, you must now distinguish SQLSTATE of class 01: These are SQL Warnings, not SQL errors.
In the next example, when connected to DB2, the SQLSTATE register will get the value 01504 indicating that all rows of the table have been deleted. As a result, testing SQLSTATE against 00000 will evaluate to false, and run into the error handling block, which is unexpected:
01
MAIN02
DATABASE stores03
WHENEVER ERROR CONTINUE04
DELETE FROM customer05
IF SQLSTATE <> "00000" THEN06
-- handle error07
END IF08
END MAIN
To check for successful SQL execution with or without warning, you can, for example, code:
01
MAIN02
DATABASE stores03
WHENEVER ERROR CONTINUE04
DELETE FROM customer05
IF NOT (SQLSTATE=="00000" AND SQLSTATE MATCHES "01*") THEN06
-- handle error07
END IF08
END MAIN
See also SQL Warnings for more details.
The SERIALREG based serial emulation is defined by the following FGLPROFILE entry:
dbi.database.<dbname>.ifxemul.datatype.serial.emulation = "regtable"
Genero BDL 2.20 introduces the BIGINT data type, which is a 64-bit signed integer. You can use BIGSERIAL or SERIAL8 columns with Informix, and ODI drivers can emulate 64-bit serials in other database servers. However, if you are using serial emulation based on the SERIALREG table, you must redefine this table to change the LASTSERIAL column data type to a BIGINT (If the BIGINT data type is not supported by the database server, you can use a DECIMAL(20,0) instead):
CREATE TABLE serialreg ( tablename VARCHAR2(50) NOT NULL, lastserial BIGINT NOT NULL, PRIMARY KEY ( tablename ) )
Warning: If you need to migrate an installed database using SERIALREG-based triggers, you will have to keep the current registered serials and use ALTER TABLE instead of CREATE TABLE. Next example shows the ALTER TABLE syntax for SQL Server. Check database server manuals for the exact syntax of the ALTER TABLE statement:
ALTER TABLE serialreg ALTER COLUMN lastserial BIGINT NOT NULL
Additionally, all existing SERIALREG-based triggers must be modified, in order to use BIGINT instead of INTEGER variables, otherwise you will get BIGTINT to INTEGER overflow errors. For example, to modify existing triggers with SQL Server, you can use the ALTER TRIGGER statement, which can be easily generated from the database browser tool (there is a modify option in the contextual menu of triggers). After the existing trigger code was generated, you must edit the code to replace the INTEGER data type by BIGINT in the variable declarations, and execute the ALTER TRIGGER statement.
Because Genero BDL 2.20 implements new data types like BIGINT and BOOLEAN, the database schema extraction tool has been reviewed to map native database types to these new types when possible. You must take care when extracting a .sch file from the database.
For example, before version 2.20, fgldbsch converted an Oracle NUMBER(20,0) to a DECIMAL(20,0) by default. Now, since 2.20 provides the BIGINT native FGL type, it can be used to store a NUMBER(20,0) from Oracle.
You can get the previous behavior by using a conversion directive with the -cv option of fgldbsch.
To see the new conversion rules, run the fgldbsch tool with the -ct option.
Prior to Genero BDL 2.20, if an unexpected error occured in a database driver, the driver could return error -768, which is a real Informix SQL error that instructs the user to call the IBM support center.
To avoid any mistake, 2.20 database drivers return now the error -6319 if an internal error occurs, which is a Genero specific error message that suggests you to set the FGLSQLDEBUG environment variable to get detailed debug messages.
For security reasons, the image file transfer mechanism has been slightly modified in version 2.20 (note that this modification has also been back-ported in 2.11.14):
If FGLIMAGEPATH is set, the current working directory is no longer searched as in previous versions. You must explicitly add "." to the list of directories. By default, if FGLIMAGEPATH is not defined, the runtime system still searches the current directory.
If FGLIMAGEPATH is defined, the image files used in IMAGE form fields or in the IMAGE attribute must be located below one of the directories listed in the environment variable. This constraint does not exist if FGLIMAGEPATH is not set and has been relaxed in 2.21.00 for image fields displayed by program (see below).
Starting with 2.21.00, images displayed by program to IMAGE fields are considered as valid files to be transferred to the clients without risk and do not follow the FGLIMAGEPATH security restrictions. Images are however searched according to the path list defined in FGLIMAGEPATH.
For more details, see FGLIMAGEPATH and IMAGE attribute.
Starting with version 2.20.00, the dialog class methods like ui.Dialog.setActionActive() can now raise a runtime error -8089 if the action name is invalid. Before version 2.20, the method ignored the invalid action name, and it could take a while for the programmer to find the mistake.
You can find more details about action identification in the Dialog Class page.
Starting with version 2.20.05, the dialog class methods like ui.Dialog.setFieldTouched() can now raise a runtime error -1373 if the field specified does not match a field in the current dialog. Before version 2.20.05, these methods previously ignored the invalid field specification, and it could take a while for the programmer to find the mistake.
You can find more details about action identification in the Dialog Class page.
Starting with version 2.20.05, the fglform compiler performs more layout checking than before. Thus, existing (invalid) forms that compiled with prior versions of Genero may no longer compile with 2.20.05. This strict checking is done to detect layout mistakes during form design, instead of having the front-ends render invalid forms in a unknown manner at run time.
For example, the following form definitions are invalid and will raise a compilation error with fglform:
01
SCHEMA FORMONLY02
LAYOUT03
GRID04
{05
[f01 : |f02 ] -- HBox layout tags in lists are denied06
[f01 |f02 ]07
[f01 |f02 ]08
[f01 |f02 ]09
}10
END11
END
01
SCHEMA FORMONLY02
LAYOUT03
GRID04
{05
[f01 ] [f02 ]06
[f01 ] [f02 ] -- Misaligned field tags (vertical)07
[f01 ] [f02 ]08
[f01 ] [f02 ]09
}10
END11
END
01
SCHEMA FORMONLY02
LAYOUT03
GRID04
{05
[f01][f01][f01] [f01] -- Misaligned field tags (horizontal)06
}07
END08
END
Version 2.20.06 fixes bug 13181 related to database schema files, which introduces a compatibility issue with older versions of fglcomp and fglform. If some database tables use data types that are equivalent to the BOOLEAN Informix type, such as the BIT type in SQL Server, you must re-generate the .sch database schema file with the fgldbsch tool. If you keep using the schema generated by an older version such as 2.20.04, fglcomp or fglform will raise the error -6634.
This problem will only occur if your database tables use the BOOLEAN (or native equivalent type). See ODI Adaptation Guides for more details about database specific boolean types.
Genero BDL version 2.21 introduced support for PostgreSQL 8.4 with the new database driver dbmpgs84x. This version of PostgreSQL implements a native INTERVAL type that is similar to the Informix / Genero INTERVAL type.
When using the dbmpgs84x (and higher) driver, Informix-style INTERVAL types will be mapped / translated to native PostgreSQL INTERVALs. Prior drivers will keep using the CHAR(50) replacement. If your application is storing INTERVAL in a PostgreSQL database, you will have to modify you database schema to replace the existing CHAR(50) column with the native INTERVAL data type of PostgreSQL 8.4. If you cannot migrate the database, you can still use the older dbmpgs83x driver using CHAR(50) for INTERVALs, but that driver requires a PostgreSQL client version 8.3.
For more details, see the ODI Adaptation Guide for PostgreSQL.
Before version 2.21, fglcomp --build-rdd only produced the .rdd data definition file. This option is now a compilation option: Both .42m and .rdd files are created at the same time.
When a unique or primary key constraint is violated, the Informix driver returns -268 if the database uses transaction logging, and -239 if the database uses no logging.
Regarding non-Informix drivers, all 2.21 drivers now return SQLCA.SQLCODE -268 when a unique constraint or primary key constraint is violated. Before 2.21, the Oracle and SQL Server / Sybase drivers returned error -239, which is only returned by Informix databases without transaction logging. Returning error -268 for all drivers is the best choice in a context of transactional databases.
Check your code for -239 error code usage and replace by -268. If you still need to test error -239 (for example because you have Informix databases without transactions), we recommend that you write a function testing different error codes to check unique constraint violation:
01
FUNCTION isUniqueConstraintError()02
IF (SQLCA.SQLCODE==-239 OR SQLCA.SQLCODE==-268)03
OR (SQLCA.SQLCODE==-346 AND SQLCA.SQLERRD[2]==-100)04
THEN05
RETURN TRUE06
ELSE07
RETURN FALSE08
END IF09
END FUNCTION
Before version 2.21.00, the Genero db drivers (dbmads*) were linked on Windows with ODBC32.LIB, using the Windows Driver Manager. With 2.21 the dbmads* drivers are now linked directly with AODBC.DLL to bypass the Driver Manager, as is done on Unix platforms. You must now set the PATH environment variable to point the the AODBC.DLL library: the DLL specified in the ODBC data source is now ignored.
For more details, see the ODI Adaptation Guide for Genero db.
Before 2.21.00, the IMPORT instruction for C-Extensions was documented as allowing a comma-separated list of libraries:
IMPORT lib1, lib2
This compiled, but at runtime only the first library was found. Using elements of the other libraries raised a runtime error.
With 2.21.00 and the new 42m module importation support, the compiler is now more strict and denies the comma-separated syntax. You must specify every library, Java class or 4gl module in separate lines:
IMPORT lib1 IMPORT JAVA myclass IMPORT FGL mymodule
(This issue was actually registered as a bug/enhancement #15128)
Starting with 2.21.00, the INITIALIZE TO NULL instruction clears the dynamic arrays (i.e. array.getLength() returns 0). Before this version, all elements of the dynamic where kept, and set to null. Since the old behavior was documented, this behavior change required a migration note. The new behavior is expected by most programmers.
(This issue was actually registered as a bug #15666 and #15700)
The fglform compiler of version 2.21.00 makes now a strict checking of the fields used in the screen record definition for table containers and generates error -6819 if the screen record do not use all columns used in the table. Note that the order can be different, however.
For more details, see Table containers.
The INPUT ARRAY dialog and sub-dialog provides the APPEND ROW and AUTO APPEND attributes to control row creation at the end of a list (a.k.a. temporary row creation). APPEND ROW controls explicit temporary row creation while AUTO APPEND controls automatic temporary row creation. Starting with version 2.20, moving down after the last row (with the mouse or keyboard) or leaving the last column of the last row with a TAB key are now considered as events to trigger automatic temporary row creation. Before 2.20, these cases were considered as events for an explicit temporary row creation. In other words, if you want to deny temporary row creation in such case, it is now done with AUTO APPEND = FALSE while in older versions it was controlled by APPEND ROW = FALSE.
For more details, see Handling temporary row creation.
Starting with version 2.20, (or with version 2.10 when FGL_USENDIALOG=1), the dialogs will automatically disable some predefined actions if it makes no sense to trigger the action in the current context. For example, during an INPUT ARRAY, if there are no rows to remove, the predefined delete action will be disabled automatically. Similarly, the insert and append actions get disabled when the array is full (this can happen with static arrays or when using the MAXCOUNT attribute). Note that the predefined actions will also be disabled if you overwrite them with your own ON ACTION handler.
The BEFORE ROW control block indicates if a new row is reached in a DISPLAY ARRAY or INPUT ARRAY. Before version 2.20, the BEFORE ROW block was always executed when entering a DISPLAY ARRAY or INPUT ARRAY dialog, even if the number of real data rows was zero. Starting with 2.20, when using an empty dynamic array or when using a static array and specifying zero data rows with a SET_COUNT(0) call or with the COUNT=0 attribute, the BEFORE ROW control block is no longer executed when the dialog starts.
Note that the BEFORE ROW block will be executed when a new row is created in INPUT ARRAY. When entering an INPUT ARRAY with an empty array, a new temporary row is created by default, except if you use the AUTO APPEND = FALSE attribute.