Kbase P106786: 4GL: The BREAK BY option and its extra 'look ahead' buffer explained.
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  05/12/2009 |
|
Status: Verified
GOAL:
4GL: The BREAK BY option and its extra 'look ahead' buffer explained.
GOAL:
What is the BREAK BY option of the FOR EACH and the DO PRESELECT 'look ahead' buffer?
GOAL:
How does the BREAK BY option of the FOR EACH and the DO PRESELECT statements affect data availability?
FACT(s) (Environment):
All Supported Operating Systems
Progress/OpenEdge Product Family
FIX:
This Solution describes the behavior of the BREAK BY option of the DO or the FOR statements. This option may appear to change the normal behavior of the FOR EACH or the DO PRESELECT statements' record buffer availability.
When the BREAK BY option is used, an additional internal buffer is maintained. This additional buffer is used to "look ahead" at the next row in the query to determine whether a breakpoint will be encountered based on the fields specified in the BREAK BY and the values in the current data buffer(s) for the query. The "look ahead" also allows the calculation of any aggregate values required before releasing the last record of a group from the current data buffer(s).
With the BREAK BY option a buffer's data remains available outside a FOR EACH or a PRESELECT block. While without the BREAK BY option, no such data is available outside these blocks. The following code snippet demonstrates this situation:
FOR EACH Customer:
END.
MESSAGE AVAILABLE(Customer)
VIEW-AS ALERT-BOX INFO BUTTONS OK.
FOR EACH Customer BREAK BY country:
END.
MESSAGE AVAILABLE(Customer)
VIEW-AS ALERT-BOX INFO BUTTONS OK.
This can be explained by the normal behavior of a LEAVE within a FOR EACH block. If you allow the FOR EACH loop to continue to the end-of-file condition, the buffer contents will be cleared out after control exits the FOR EACH loop. With the BREAK BY however, the "look ahead" buffer is actually one record ahead of the data buffer, so it encounters the end-of-file condition, a LEAVE of the FOR EACH block is executed, and the query's data buffer retains the last record values.
Another side-effect can be seen with sub-procedures called from within a FOR EACH or PRESELECT with the BREAK BY option. The "look ahead" buffer cannot be referenced directly by the 4GL developer. It is strictly a local buffer and cannot span procedures. Therefore, any break functionality must be performed within the procedure containing the FOR EACH or PRESELECT statement. For example, the following code will fail with the error: "BREAK keyword or BY phrase missing for aggregate expression. (574)"
DEFINE BUFFER bCustomer FOR Customer.
DO PRESELECT EACH bCustomer NO-LOCK BREAK BY Country:
RUN test.p(BUFFER bCustomer).
END.
/* test.p */
DEFINE PARAMETER BUFFER pbCustomer FOR Customer.
FIND FIRST pbCustomer.
IF FIRST-OF(Country) THEN
DISPLAY pbCustomer.Custnum.
The above example fails because the FIRST-OF function in the sub-procedure does not have access to the internal "look ahead" buffer implemented for the BREAK BY option in the main procedure.