Bug #6997
OUTPUT BY-REFERENCE records are not cleared
0%
Related issues
History
#1 Updated by Dănuț Filimon over 1 year ago
In start.p, a temporary table main
is created which is assigned 1 element, then that table is used as an output parameter with BY-REFERENCE
and passed to a non-persistent external procedure.
start.p
DEFINE TEMP-TABLE main NO-UNDO FIELD field1 AS CHARACTER. CREATE main. ASSIGN main.field1 = "main-table". RUN test-ttbyref83proc.p (OUTPUT TABLE main BY-REFERENCE). FOR EACH main. MESSAGE "MAIN: " + STRING(main.field1). END.
In the external procedure there are 2 tables like main. The output table received is assigned another element, then it is passed to an internal procedure and another element is created. Finally, all the values are printed.
test-ttbyref83proc.p
DEFINE TEMP-TABLE main NO-UNDO FIELD field1 AS CHARACTER. DEFINE TEMP-TABLE main1 NO-UNDO FIELD field1 AS CHARACTER. DEFINE OUTPUT PARAMETER TABLE FOR main. CREATE main. ASSIGN main.field1 = "procedure-main-table". RUN int1(OUTPUT TABLE main BY-REFERENCE). PROCEDURE int1: DEFINE OUTPUT PARAMETER TABLE FOR main1. CREATE main1. ASSIGN main1.field1 = "internal-procedure-main-table". END. // Records from main should not be displayed FOR EACH main. MESSAGE "main NPP1: " + STRING(main.field1). END. // This item is not created CREATE main. ASSIGN main.field1 = "should-not-exist". // Records from main1 should be displayed if any FOR EACH main1. MESSAGE "main1 NPP2: " + STRING(main.field1). END.
The problem is that the FWD converted code has different results compared to the 4GL code. I only remarked this problem when passing a table using OUTPUT
and BY-REFERENCE
to a persistent/non-persistent procedure and then using the same specification to pass it into an internal procedure.
In test-ttbyref83proc.p, the first FOR EACH main
and the last CREATE main
are ignored in 4GL, but executed in FWD.
4GL output:
MAIN: main-table MAIN: procedure-main-table MAIN: internal-procedure-main-table
Converted code output:
main NPP1: main-table main NPP1: procedure-main-table main NPP1: internal-procedure-main-table MAIN: main-table MAIN: procedure-main-table MAIN: internal-procedure-main-table MAIN: should-not-exist
#2 Updated by Dănuț Filimon over 1 year ago
- Related to Support #6714: check if there is an optimization opportunity when copying temp-tables based on multiplex id added
#3 Updated by Ovidiu Maxiniuc over 1 year ago
- the CREATE /ASSIGN from
int1
are actually performed directly into themain
of thestart.p
which was sent BY-REFERENCE twice. This seems to work correctly; - after leaving
int1
, the localmain
andmain1
are not bound any more (although themain
is still bound tostart.p
's table as parameter). The creation ofmain
record which should-not-exist should be created the very same way as the internal-procedure-main-table. If the binding betweenmain
andmain1
still existed, themain1 NPP2
loop would have display it. So it must be created in themain
table which is still bound as output parameter to the table fromstart.p
. Actually, there is no difference between the two CREATEs in thetest-ttbyref83proc.p
procedure. The only factor which affects them is the call to internal procedureint1
. - personally, I think this is a BUG in OE which this testcase demonstrate. After returning from
RUN int1(OUTPUT TABLE main BY-REFERENCE).
, I guess the localmain
is unbound from the parameter and themain NPP1
and second CREATE does not happen on reference table, but on local table. This fully explain the output from the code when executed on OE.
#4 Updated by Ovidiu Maxiniuc over 1 year ago
I returned to this testcase. I altered the original code a bit and I found more evidences in favour of confirming the bug.
I added a second parameter to int1
and called it twice, like this:
RUN int1(OUTPUT TABLE main BY-REFERENCE, 1).
RUN int1(OUTPUT TABLE main BY-REFERENCE, 2).
PROCEDURE int1:
DEFINE OUTPUT PARAMETER TABLE FOR main1.
DEFINE INPUT PARAMETER a AS INT.
CREATE main1.
ASSIGN main1.field1 = "internal-procedure-main-table: " + STRING(a).
END.
With this, the output changes to:
main NPP1: internal-procedure-main-table: 2 MAIN: main-table MAIN: procedure-main-table MAIN: internal-procedure-main-table: 1
It is now clear that something happens between the two calls to internal procedure: the local main
table which was associated with the table from the caller is disconnected so that, in case of the second call, the local table is passed as parameter. Hence, the internal-procedure-main-table: 1
goes to output parameter while internal-procedure-main-table: 2
remains in local main
table.
LE: the original code has a small flaw (the main.field1
is displayed while iterating main1
table), but this is really irrelevant as the main1
table is empty.
#5 Updated by Constantin Asofiei 4 months ago
The problem in this task still exists.