Feature #3940
CREATE-RESULT-LIST-ENTRY() method support
100%
Related issues
History
#1 Updated by Greg Shah over 5 years ago
As noted in #3762, we must provide support for both BROWSE:CREATE-RESULT-LIST-ENTRY()
and QUERY:CREATE-RESULT-LIST-ENTRY()
.
From Stanislav:
I've been wondering if the core of the implementation is the idea that the query is closed and reopened such that there is a new result list.
Unfortunately it's not the case. The new entry contains ids of the current records contained in the query's backing buffers. It can be arbitrary records not matching the original query sorting. "No record" is also a valid entry.
Note that I'm not going to implement
CREATE-RESULT-LIST-ENTRY
for non-scrolling queries because it seems to be inpractical: what is the sense of adding an entry if you cannot get back to it? I guess that underlying implementations for scrolling and non-scrolling queries are similar in 4GL, while in FWD it may be completely different, so that will save a lot of time.
#2 Updated by Greg Shah over 5 years ago
Stanislav: You spent some time on this recently. Please post your findings here. What branch has your code changes?
#3 Updated by Stanislav Lomany over 5 years ago
Stanislav: You spent some time on this recently. Please post your findings here. What branch has your code changes?
Which branch do you want me to commit to? The changes are small and safe.
#4 Updated by Greg Shah over 5 years ago
Use 3750b.
#5 Updated by Greg Shah over 5 years ago
Stanislav:
- I don't think your changes are in 3750b yet.
- Did you write testcases? If so, where are they?
- Please document a list of your findings.
- What aspects of the problem still need testcases? We will have external resources write these.
#6 Updated by Stanislav Lomany over 5 years ago
Greg, where I can commit to, except 3750b?
#7 Updated by Greg Shah over 5 years ago
Put it in 3908a.
#8 Updated by Stanislav Lomany over 5 years ago
Put it in 3908a.
I don't see an active branch with this number.
#9 Updated by Greg Shah over 5 years ago
Sorry, it is 3809a.
#10 Updated by Stanislav Lomany over 5 years ago
- File query-entry-browse.p
added
- File query-entry.p
added
- File query-entry-mult.p
added
Testcases attached. Couple of notes:
- There is no need to implement
CREATE-RESULT-LIST-ENTRY
for non-scrolling queries. - "No record" is a valid entry.
- Additional testcases should be created to check edge conditions like adding entries to the beginning or the end of the list. Also reposition TO ROW and TO ROWID should be checked.
#11 Updated by Stanislav Lomany over 5 years ago
I've committed stubs for CREATE-RESULT-LIST-ENTRY
as rev 11302 in 3809a. It doesn't contain much actual code.
#12 Updated by Stanislav Lomany about 5 years ago
Testcases forWhat aspects of the problem still need testcases? We will have external resources write these.
QUERY:CREATE-RESULT-LIST-ENTRY()
:
- Testcases should be for queries with the single or multiple buffers.
- Testcases should be for all FWD query types:
PreselectQuery
,AdaptiveQuery
,CompoundQuery
etc. (we need to provide rules that will allow to create such testcases). - A new entry should be added into the middle of a result set, as the first entry, as the last entry. Addition of multiple sequential entries should be checked.
- After the item was added, check that first/last/next/prev navigation and reposition to row/rowid/forwards/backwards works.
- Test empty buffer(s) in a result entry for single/multiple-buffer entries.
- Ideally it can be a small testcase harness that can run all related testcases at once.
- We may cut down the number of testcases by not implementing them for non-scrolling queries.
- Testcases should be for permanent and temporary buffers.
- Check that
DELETE-RESULT-LIST-ENTRY
works on the created entries.
BROWSE:CREATE-RESULT-LIST-ENTRY()
:
- Check "standard" way of adding new rows to browse using
insert-row
+create-result-list-entry
. - All interactive testcases should display reproduction sequence in the message area.
- Actually the cases described above for the
QUERY
can be applied to test browse.
#13 Updated by Greg Shah about 5 years ago
Testcases should be for all FWD query types: PreselectQuery, AdaptiveQuery, CompoundQuery etc. (we need to provide rules that will allow to create such testcases).
- PreselectQuery is created from DO/REPEAT PRESELECT
- AdaptiveQuery is FOR EACH
- CompoundQuery is a multiple-buffer query such as FOR EACH buf1 EACH buf2
Is this correct and what other 4GL query types are needed?
A new entry should be added into the middle of a result set, as the first entry, as the last entry. Addition of multiple sequential entries should be checked.
Are there scenarios where the new entry cannot be created? If so we need tests for that.
We also need testcases to show what error conditions or other boundary conditions. For example, what happens if the query is closed? Or what happens when the query handle is unknown/not initialized?
We may cut down the number of testcases by not implementing them for non-scrolling queries.
At a minimum, we need a testcase that proves that non-scrolling queries cannot work with CREATE-RESULT-LIST-ENTRY
.
#14 Updated by Stanislav Lomany about 5 years ago
Addition: 10. We may also want to test EACH, FIRST/LAST/UNIQUE
cases. Really not sure about cases where FIRST/LAST/UNIQUE
is used as the first component.
- PreselectQuery is created from DO/REPEAT PRESELECT
- AdaptiveQuery is FOR EACH
- CompoundQuery is a multiple-buffer query such as FOR EACH buf1 EACH buf2
CREATE-RESULT-LIST-ENTRY
works only with query handle, so DO/REPEAT PRESELECT
is not applicable. I think the list is:
AdaptiveQuery
isFOR EACH
PreselectQuery
isFOR EACH
when there is no matching index.CompoundQuery
isFOR EACH buf1, EACH buf2
PresortQuery
isFOR EACH BREAK BY
PresortCompoundQuery
isFOR EACH buf1, EACH buf2 BREAK BY
wherebuf1
andbuf2
belong to different databases (e.g. temporary and permanent).
Are there scenarios where the new entry cannot be created? If so we need tests for that.
We also need testcases to show what error conditions or other boundary conditions. For example, what happens if the query is closed? Or what happens when the query handle is unknown/not initialized?
The two cases you've described are the only ones that come to my mind. I'm not aware of other cases that fail.
At a minimum, we need a testcase that proves that non-scrolling queries cannot work with
CREATE-RESULT-LIST-ENTRY
.
Non-scrolling queries CAN work with it. I wasn't sure if we need to implement them. But you're right, why not have testcases for them?
So, 11. SCROLLING/non-SCROLLING.
#15 Updated by Marian Edu about 5 years ago
- CREATE-RESULT-LIST-ENTRY
- Static temp-tables - temporary
- Single table in query
- For Each
- Empty temp-tables, build query index, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, build query index, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- Join query between tables, create records out of where clause apply method and navigate
- Primary key join query between tables, create records out of where clause apply method and navigate
- Loaded temp-tables, build query index, create parent/child records, navigate at middle, apply method for several times and navigate
- Preselect Each
- Empty temp-tables, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- For Each
- Multiple tables in query
- For Each
- Empty temp-tables, build query index, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, build query index, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- Join query between tables, create records out of where clause apply method and navigate
- Primary key join query between tables, create records out of where clause apply method and navigate
- Preselect Each
- Empty temp-tables, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- For Each
- Errors and Boundaries
- Closed query
- Empty temp-table
- Invalid handle
- No records in temp-table
- Scrolling query and release temp-table
- No-scrolling and release temp-table
- Apply method for scrolling and non-scrolling query
- Unopen query
- Single table in query
- Tables from database – permanent
- Single table in query
- For Each
- Empty temp-tables, build query index, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, build query index, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- Preselect Each
- Empty temp-tables, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- For Each
- Multiple tables in query
- For Each
- Empty temp-tables, build query index, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, build query index, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- Preselect Each
- Empty temp-tables, create parent/child records ( all combinations ), apply method and navigate
- Empty temp-tables, no build query index, create parent/child records ( all combinations ), apply method and navigate
- Loaded temp-tables, create parent/child records, navigate at first(last, middle, beginning), apply method and navigate
- For Each
- Single table in query
- DELETE-RESULT-LIST-ENTRY
- Static temp-tables - temporary
- Single table in query
- Test link between temp-table and query index by call method after execute find on temp-table
- Method behavior for table with deleted records after building query index
- Behavior after build query index, delete elements from table, navigate on index of deleted elements and apply method
- Behavior for released table
- Behavior for build query index, apply reposition without next/previous and apply method
- Multiple tables in query
- Update record in child table and test behavior of using / not using delete-result-list-entry
- Single table in query
- for / preselect – type of open query
- empty / load – temp-table or db-table has not / has records before build query index
- list / no_list – build/no_build query index
- na_na / ok_na / na_ok / ok_ok – table parent or child have/have not record after query index is build
- result – apply method – create or delete depending of folder
- first/last/prev/next – navigation on query before of after apply method
#16 Updated by Stanislav Lomany almost 5 years ago
At this point FWD has limited implementation of CREATE-RESULT-LIST-ENTRY
: it is only implemented for AdaptiveQuery
and implementation is not completed (TODO left and it looks like the code hasn't been tested thoroughly).
#17 Updated by Stanislav Lomany almost 5 years ago
I've noticed an issue that is not related to this task. Testcase:
define temp-table tt field f1 as integer. def var h as handle. h = buffer tt:handle. delete object h no-error. <-- exception here
Exception:
Caused by: java.lang.RuntimeException: Error creating static proxy for interface com.goldencode.p2j.util.CommonSession: static method boolean isType(java.lang.String) was not found in the given classes. at com.goldencode.proxy.StaticProxy.init(StaticProxy.java:346) at com.goldencode.proxy.StaticProxy.<init>(StaticProxy.java:223) at com.goldencode.proxy.StaticProxy.obtain(StaticProxy.java:200) at com.goldencode.p2j.util.SessionUtils.asHandle(SessionUtils.java:202) at com.goldencode.p2j.util.HandleOps.isSystemHandle(HandleOps.java:250) at com.goldencode.p2j.util.HandleOps.delete(HandleOps.java:321)
This error appears after rev 11325:
revno: 11325 [merge] Adds many runtime/conversion improvements and fixes to the DATA-SET support in FWD: - OM: many changes related to DATA-SEt (conversion and runtime). This includes BEFORE/AFTER-TABLE/BUFFER/ROWID, COPY-DATASET, JSON/XML/XMLSCHEMA serialization, MERGE-CHANGES, ORIGIN-ROWID and many more. Refs #3809 - AVK: #4078 issue with Hotel demo login in Swing mode - HC: adds JSON support via runtime implementation of legacy (previously skeleton) classes. Refs #3751
#18 Updated by Greg Shah almost 5 years ago
I think this is already fixed in 4124a, please check your testcase in that branch.
#19 Updated by Stanislav Lomany almost 5 years ago
I think this is already fixed in 4124a, please check your testcase in that branch.
Yes, it is fixed.
#20 Updated by Stanislav Lomany almost 5 years ago
I want to clarify if we need to implement CREATE-RESULT-LIST-ENTRY
for non-scrolling queries? Do you see any practical use in it? If not, we can postpone it until we meet a real case where it is used. That'll save us a lot of time.
#21 Updated by Stanislav Lomany almost 5 years ago
As far as I get buffer::extent-field = variable
is not supported at runtime. Correct me if I'm wrong.
#22 Updated by Stanislav Lomany almost 5 years ago
- File crle-compound3-find-where.p
added
Greg, when CREATE-RESULT-LIST-ENTRY
inserts the last entry in the result set and we continue to iterate the query, things become messy in 4GL. It continues to walk by index which produces a kind of mixed results. Specifically, if we have record X Y Z
inserted after the record A B C
then the A B C
will be "snapshot" records which drive the order, but X
and Y
will remain in buffers until they're gone by iteration. An example (A+1
notation means "the next record after A"):
A B C X Y Z X Y C+1 .......... X B+1 .. .......... A+1 .. ..
4GL in this case can produce records that do NOT match
WHERE
condition of the query. But, as well, in some cases, WHERE
condition is properly applied.Testcase is attached, sample output:
1 1 2 1 1 3 1 1 4 1 2 1 1 2 2 3 3 4 <-- inserted entry 3 3 3 <-- doesn't match WHERE condition 3 3 4 3 3 1 3 3 2 <--- why "3 3 3" is missing if we can see it above? 3 3 4 3 4 1 3 4 2 3 4 3 3 4 4 ------ end of disturbance caused by the insertion, ------ entries from "1 2 3" to "1 4 4" are missing 2 1 1 2 1 2 2 1 3 2 1 4 .....
The point is that if user inserts an entry during query iteration, results can be unexpected.
I'm not 100% sure, I'll check it tomorrow again, but I haven't seen this kind of behavior when CREATE-RESULT-LIST-ENTRY
is used by a browse, which is interesting.
#23 Updated by Stanislav Lomany almost 5 years ago
- If a query is bound to the browse then
CREATE-RESULT-LIST-ENTRY
cannot be used without creating a new row in the browse: "Selected row must be new row when using CREATE-RESULT-LIST-ENTRY for QUERY widget. (9483)" error occurs in this case. - In the previous note I noted that 4GL has messy behavior when a query is iterated after the last entry has been created by
CREATE-RESULT-LIST-ENTRY
. In browse I haven't seen this behavior. Why? 4GL uses a trick. If a new row is the last row in the view, then right afterROW-ENTRY
event is called for this row, 4GL fetches an extra entry for the backing query. Which means thatCREATE-RESULT-LIST-ENTRY
will create non-last entry and messy behavior doesn't occur.
#24 Updated by Stanislav Lomany almost 5 years ago
- File simple-compound.p
added
I've attached a simple testcase that shows that after a record has been added during iteration of a compound query, compound query results can be unexpected. That influences my work only indirectly: I have to check if a bug was added by me or if it is an existing bug.
1 1 1 2 1 3 2 1 2 2 2 3 2 7 3 1 <-- missing in FWD 3 2 <-- missing in FWD 3 3 3 7 5 1 <-- missing in FWD 5 2 <-- missing in FWD 5 3 5 7
#25 Updated by Stanislav Lomany almost 5 years ago
Rebased task branch 3816a from P2J trunk revision 11328.
#26 Updated by Stanislav Lomany almost 5 years ago
- File all-tests.ods added
CREATE-RESULT-LIST-ENTRY
testcases. So we have:
- Fix few issues for adaptive queries.
- Looks like there are two types of compound query errors (not sure what lies beyond these errors).
CREATE-RESULT-LIST-ENTRY
should be implemented for preselect queries.
#27 Updated by Greg Shah almost 5 years ago
In which branch are your changes?
I assume you are implementing the DELETE-RESULT-LIST-ENTRY
as well? It is used in the testcases.
#28 Updated by Stanislav Lomany almost 5 years ago
In which branch are your changes?
3816a
I assume you are implementing the
DELETE-RESULT-LIST-ENTRY
as well? It is used in the testcases.
Now I assume so too.
#29 Updated by Stanislav Lomany almost 5 years ago
Greg, P2JQuery.first/next/previous/last
function are all declared with @throws QueryOffEndException
. Is that valid? GET NEXT/PREV/FIRST/LAST
statements which are converted to these function do not raise error:
If you execute a GET NEXT statement after the last record of the query has been fetched or you execute a GET PREV statement after the first record of the query has been fetched, the ERROR condition is not raised.
Fortunately, internals of these functions do not actually throw
QueryOffEndException
, so everything is OK. But I found the case which I need to fix and which throws QueryOffEndException
. So the question is: should I remove @throws QueryOffEndException
and handle QueryOffEndException
internally for the case I need to fix?#30 Updated by Eric Faulhaber almost 5 years ago
QueryOffEndException
is thrown by some implementations of these methods, not all. It is needed by the BlockManager
to terminate loop processing in some cases, for example. This is why it is annotated with @throws
in the P2JQuery
javadoc. As long as a single case exists that needs it, we should leave the annotation in place, I think.
If you change a particular concrete implementation which currently throws it under some conditions, such that it can no longer be thrown from that implementation, I guess you can remove it from that particular implementation's comments. I'm not sure if javadoc will complain about that.
In any case, this is an unchecked exception, and there is no requirement to catch it based on a javadoc annotation. So, what are you aiming to correct?
#31 Updated by Stanislav Lomany almost 5 years ago
In any case, this is an unchecked exception, and there is no requirement to catch it based on a javadoc annotation. So, what are you aiming to correct?
Here is a testcase which demonstrates the problem:
def temp-table tt field f1 as integer index idx1 f1. create tt. tt.f1 = 2. def var i as integer. def query q for tt scrolling. open query q for each tt. query q:get-first(). message query q:NUM-RESULTS. find first tt. delete tt. query q:get-last(). // QueryOffEndException stops the testcase message query q:NUM-RESULTS.
And here is the stack. I'm not sure at what point it goes wrong. So far I suspect DynamicResults
.
setRecord:8827, RecordBuffer (com.goldencode.p2j.persist) <- raises QueryOffEndException updateBuffer:3278, RandomAccessQuery (com.goldencode.p2j.persist) last:1629, RandomAccessQuery (com.goldencode.p2j.persist) last:1511, RandomAccessQuery (com.goldencode.p2j.persist) last:4085, AdaptiveQuery$DynamicResults (com.goldencode.p2j.persist) last:144, ResultsAdapter (com.goldencode.p2j.persist) last:2402, PreselectQuery (com.goldencode.p2j.persist) last:1698, AdaptiveQuery (com.goldencode.p2j.persist) last:2369, PreselectQuery (com.goldencode.p2j.persist) getLast:2244, AbstractQuery (com.goldencode.p2j.persist) getLast:4826, QueryWrapper (com.goldencode.p2j.persist) lambda$execute$0:32, Switch1d (com.goldencode.testcases)
#32 Updated by Eric Faulhaber almost 5 years ago
When we assign the PreselectQuery
(AdaptiveQuery
) delegate to the QueryWrapper
, we probably need to call delegate.setLenientOffEnd(true)
. I guess this is true for all PreselectQuery
delegates, unless we use QueryWrapper
for some other case I can't remember right now.
#33 Updated by Stanislav Lomany almost 5 years ago
In this case lenientOffEnd
is already set in PreselectQuery.open
. But I have another idea. lenientOffEnd
doc says than
If set to lenient mode, invocations ofnext
andprevious
which do not find a record do not raise a QueryOffEndException.
We don't invoke next
/prev
, we invoke first
/last
which go off-end because the result set is empty. Does this case in your opinion fit in the cases which lenient off-end should handle? If yes, then I should add conditional re-throw of QueryOffEndException
in PreselectQuery.first
/last
.
#34 Updated by Eric Faulhaber almost 5 years ago
Well, the fact that I differentiated the off-end behavior between first/last and next/previous tells me I needed it work this way to handle a specific case, though I can't remember what that might be now. I developed PreselectQuery
and AdaptiveQuery
originally to handle the basic REPEAT PRESELECT and FOR EACH semantics, respectively. The requirements of OPEN QUERY (which introduced QueryWrapper
) came later. So, the lenientOffEnd
behavior probably was biased toward the former contructs' semantics.
I'm thinking we don't want to change the core PreselectQuery
behavior, but maybe we honor it for QueryWrapper.first|last
by catching the QOEE and checking the PreselectQuery
delegate's lenientOffEnd
flag. If true
, we eat the QOEE, otherwise we rethrow it. That should cover the GET FIRST|LAST cases needing not to raise the exception, while preserving the original behavior for the core query implementations.
We really should have a test case to verify the need for the QOEE on PreselectQuery|AdaptiveQuery.first|last
. You'll need to look into the TRPL which emits these to determine what 4GL constructs result in those methods being used.
#35 Updated by Stanislav Lomany almost 5 years ago
Guys, this abend
Caused by: java.lang.NullPointerException: Table must be non-null at com.goldencode.p2j.persist.RecordIdentifier.<init>(RecordIdentifier.java:103) at com.goldencode.p2j.persist.dirty.DefaultDirtyShareManager.lockSingle(DefaultDirtyShareManager.java:1706) at com.goldencode.p2j.persist.dirty.DefaultDirtyShareManager.getDirtyInfo(DefaultDirtyShareManager.java:1351) at com.goldencode.p2j.persist.dirty.DefaultDirtyShareContext.getDirtyInfo(DefaultDirtyShareContext.java:1123) at com.goldencode.p2j.persist.RandomAccessQuery.executeImpl(RandomAccessQuery.java:4340) at com.goldencode.p2j.persist.RandomAccessQuery.execute(RandomAccessQuery.java:3415) at com.goldencode.p2j.persist.RandomAccessQuery.findNext(RandomAccessQuery.java:3803) at com.goldencode.p2j.persist.RandomAccessQuery.next(RandomAccessQuery.java:1818) at com.goldencode.p2j.persist.RandomAccessQuery.next(RandomAccessQuery.java:1697) at com.goldencode.p2j.persist.AdaptiveQuery$DynamicResults.next(AdaptiveQuery.java:4097) at com.goldencode.p2j.persist.ResultsAdapter.next(ResultsAdapter.java:159) at com.goldencode.p2j.persist.PreselectQuery.peekNext(PreselectQuery.java:3449) at com.goldencode.p2j.persist.AdaptiveQuery.peekNext(AdaptiveQuery.java:2116) at com.goldencode.p2j.persist.CompoundQuery.processComponent(CompoundQuery.java:2928) at com.goldencode.p2j.persist.CompoundQuery.retrieveImpl(CompoundQuery.java:2558) at com.goldencode.p2j.persist.CompoundQuery.retrieve(CompoundQuery.java:1976) at com.goldencode.p2j.persist.CompoundQuery.peekNext(CompoundQuery.java:1327) at com.goldencode.p2j.persist.Cursor.reposition(Cursor.java:348) at com.goldencode.p2j.persist.Cursor.repositionByID(Cursor.java:292) at com.goldencode.p2j.persist.DynamicQuery.repositionByID(DynamicQuery.java:221) at com.goldencode.p2j.persist.CompoundQuery.repositionByID(CompoundQuery.java:353) at com.goldencode.p2j.persist.QueryWrapper.repositionByID(QueryWrapper.java:2806) at com.goldencode.p2j.persist.QueryWrapper.queryRepositionByID(QueryWrapper.java:3597) at com.goldencode.tests.query.db.methods.create_result_list_entry.multiple.ForLoadListBeginingOkOkResult.lambda$null$40(ForLoadListBeginingOkOkResult.java:154)
happens inside this call:
// check the dirty share manager for an overriding result // TODO: checking the number of referenced buffers is a temporary workaround; // a query with server-side joins will not return the right information from the // dirty database and may cause a fatal error, if the joined table does not yet // exist in the dirty database; however, this is not a correct solution! if (info == null && getReferencedBuffers().length == 1) { info = dirtyContext.getDirtyInfo(buffer, index, activeBundleKey, activeBundle, allArgs, allTypes, dmo, hqlPreproc.isFindByRowid()); }
What kind of tactics should be applied here?
#36 Updated by Eric Faulhaber almost 5 years ago
Is this the first exception? Because this
Caused by: java.lang.NullPointerException: Table must be non-null at com.goldencode.p2j.persist.RecordIdentifier.<init>(RecordIdentifier.java:103) at com.goldencode.p2j.persist.dirty.DefaultDirtyShareManager.lockSingle(DefaultDirtyShareManager.java:1706) at com.goldencode.p2j.persist.dirty.DefaultDirtyShareManager.getDirtyInfo(DefaultDirtyShareManager.java:1351) ...
...is happening when we are trying to unlock an index. I would have expected this to fail earlier, when we are trying to acquire the lock, at DefaultDirtyShareManager
:1242.
Anyway, this stack trace tells me that index we are passing into the DefaultDirtyShareContext.getDirtyInfo
call is null
. This indicates we could not match the sort clause used for the RandomAccessQuery
. This happens in the RAQ.initialize
method:
// Get index name, which is needed for dirty checking work. try { IndexHelper indexHelper = buffer.getIndexHelper(); this.index = indexHelper.getIndexForSort(buffer, sort); this.dmoSorter = indexHelper.getSorterForSortPhrase(buffer, sort); } catch (PersistenceException exc) { if (LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, "Error locating index for sort phrase [" + sort + "]", exc); } }
Do you see that, "Error locating index for sort phrase..." error in the log?
What does the business logic for the CompoundQuery
setup look like (i.e., from ForLoadListBeginingOkOkResult
)?
#37 Updated by Stanislav Lomany almost 5 years ago
Do you see that, "Error locating index for sort phrase..." error in the log?
No, index
field just gets null
value here: this.index = indexHelper.getIndexForSort(buffer, sort);
I suppose we should raise Error locating index for sort phrase...
in this case too.
So, the permanent H2 database got queried for the index with no result. Are indexes supposed to be carried from .df
into H2 database?
#38 Updated by Stanislav Lomany almost 5 years ago
Do you think thatI'm thinking we don't want to change the core
PreselectQuery
behavior, but maybe we honor it forQueryWrapper.first|last
by catching the QOEE and checking thePreselectQuery
delegate'slenientOffEnd
flag. Iftrue
, we eat the QOEE, otherwise we rethrow it.
QueryWrapper.first|last
should throw QOEE? It is used in:
get first|last
get-first|last
- reposition
- browse logic
Browse is aware of this specificity of first|last
, in other cases throw of QOEE looks like a bug.
#39 Updated by Eric Faulhaber almost 5 years ago
Stanislav Lomany wrote:
Do you think thatI'm thinking we don't want to change the core
PreselectQuery
behavior, but maybe we honor it forQueryWrapper.first|last
by catching the QOEE and checking thePreselectQuery
delegate'slenientOffEnd
flag. Iftrue
, we eat the QOEE, otherwise we rethrow it.QueryWrapper.first|last
should throw QOEE? It is used in:
get first|last
get-first|last
- reposition
- browse logic
Browse is aware of this specificity of
first|last
, in other cases throw of QOEE looks like a bug.
If you have found through your testing that throwing QOEE appears to be a bug in these cases, then it probably is. We can eat it at the QueryWrapper
level if you can find no OPEN QUERY case where it should be thrown.
#40 Updated by Eric Faulhaber almost 5 years ago
Stanislav Lomany wrote:
Do you see that, "Error locating index for sort phrase..." error in the log?
No,
index
field just getsnull
value here:this.index = indexHelper.getIndexForSort(buffer, sort);
I suppose we should raiseError locating index for sort phrase...
in this case too.
Probably, though I suspect this error is due to an improper environment (indices were not migrated to the database).
So, the permanent H2 database got queried for the index with no result. Are indexes supposed to be carried from
.df
into H2 database?
Indices are normally created during data import. If you ran conversion and then just used the table DDL to create an H2 database for testing, but never imported anything into it, then it has no indices. This is not a "normal" application migration scenario, but you can create the indices separately by running the generated index DDL on your test database. They are absolutely necessary for converted code to operate correctly, not just for performance.
#41 Updated by Stanislav Lomany almost 5 years ago
Guys, here is a simple testcase:
def temp-table tt field f1 as integer index idx1 f1. create tt. tt.f1 = 1. open query q preselect each tt. message avail(tt).
In FWD the record is available, in 4GL it is not.
Should I fix it by releasing backing buffers on open of a QueryWrapped-
preselect query?
#42 Updated by Eric Faulhaber almost 5 years ago
Yes.
#43 Updated by Stanislav Lomany almost 5 years ago
FYI, I made harness which sequentially runs CRLE tests. I had to split the set of tests in half, otherwise this error occurs:
Caused by: java.lang.RuntimeException: Unexpected code path at org.h2.message.DbException.throwInternalError(DbException.java:254) at org.h2.message.DbException.throwInternalError(DbException.java:267) at org.h2.engine.Session.unlockAll(Session.java:985) at org.h2.engine.Session.endTransaction(Session.java:760) at org.h2.engine.Session.commit(Session.java:708) at org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:46) at org.h2.command.CommandContainer.update(CommandContainer.java:102) at org.h2.command.Command.executeUpdate(Command.java:261) at org.h2.jdbc.JdbcConnection.commit(JdbcConnection.java:497)
#44 Updated by Eric Faulhaber almost 5 years ago
We've seen this before with H2. Don't know what it is, but in every case we've hit this so far, doing the same thing with PostgreSQL does not cause a problem. If it's important to avoid this, I would recommend switching over to PostgreSQL. Otherwise, go with your approach, as long as it meets your needs.
#45 Updated by Stanislav Lomany almost 5 years ago
Guys, in the following sequence
open query q preselect each tt. create tt. tt.f1 = 1. query q:create-result-list-entry. get first q.
first
fails to load the recently created record into the buffer. PreselectQuery.coreFetch -> Persistence.load
tries to load the record into the buffer which already contains the target record. It fails because Session.get
returns null
. Any ideas?
This sequence works:
... release tt. get first q.
#46 Updated by Eric Faulhaber almost 5 years ago
Stanislav Lomany wrote:
Guys, in the following sequence
[...]
first
fails to load the recently created record into the buffer.PreselectQuery.coreFetch -> Persistence.load
tries to load the record into the buffer which already contains the target record. It fails becauseSession.get
returnsnull
. Any ideas?
I suspect we are not flushing the newly created record to the database properly in this sequence, whereas the release forces a flush.
This sequence works:
[...]
Is this blocking you? Can you use the latter sequence for your testing and open a new bug for the failing one?
#47 Updated by Stanislav Lomany almost 5 years ago
Is this blocking you? Can you use the latter sequence for your testing and open a new bug for the failing one?
OK, I'll modify failing testcase(s) so they don't fail and open a new bug.
BTW AdaptiveQuery
fails on this part too, it just has an extra way to re-find record.
#48 Updated by Stanislav Lomany almost 5 years ago
- Related to Bug #4325: Not flushing the newly created record to the database added
#49 Updated by Stanislav Lomany almost 5 years ago
Caused by: java.lang.RuntimeException: Unexpected code path
I got rid of this by setting MVCC=false
.
#50 Updated by Stanislav Lomany almost 5 years ago
INSERT-ROW
:
- If a button trigger executes
INSERT-ROW
, then focus is changed to the target browse. Even the following trigger sets the focus to the browse:on choose of btn DO: browse br:INSERT-ROW("After"). apply "entry" to other-widget. END.
- If a trigger is fired from a fill-n, then focus is not changed, but browse draws the in-row fill-in, so we have an in-row fill-in while the browse is not focused.
- Haven't checked the other types of widgets yet.
I think that the item 1 should be fixed because it is typical to have an "Add record" button. Do you agree?
#51 Updated by Greg Shah almost 5 years ago
I think that the item 1 should be fixed because it is typical to have an "Add record" button. Do you agree?
Yes. Is issue 1 explaining how it should work in the 4GL?
Can you explain issue 2 a bit more?
#52 Updated by Stanislav Lomany almost 5 years ago
- File edit-nofocus.png added
Yes. Is issue 1 explaining how it should work in the 4GL?
Yes.
Can you explain issue 2 a bit more?
Here is a screenshot of the result of this trigger which has been fired while the lower fill-in was focused:
ON i anywhere DO: browse br:INSERT-ROW("After"). END.
We have an in-row fill-in which is drawn, but not focused.
#53 Updated by Greg Shah almost 5 years ago
Is issue 2 really just the same problem as issue 1 ("we must set focus to the browse on INSERT-ROW
")?
#54 Updated by Stanislav Lomany almost 5 years ago
Issue 1 (button) is about delayed focus change.
Issue 2 (fill-in) is about maintaining an in-row fill-in when browse is not focused.
#55 Updated by Greg Shah almost 5 years ago
Can you fix issue 2 quickly?
#56 Updated by Stanislav Lomany almost 5 years ago
Can you fix issue 2 quickly?
It looks like the mechanics is the following: focus is temporary changed to the in-row editor and it fires ENTRY event. Then the focus is silently returned to the original widget without popping any ENTRY or LEAVE events. Also it is required to check other types of widgets and events which fire the trigger. So I don't think I can do it quickly.
#57 Updated by Stanislav Lomany almost 5 years ago
Rebased task branch 3816a from P2J trunk revision 11333.
#58 Updated by Stanislav Lomany over 4 years ago
- Status changed from New to WIP
Rebased task branch 3816a from P2J trunk revision 11334.
Please review it.
#59 Updated by Greg Shah over 4 years ago
Is there anything left open on this task?
#60 Updated by Ovidiu Maxiniuc over 4 years ago
I have just reviewed the 11342 revision of branch 3816a. I found nothing wrong with it.
#61 Updated by Stanislav Lomany over 4 years ago
Is there anything left open on this task?
I'm working on the issues with CRLE when the created row is out of view.
Other than that there's nothing left. Some issues were intentionally ignored/postponed:- Implementation for CRLE/DRLE for non-scrolling queries - needs much effort to implement and is not practically used.
- CRLE for the last entry in the result list - 4GL behavior is messy.
- Browse mode when INSERT-ROW creates an in-row fill-in which is active even when the browse is not focused. Done by a trigger with INSERT-ROW if the current widget is not a button.
#62 Updated by Greg Shah over 4 years ago
Create tasks for the 3 issues, link them here and make me a watcher.
Can you finish today?
#63 Updated by Stanislav Lomany over 4 years ago
Can you finish today?
I'm not sure, I'll try.
#64 Updated by Stanislav Lomany over 4 years ago
Rebased task branch 3816a from P2J trunk revision 11335.
I've committed the fix for the CRLE "out of view" issue, so I'm done with this task.
Other than that, I noted although we recently had changes in row entry/leave events, there are (old or new?) unwanted entry events and duplicate entry events in FWD. I couldn't fix it quickly because it requires more solid approach.
#65 Updated by Greg Shah over 4 years ago
Did you update the gap marking rules to match your changes? I assume that CRLE, DRLE and INSERT-ROW are now considered fully supported at conversion and "full restricted" runtime. Please make a note about the restrictions and point to the task number (of the task you are going to add to list the remaining items).
We could list it as partial, but my understanding is that the remaining items are not core. Is that correct?
#66 Updated by Stanislav Lomany over 4 years ago
We could list it as partial, but my understanding is that the remaining items are not core. Is that correct?
Yes. I'll shortly mark them as you suggested.
#67 Updated by Greg Shah over 4 years ago
Is see the primary functional change is in Browse.insertRow()
. How much testing have you done on this? I guess it would not get hit in ChUI regression testing (it has no updatable browses, I think). Have you tried it in one of the large GUI apps which have updatable browse?
Are there changes in query/persistence/browse that can be hit by ChUI regression testing?
#68 Updated by Stanislav Lomany over 4 years ago
Have you tried it in one of the large GUI apps which have updatable browse?
I'll test tomorrow and let you know the results.
Are there changes in query/persistence/browse that can be hit by ChUI regression testing?
Yes, query changes related to cursor need good review and regression testing.
#69 Updated by Stanislav Lomany over 4 years ago
The remaining issues were moved to #4341.
#70 Updated by Stanislav Lomany over 4 years ago
- Related to Feature #4341: CREATE-RESULT-LIST-ENTRY missing implementation features added
#71 Updated by Greg Shah over 4 years ago
Yes, query changes related to cursor need good review and regression testing.
OK, please get ChUI regression testing done.
#72 Updated by Constantin Asofiei over 4 years ago
Stanislav, a quick note about the SharedVariableManager.lookupTempTable(String legacyName)
. Please make sure the legacy name is really the legacy name, with case-sensitivity preserved.
OTOH, the query changes I think they do need ETF testing... I'll work on this; I'm starting conversion, but before running the tests, please fix any MAJIC regressions you find (and let me know if you find any).
#73 Updated by Stanislav Lomany over 4 years ago
What are the know failing regression tests except tc_job_002?
#74 Updated by Constantin Asofiei over 4 years ago
Stanislav Lomany wrote:
What are the know failing regression tests except tc_job_002?
The 'clock violation approval' tests (and some employee reports), which are dependent on the time of day the testing is done.
#75 Updated by Stanislav Lomany over 4 years ago
Then we have two failing tests. I'm looking into it.
#76 Updated by Stanislav Lomany over 4 years ago
Then we have two failing tests. I'm looking into it.
Never mind. Regression testing passed. I just got two identical runs, the third one is good.
#77 Updated by Stanislav Lomany over 4 years ago
Stanislav, a quick note about the SharedVariableManager.lookupTempTable(String legacyName). Please make sure the legacy name is really the legacy name, with case-sensitivity preserved.
Search shouldn't be case-sensitive. E.g. it is used by ADD-FIELDS-FROM which is not case-sensitive.
#78 Updated by Constantin Asofiei over 4 years ago
Stanislav Lomany wrote:
Stanislav, a quick note about the SharedVariableManager.lookupTempTable(String legacyName). Please make sure the legacy name is really the legacy name, with case-sensitivity preserved.
Search shouldn't be case-sensitive. E.g. it is used by ADD-FIELDS-FROM which is not case-sensitive.
I understand that, what I meant is this: if the legacy name is w-t1
, and a call is done via W-t1
, this will resolve the same table, right?
#79 Updated by Greg Shah over 4 years ago
Constantin: Are we OK to merge to trunk?
We are from my perspective.
#80 Updated by Constantin Asofiei over 4 years ago
Yes, go ahead and merge.
#81 Updated by Stanislav Lomany over 4 years ago
Rebased task branch 3816a from P2J trunk revision 11336.
#82 Updated by Stanislav Lomany over 4 years ago
- Status changed from WIP to Review
3816a has been merged into the trunk as bzr revision 11337.
#84 Updated by Greg Shah over 4 years ago
- Assignee set to Stanislav Lomany
- Status changed from Review to Closed
- % Done changed from 0 to 100