Bug #10636
4GL FOR FIRST LEAVE statement exits the function
100%
History
#1 Updated by Teodor Gorghe 10 months ago
On OE 11.6, there is a strange feature, when there is a LEAVE statement on a FOR block with a RECID or ROWID in where clause, in an OO method, 4GL does not leave the current FOR block but acts like RETURN ?.
On FWD, the LEAVE statement leaves the FOR block, in all cases, and then executes what is next in the current method.
#3 Updated by Teodor Gorghe 10 months ago
On OE 11.6, this does not happen when the RECID/ROWID function is used on an inequality condition.
When there is more than 1 nested FOR loop, all with the RECID/ROWID equality condition, the method exit happens. If one nested FOR block does not have that equality, then the LEAVE statement acts like it should be, leaving the current block.
#4 Updated by Greg Shah 10 months ago
There are other cases when the 4GL decides to convert a LEAVE (or a NEXT) to a RETURN.
You can look inside rules/annotations/block_properties.rules and you will find sections like this:
<!-- ON phrases and the UNDO statement can be specified with secondary
actions (RETRY, LEAVE, NEXT) which have no explicit target (label),
in such cases the target is always the same as the target of the
UNDO AND depending on the target block properties, the action may
be statically converted as in the following:
1. If the action is LEAVE or NEXT and the target block is a
top-level block, then the action will be converted to a RETURN.
2. If the action is NEXT and the target block is a non-iterating
inner block (it is not a top-level block), then the NEXT will
be converted to a LEAVE.
RETURN is an action that never references a label so it is
ignored in this processing.
RETRY will automatically be targetted to the same block as a
pending UNDO by the runtime, so it can be ignored here. This means
that we avoid emitting an extra string in the converted source
code, which is better.
-->
...
<!-- NEXT statement that explicitly targets a FOR FIRST/LAST must
convert to a LEAVE -->
...
<!-- NEXT statement without an explicit target (label) must have one
calculated in this 3 phase process:
1. The nearest enclosing iterating block.
2. The nearest enclosing FOR FIRST/LAST. In this case, the NEXT
will be statically converted to a LEAVE.
3. NEXT converts to a RETURN (because it is implicitly targetting
a top-level block).
Note that a more deeply nested FOR FIRST/LAST will NOT take
precedence over a more enclosing looping block. So each phase of
this search must be executed completely before the next phase can
start.
-->
...
<!-- LEAVE statement without an explicit target (label) must have one
calculated:
1. The nearest enclosing non-simple DO inner block.
2. LEAVE converts to RETURN (because it is implicitly targetting
a top-level block).
-->
Please consider those conditions and try to determine how labeling, NEXT etc... work in your cases.
#5 Updated by Constantin Asofiei 10 months ago
Teodor, I think this is just the target of the leave/next is the outer block in such case:
def var r as rowid.
find first book.
r = rowid(book).
release book.
def var l as log.
repeat:
message "next" l.
if l then leave.
l = true.
for first book where rowid(book) = r:
message "here".
if l then next. // looks like this targets the outer block by default if 'rowid' (or 'recid'?) is used
end.
message "done".
end.
message "finished".
This shows 'finished' and executes the REPEAT twice.
Is not just that it converts to RETURN.
Please test with something other than OE11.6 also.
#6 Updated by Constantin Asofiei 10 months ago
Also, you can target the FOR block in OE if it has an explicit label and that is used for leave/next. So just the implicit label seems to be impacted.
#7 Updated by Teodor Gorghe 9 months ago
- Assignee set to Teodor Gorghe
- Status changed from New to WIP
Created task branch 10636a.
#8 Updated by Teodor Gorghe 9 months ago
- Status changed from WIP to Review
- % Done changed from 0 to 100
- reviewer Constantin Asofiei added
Committed revision 16215 on task branch 10636a:
- NEXT/LEAVE points to the outer block, when the current FOR BLOCK has RECID/ROWID equality on WHERE clause.
#9 Updated by Constantin Asofiei 6 months ago
- Status changed from Review to Internal Test
#10 Updated by Teodor Gorghe 6 months ago
Rebased task branch 10636a to trunk revision 16358.
#11 Updated by Constantin Asofiei 6 months ago
- Status changed from Internal Test to Merge Pending
Merge to trunk after 10560a
#12 Updated by Teodor Gorghe 6 months ago
- Status changed from Merge Pending to Test
Branch 10636a was merged to trunk rev. 16385 and archived.
#13 Updated by Constantin Asofiei 6 months ago
- Status changed from Test to Closed