Project

General

Profile

Bug #9034

FindQuery unique fails in a self join context

Added by Artur Școlnic almost 2 years ago. Updated over 1 year ago.

Status:
Test
Priority:
Normal
Target version:
-
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
reviewer:
production:
No
env_name:
topics:

History

#2 Updated by Artur Școlnic almost 2 years ago

This ticket is derived from #8912-188.

#3 Updated by Artur Școlnic almost 2 years ago

define temp-table tt no-undo
    field f1 as character 
    index idx is primary unique f1.

create tt.
assign 
tt.f1 = ?.

create tt.
assign 
tt.f1 = ?.

define buffer btt for tt.
for each tt on error undo, throw:
    find btt where btt.f1 = tt.f1 no-error.
    if ambiguous btt then do:
        message "ambiguous".
    end.
end.
message "finished".

In 4GL the program above outputs ambiguous 2 times and then finished.
In FWD, only finished is displayed.

If instead of the find btt where btt.f1 = tt.f1, we use find btt of tt, there is also a conversion issue. Instead of the field f1, the recid is used in the where clause of the find query.
First I will investigate the runtime issue.

#4 Updated by Artur Școlnic almost 2 years ago

In this case, DirectAccessHelper.findByUniqueIndex() is used, it assumes that if there is a unique index, only one record can be accessed with the same value for the indexed field.
getUniqueRow is used and the response is returned, I added a simple check to see if there are more results after the first record is accessed

if( driver.nextPrimaryKey(tableName, response.getRecid().intValue(), true) != 0){
   throw new DirectAccessException("Error direct accessing for finding record by unique index. More than one records found.");
}

The test case in #9034-3 matches the behavior in 4GL with this change.

#5 Updated by Artur Școlnic almost 2 years ago

  • Status changed from WIP to Review

I committed a better version of the change from #9034-4 to 9034a, I did some initial testing and it looks ok.
The conversion fix just omits the transforming of the of clause for non meta tables, I committed it to 9034b. For testing, I converted some test cases, the conversion went fine.
Both task branches are ready for review.

#6 Updated by Artur Școlnic almost 2 years ago

Using 9034b this query

define buffer btt for tt.
...
    find btt of tt no-error.

is converted as
silent(() -> new FindQuery(btt, (String) null, null, "btt.f1 asc", tt).unique());

#7 Updated by Eric Faulhaber almost 2 years ago

Alexandru, please review 9034a/15373. The only issue I see is a minor coding standard format issue, but you are more familiar with the H2 direct access interface.

The minor format issue:

if( response.getRecid() ...

should be:

if (response.getRecid() ...

#8 Updated by Eric Faulhaber almost 2 years ago

Code review 9034b/15373:

The conversion change looks good.

#9 Updated by Alexandru Lungu almost 2 years ago

  • % Done changed from 0 to 80
  • Status changed from Review to WIP

Review of 9034a:

I understand the problem; the direct-access presumed that a unique index look-up would find one single record. Apparently, it may found more due to the fact that one field may be unknown.

  • First of all, it doesn't compile. nextPrimaryKey does not exist. The only signature available in FWD-H2 is:
    public long nextPrimaryKey(String tableName, int multiplex) 
  • Even if it would match, it is not clear to me the intent: nextPrimaryKey is retrieving the next PK available to that table and reserves it. It is like doing a NEXT VALUE on a sequence and is usually prior to INSERT statements.
  • Also, even if we would detect this case, I think the implementation should go in direct-access layer instead of fall-backing to the SQL one. I want to purely drop the index look-up spent time and start all over again due to the exception. Lets improve the direct-access layer to cover this case

Please check-out FWD-H2 (code/p2j_repo/fwd-h2/trunk) and attempt to change FWDDirectAccessDriver to provide this hint back to DirectAccessHelper (maybe add in response an "ambiguous" flag for your case). In that case, you shall use something like Persistence.uniqueResultViolation and, in essence, behave like RandomAccessQuery when finding more "unique" records. Use H2_Database_Fork for more details on FWD-H2 development.

#10 Updated by Artur Școlnic almost 2 years ago

  • Status changed from WIP to Review

I committed 9034a/15373 and 9034a_h2/51, added support for identifying ambiguous unique find.

#11 Updated by Eric Faulhaber almost 2 years ago

Alexandru, please review.

#12 Updated by Alexandru Lungu almost 2 years ago

  • % Done changed from 80 to 100
Review of 9034a:
  • I am a bit confused with the state of this branch. I already reviewed 9034a/15373 in #9034-9. Maybe you missed committing the changes as 9034a/ 15374?
Review of 9034a_h2:
  • The changes are functionally good.
  • Please fix the formatting. Even if there are no explicit formatting rules for the FWD-H2 code, please attempt to keep an homogeneous formatting. Specially, the FWD extensions should respect the FWD formatting standards, whereas the rest of FWD-H2 should simply look the same.
    • The opening brace of getAmbiguous() should be on a new line.
    • Add return and param tags for the javadoc of the setters/getters
    • Keep the javadoc of ambigous on a single line

#13 Updated by Artur Școlnic almost 2 years ago

Alexandru Lungu wrote:

  • I am a bit confused with the state of this branch. I already reviewed 9034a/15373 in #9034-9. Maybe you missed committing the changes as 9034a/ 15374?

Sorry for that, I indeed forgot to commit, 9034a/15374 is now committed.

#14 Updated by Alexandru Lungu over 1 year ago

  • Status changed from Review to WIP
  • % Done changed from 100 to 90
Review of 9034a:
  • remove oo imports from RAQ
  • add history entry for DirectAccessHelper
  • remove changes from ErrorManager (empty line)

Please commit required changes to 9034a_h2 according to #9034-12.

#15 Updated by Alexandru Lungu over 1 year ago

Review of 9034a:

These were change local on my side, ignore review.

#16 Updated by Artur Școlnic over 1 year ago

Alexandru, during testing of 9134a_h2, I encountered some issue with the next method in TreeCursor:

 if (beforeFirst) {
    beforeFirst = false;
    if (node == null) {
       return false;
    }

I think this conditional needs to be refactored to:
if (node == null) {
    return false;
    }
    if (beforeFirst) {
       beforeFirst = false;

considering that I added an extra cursor.next() in FWDDirectAccessDriver.retrieve(). For the second next, beforeFirst will be false and the null checking will not be performed.

#17 Updated by Alexandru Lungu over 1 year ago

This is how the code looked before any FWD-H2 specific changes:

            |     @Override
            |     public boolean next() {
            |         if (beforeFirst) {
            |             beforeFirst = false;
            |             if (node == null) {
            |                 return false;
            |             }
            |             if (first != null && tree.compareRows(node.row, first) < 0) {
            |                 node = next(node);
            |             }
            |         } else {
            |             node = next(node);
            |         }
            |         if (node != null && last != null) {
            |             if (tree.compareRows(node.row, last) > 0) {
            |                 node = null;
            |             }
            |         }
            |         return node != null;
            |     }

You are suggesting changing the code H2, which doesn't seem right. I think the problem is node.active false without a null-check. It should be rewritten as node != null && node.active false.

#18 Updated by Artur Școlnic over 1 year ago

I committed 9034a_h2/53, it addressed the review points from #9034-12 and the issue discussed in #9034-17.

deleted

#19 Updated by Alexandru Lungu over 1 year ago

  • % Done changed from 90 to 100
  • Status changed from WIP to Internal Test

I am OK with the changes in 9034a_h2. Please go ahead and merge to the FWD_H2 trunk. From my understanding, 9034a should reach FWD trunk after the H2 is upgraded. We will honor that.

Please let me know if more testing is required.

#20 Updated by Artur Școlnic over 1 year ago

I am ready to merge 9034a_h2.

#21 Updated by Alexandru Lungu over 1 year ago

Please go ahead and merge 9034a_h2 to FWD-H2 trunk.

#22 Updated by Artur Școlnic over 1 year ago

9034a_h2 was merged to FWD-H2 trunk as rev 54.

#23 Updated by Alexandru Lungu over 1 year ago

  • Status changed from Internal Test to Merge Pending

Please merge 9034a after 9263a to trunk.

#24 Updated by Artur Școlnic over 1 year ago

  • Status changed from Merge Pending to Test

9034a was merged to trunk as rev 15593.

Also available in: Atom PDF