Upgrading programs that have SEARCH ALL statements

Enterprise COBOL has corrected errors in the implementation of the SEARCH ALL statement. SEARCH ALL statements in earlier releases of COBOL contained errors in the key comparison logic, which caused different results than might have been intended. In particular, the comparison did not produce the same result as an IF statement or a sequential SEARCH statement.

Length mismatch problem: a search argument is longer than the table key

The SEARCH ALL statement comparisons should pad an alphanumeric key with blanks or extend a numeric key with leading zeros if the key is shorter than the SEARCH argument. However, in V3R3 and earlier releases, SEARCH ALL ignored the excess characters in the argument in some cases. For example, an alphanumeric search argument of 01 ARG PIC X(6) containing "ABCDEF" would incorrectly match a table or array key of 05 MY-KEY PIC X(4) with value "ABCD". A search argument containing "ABCD??" (where ? is a blank) would match, as expected.

Similar problems occurred with a numeric search argument and keys. For example, a search argument of 01 ARG PIC 9(6) containing 123456 would incorrectly match a table or array key of 05 MY-KEY PIC 9(4) with value 3456. A search argument containing 003456 would match, as expected.

Sign mismatch problem: signed numeric argument and unsigned numeric key

A second problem occurs when the search argument is a signed numeric item and the table key is an unsigned numeric item. If the runtime value of the search argument is negative, such as -1234, programs compiled with V3R3 and earlier would match a table key of 1234. These comparisons should be done using the rules for a normal COBOL relation condition, and a negative argument such as -1234 should never match a table key that is unsigned.

The correction:

Enterprise COBOL corrected these problems. However, some applications compiled with earlier releases might depend on the incorrect behavior. You must identify and modify these applications before you move them to Enterprise COBOL Version 4 or later.

To assist you in identifying the programs and SEARCH ALL statements that are impacted by these corrections, the following compiler and runtime warning diagnostics are issued.
  • Compiler messages: Enterprise COBOL compiler generates the following compiler diagnostics. Whether there is an actual impact depends on the contents of the argument at run time.
    • IGYPG3189-W for all SEARCH ALL statements that have a search argument that is longer than the table key, and hence might be impacted by the first problem
    • IGYPG3188-W when the search argument is a signed numeric item and the table key is an unsigned numeric item, and hence the program might be impacted by the second problem
  • Runtime messages: The following runtime messages are generated. Programs that generate either of these runtime messages might be affected by the change.
    • IGZ0194W for all SEARCH ALL statements that have search arguments with excess bytes that are not blank or zero.
    • IGZ0193W when the search argument is a signed numeric item with a negative value and the table key is an unsigned numeric item.

To migrate

To move an application to Enterprise COBOL Version 4 or later, do one of the following sets of steps:

  • Act on the compiler messages:
    1. Compile your programs with Enterprise COBOL
    2. Review any SEARCH ALL statements that are flagged with compiler messages IGYPG3188-W or IGYPG3189-W; such statements are potentially impacted.
      Tip: To minimize the possibility of incompatible results, you can force programmers at your site to correct these SEARCH ALL statements by changing the severity of these messages to E or S. To change the severity of these messages, you can use the MSGEXIT suboption of the EXIT compiler option. By doing this, the programs that get these messages cannot be run until the code is corrected. The sample user exit IGYMSGXT has sample code in it to change the severity of IGYPG3188-W and IGYPG3189-W, to IGYPG3188-S and IGYPG3189-S, respectively.
  • Act on the runtime messages:
    1. Run the application in a test environment.
    2. Review any SEARCH ALL statements that generate runtime message IGZ0193W or IGZ0194W.

After you have identified which of the SEARCH ALL statements are affected, adjust the application logic appropriately by doing the following steps:

  • For SEARCH ALL statements in which the search argument is longer than the table key, do one of the following actions:
    • Ensure that any bytes in the argument in excess of the key length are spaces or zeroes as appropriate.
      Tip: When you have completed this investigation and if you decided not to change your programs, you can change the severity of IGYPG3188-W and IGYPG3189-W, to IGYPG3188-I and IGYPG3189-I, respectively, or suppress these messages entirely, by using the MSGEXIT suboption of the EXIT compiler options. This allows your programs to then compile with RC=0. The sample user exit IGYMSGXT has sample code in it to change the severity of IGYPG3188-W and IGYPG3189-W.
    • Move the argument to a temporary data item of the same size as the key and use the temporary item as the search argument.
    • Limit the range of the comparison with reference-modification. For example:
      • in the alphanumeric case of search argument 01 ARG PIC X(6) and key of 05 MY-KEY PIC X(4) use this:
        WHEN MY-KEY (MY-INDEX) = ARG(1:4)
      • in the numeric case of search argument 01 ARG PIC 9(6) and array key of 05 MY-KEY PIC 9(4) use this:
        WHEN MY-KEY (MY-INDEX) = ARG(3:4)
    The second and third actions above will prevent the warning message in the future.
  • For SEARCH ALL statements in which the search argument is signed and the table key is unsigned, ensure that the search argument is correctly initialized to a positive value before the SEARCH statement is run. Depending on the specific application logic in the COBOL program, it might be possible to make one of the following changes:
    • Change the data description of the argument to be unsigned.
    • Move the search argument to a temporary variable with no sign and use the temporary variable in the SEARCH ALL statement.
    Either action will prevent the warning message in the future.