Bug #8101
Issue with temp-table defined as reference-only
100%
History
#1 Updated by Theodoros Theodorou over 2 years ago
An exception is thrown when TestCodepageConversions.cls is executed regarding temp-tables.
Ovidiu Maxiniuc wrote:
The problem is that, in
TestCodepageConversions, theCodepageMatchtemp-table is defined asreference-only. It cannot be used until it is bound to a 'true' temp-table. This is done by passing that table as a parameter withBINDoption.I reviewed at the code and there are some pieces of code which were temporarily commented out because it regresses other BIND and REFERENCE-ONLY cases.
The good part is that we can and hopefully will use this testcase to adjust the code to make all these cases to work.
#2 Updated by Theodoros Theodorou over 2 years ago
I think I found the issue. In the TemporaryBuffer.java
/**
* Open a new buffer scope for this record buffer. Open a new multiplex
* scope and assign a multiplex ID the first time we are invoked for a
* buffer instance.
*/
protected void openScope() {
BufferManager.registerScopeable(bufferManager);
if (referenceOnly) return;
When I comment out the if (referenceOnly) return; it works, although I am not sure if I should remove it and if this is the right approach to the solution.
#3 Updated by Greg Shah over 2 years ago
This isn't likely to be a FWD issue. Don't make edits there yet. It is more likely a dependency on the 4GL code side that is not being processed as expected.
Please post the details of the failure itself and what specific 4GL code fails. Marian can help explain how that code is supposed to work.
#4 Updated by Theodoros Theodorou over 2 years ago
The failure comes from the line boolean hasRecords = local.nonEmptyTableFlags.contains(multiplexID); in TemporaryBuffer.java. It throws a NullPointerException because the private Integer multiplexID is null.
I created a small dummy test based on TestCodepageConversions.cls to track down the issue.
using Progress.Lang.*.
using OpenEdge.Core.Assert from propath.
using support.test.* from propath.
routine-level on error undo, throw.
class examples.MyTest:
define temp-table TempTableReference reference-only
field src as integer.
define static temp-table StaticTempTable
field src as integer.
method public static void emptyStaticTempTable(output table StaticTempTable bind):
empty temp-table StaticTempTable.
end.
@Test.
method public void testTempTable():
empty temp-table StaticTempTable.
emptyStaticTempTable(output table TempTableReference bind).
end method.
end class.
This test works with OE. With FWD, it fails at empty temp-table StaticTempTable inside the emptyStaticTempTable() method.
As I understand, the output table TempTableReference bind fails in FWD because define temp-table TempTableReference is reference-only. In TemporaryBuffer.openScope() the line if (referenceOnly) return; blocks the execution of TemporaryBuffer.openMultiplexScope() which sets the value of private Integer multiplexID.
#5 Updated by Theodoros Theodorou over 2 years ago
The above 4gl code generates the following java code.
private static ContextLocal<Statictemptable_1_1.Buf> statictemptable = new ContextLocal<Statictemptable_1_1.Buf>()
{
protected Statictemptable_1_1.Buf initialValue()
{
return TemporaryBuffer.define(MyTest.class, Statictemptable_1_1.Buf.class, "statictemptable", "StaticTempTable", false);
}
};
private Temptablereference_1_1.Buf temptablereference = TemporaryBuffer.define(MyTest.class, Temptablereference_1_1.Buf.class, "temptablereference", "TempTableReference", false);
...
public static void emptyStaticTempTable(final OutputTableParameter statictemptableBuf2)
{
ObjectOps.load(MyTest.class);
internalProcedure(MyTest.class, "emptyStaticTempTable", new Block((Init) () ->
{
TemporaryBuffer.associate(statictemptableBuf2, statictemptable.get(), ParameterOption.BIND);
},
(Body) () ->
{
statictemptable.get().deleteAll();
}));
}
public void testTempTable() // this is the entry point
{
internalProcedure(MyTest.class, this, "testTempTable", new Block((Body) () ->
{
statictemptable.get().deleteAll();
emptyStaticTempTable(new OutputTableParameter(temptablereference, ParameterOption.BIND));
}));
}
statictemptable.get() inside testTempTable() and in emptyStaticTempTable() are different. This is because TemporaryBuffer.associate(...); is called. As I understand, temptablereference is the reference which should point to statictemptable. I think statictemptable shouldn't be modified inside TemporaryBuffer.associate(). I tried to dig into TemporaryBuffer.associateImpl() but the code is too complicated. Can someone have a look at this?
#7 Updated by Constantin Asofiei over 2 years ago
- Status changed from New to Closed
- Assignee changed from Theodoros Theodorou to Constantin Asofiei
- % Done changed from 0 to 100
Fixed in trunk rev 15028 via 8329a.