This article applies to OpenEdge 10.x and later only. For older releases, refer to Article:
Why do Schema changes require application code to be recompiled ?The OpenEdge client ensures that the program running only has references to database objects (Tables, Indexes and LOBs) for which the definitions have remained unchanged since the last compile. This prevents ungraceful runtime errors and writes to the database with internal inconsistencies, which could occur when the application software tries to address a non-existent or unrecognized data structure.
This is done by storing CRC values for tables and indexes into the compiled code. (LOB fields are calculated into the table CRC).
- For tables, the CRC is stored if there is a static reference to the table or one of it's fields in the code. This value is compared with the database schema structure at run time to verify the connected database has the same schema structure in place as the database(s) at compile time.
- For indexes, the CRC is stored if the index is used by a static QUERY, FOR EACH or FIND construct. This can be explicitly specified with a USE-INDEX option, but more commonly this is determined implicitly by the compiler. In the second case, the SEARCH entries in the XREF listing will indicate which indexes the code uses.
When an r-code file is loaded at runtime, the CRC's stored in the r-code are checked against the CRC's stored in the currently connected databases (which do not have to be the same as the ones connected at compile-time). If the CRC's do not match at that time, the code will not be executed.
Referencing a table does not include using the LIKE option to define variables, temp-tables or temp-table fields based on dictionary entries.
Dynamic objects working on the database (dynamic buffers, queries and related constructs) are handled at runtime only, and do not cause any CRC values to be stored at compile time even if the object names are hard-coded. This includes the shorthand notations For example: "
<buffer handle variable>::<buffer-field name>"
In contrast, a dynamic reference to a static buffer will require recompiling when the schema changes. For example: "
BUFFER customer:FIND-FIRST()"
Which Schema changes do require code to be recompiled ?The following changes will affect the table CRCs and will therefore require the code to be recompiled.
For Tables:
- Changing the name of the table or index
- Deleting a field in the table
- Added a field to the table (pre-10.1C)
- Changing the field order within the table
For Table Fields:
- Changing the name, data type, decimal precision, number of extents or case sensitivity
- Changing foreign database metadata in a schema-holder database for Dataservers (foreign database field type, length, offset, or case sensitivity)
For Indexes:
- Changing the index name, uniqueness requirement or abbreviated option.
- Adding, removing or changing the order of the indexed fields
- Changing the ascending/descending order of an indexed field
In previous OpenEdge versions, after a field is added to a table, any r-code compiled against the old version of the table will not run, because the CRC in the r-code is different from the CRC in the schema.
In
OpenEdge 10.1C and later, the CRC check is relaxed in some instances, to provide better support for online schema changes on the client side. If the change to a table is a simple addition of one or more new fields, the old r-code will still execute, even though the CRCs no longer match. When the CRCs do not match, the AVM tests whether the fields of the table (specifically, their names, data types, extents, and logical field record positions) have changed since the r-code was compiled. If they have not changed, the old r-code will run. One case where it will not run is if one of the new fields has a
logical field record position less than one of the old fields (in other words, a new field has been inserted into the logical record position sequence).
Since 10.1C, there are 3 exceptions to these rules when connecting an OpenEdge client to an OpenEdge database.
In the following cases the
Table CRC changes, but the client will continue to execute the code compiled against a previous version of the schema without requiring a recompile:
- Adding a field to the table
- Changing the field order within the table
- Changing the decimal precision on a table field
A side-effect of this change in 10.1C is that the CRC check is relaxed after a field is added to a table. This does not just apply to connected users at the time of the on-line change, but permanently. If the change to a table is a simple addition of one or more new fields, the old r-code will still execute, even though the CRC no longer matches for the table.
In this case the AVM tests whether the fields of the table have changed since the r-code was compiled. If not, the old r-code will run. If however any of the below field attributes are changed an error will be thrown:
- Field Name
- Data-type
- Extent
- Logical field record position (rpos))
Database CRC changes that do not prevent r-code executionNote that for example because the table's CRC has changed, a binary load will fail because the CRC does not match with the database it was dumped from.
Table CRCs do not match. Cannot load data into this table. (6713)
Table PartitionsOpenEdge 11.4 introduced Table Partition capabilities to the OpenEdge database. When partition policies are created existing indices may be selected to be used to define Table Partition Policies. If existing indices are used, these indices will be converted to
a local partition aligned index. Code which was already compiled with the existing index will not need to be recompiled. The
local partition aligned index will simply work more efficiently when queries are performed to find partition data that matches the query.
When a Partition Policy is not created based on an existing index then code should be recompiled after the partition policy is implemented so the new code picks up the local partition aligned index that was created by implementing the partition policy. This may necessitate two sets of code be kept for situations where multiple end-users make use of a common product but not all of the end users make use of table partitioning.
Code specifically compiled to pick up Local Partition indices will not run against a table that does not have Table Partitioning enabled and specifically, Table Partitioning enabled for the same data the code is written to interact with.
Which schema changes do not require recompiling but may affect the code ?The OpenEdge Dictionary includes many features that, in effect, provide defaults for functional application code. Any change to one of these items will not force a recompile of the object code, and will not change the table's CRC.
However, it is important to remember
if the code is not recompiled, the change will not take effect:
- These features will be written to the compiled program at compile time, and will not be updated from the database at runtime.
- Without recompiling, Data Dictionary changes will not be included in the r-code. For example: After adding Data Validation statements or making Security Changes, the old r-code continues to allow updates without enforcing the new validation and the new security is not in effect. In most cases, if changes are made in these areas a recompile is recommended.
These application-oriented changes are:
- Adding, changing or removing validation expressions and messages of a table or it's fields.
- Adding, changing or removing schema triggers of a table or it's fields.
- Adding, changing or removing security settings of a table or it's fields.
- Changing the initial value, max value or mandatory requirement of a field in the table.
- Changing the format, label, column-label or help message of of a field in the table.
Other changes that do not force a recompile:
- Making a different index the Primary index for the table. Existing static code will keep using the same indexes it used before. Dynamic constructs will pick the different Primary index only if the index selection algorithm ends up defaulting to primary index.
- Adding new indexes to an existing table. Existing static code will simply not use the new index, even if it would benefit from it. Dynamic constructs will be able to use them as these determine index usage at runtime.
- Adding a new table and its associated fields. Static code would need to be modified to use the new table anyway. Dynamic code may be able to see and work with these tables, depending on how it's written.
Which Schema changes do not require recompiling and will not affect the code ?The database offers features to manage the physical storage of the tables, the memory management, the support of SQL connections etc. A number of these features are configured through the schema definitions.
The ABL client only cares about the
logical layout of a table. Any changes made to these database features have no impact at all on the r-code. These features include, but are not limited to:
- Moving object to a different storage area
- Changing the description of a table or it's fields
- Configuring the object to use the Alternate Buffer Pool (10.2B and later)
- SQL field width/field format.