CUCO study materials
CUCO study resources

SEARCH ALL on a Table Loaded in Arrival Order Returns Wrong Reps

CUCO · Put your knowledge to work in context.

All case studies

SEARCH ALL on a Table Loaded in Arrival Order Returns Wrong Reps

Bayline Insurance has a monthly commission program. It loads up to 200 sales reps into WS-REP-TABLE, which has OCCURS 200 TIMES ASCENDING KEY IS REP-ID INDEXED BY REP-IDX. The table is filled in the order transactions arrive. WS-REP-COUNT holds how many entries were loaded. The program uses SEARCH ALL to find a rep for each transaction. In unit tests with 8 reps entered in ascending ID order, all lookups succeed. In production, with 120 reps in arrival order, about half the lookups fail, and a few return a different rep's commission rate. The same table is passed BY REFERENCE to subprogram CALC-COMM, which increments a counter in the table and sorts nothing. After CALC-COMM returns, some REP-ID values in the caller are blank. A developer suggests replacing SEARCH ALL with SEARCH and passing BY CONTENT.

1. Explain why SEARCH ALL fails on the production data but passes the unit test.

Read the worked answer

SEARCH ALL performs a binary search. It requires the table to be ordered on the search key in the direction declared by ASCENDING KEY or DESCENDING KEY. The ASCENDING KEY clause documents the ordering; it does not sort the table. The production table is loaded in transaction arrival order, which is unrelated to REP-ID, so the binary search follows comparisons into the wrong half of the table. It can miss an existing rep or land on an entry that does not match the requested key.

The unit test passed because the eight reps happened to be entered in ascending REP-ID order, which is exactly the precondition for SEARCH ALL. The wrong commission rates occur when the binary search returns a different entry that the program then uses without verifying REP-ID. The count field is not the problem for lookup; the physical order of the loaded entries is.

2. Compare the candidate fixes and recommend one for this workload.

Read the worked answer

There are three reasonable fixes:

  • Use serial SEARCH. It scans from the first entry and does not require ordering. With at most 200 entries and 120 in production, the cost is small and the code is simple. This is the lowest-risk correction.
  • Sort the table once after loading, then keep SEARCH ALL. This preserves logarithmic lookup but adds a sort step and a new failure mode if the sort key or duplicate handling is wrong. The table must be sorted on REP-ID in ascending order before the first search.
  • Use a keyed file or an index built during load. This may be worthwhile if the table grows or lookups dominate, but it is more change than this problem requires.

For 120 entries, recommend SEARCH first. If profiling later shows lookup cost matters, sort once and use SEARCH ALL, with a test that loads the table in reverse and random order. Whichever search is used, verify that the found REP-ID equals the requested REP-ID before using the rate, and ensure REP-ID values are unique.

3. Evaluate the proposal to pass the table BY CONTENT, including the blank REP-ID symptom.

Read the worked answer

BY CONTENT passes a copy, so the caller does not see changes the subprogram makes to the table. That would hide the blank REP-ID symptom in the caller, but it would also discard the counter increment that CALC-COMM is supposed to make. If the counter is an intended output, BY CONTENT changes the program's behavior and is not a valid fix.

The blank REP-IDs point to a layout or bounds problem, not to the passing mechanism. Likely causes are a mismatched copybook between caller and subprogram, a subscript that runs past WS-REP-COUNT, a group INITIALIZE in the subprogram that clears more than intended, or a linkage description whose OCCURS count differs from the caller's. BY CONTENT would mask the symptom while leaving the subprogram's memory corruption or logic error unresolved. Inspect the linkage section and copybook, add bounds checks against WS-REP-COUNT, use BY REFERENCE only for data that must be updated, and pass the count explicitly. Test with a table filled in unsorted order and with entries beyond the loaded count.