Project

General

Profile

Bug #9397

Fix COPY-TEMP-TABLE issues

Added by Ioana-Cristina Prioteasa over 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Ioana-Cristina Prioteasa
Target version:
-
Start date:
Due date:
% Done:

100%

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

err1.png (7.82 KB) Ioana-Cristina Prioteasa, 11/29/2024 06:01 AM

err2.png (7.24 KB) Ioana-Cristina Prioteasa, 11/29/2024 06:01 AM

err3.png (7.56 KB) Ioana-Cristina Prioteasa, 11/29/2024 06:01 AM

fwd_copy.png (8.14 KB) Ioana-Cristina Prioteasa, 12/03/2024 03:23 AM

progress_copy.png (4.47 KB) Ioana-Cristina Prioteasa, 12/03/2024 03:24 AM

History

#1 Updated by Ioana-Cristina Prioteasa over 1 year ago

  • Subject changed from Fix conditions of throwing 11885 legacy error to Fix COPY-TEMP-TABLE issues

Summary of the Issue

Two key issues have been identified with the COPY-TEMP-TABLE function:

1. When Should Error 11885 Be Thrown
Legacy error 11885 is the error thrown by Progress when a COPY-TEMP-TABLE is performed on 2 temporary tables that don't match.

The error message is: A unique primary index is required in the target table, each field of which is mapped to some source field, in order to do a replace-mode or parent-mode COPY/GET/MERGE/FILL type of operation on a dataset table. (11885)

This task is meant to properly investigate what is the behavior in the legacy environment and the exact meaning of each field of which is mapped to some source field.
What we discover so far is that for each component of the destination table's primary key we must find a field in the source table with the same legacy name. This is how we are throwing the error now, but it seems that Progress is actually also checking the types of these fields and these need to also match.

1. Replicating behavior when replace-mode = TRUE

According to Progress documentation, the AVM ignores the append-mode parameter when replace-mode = TRUE.
Right now in FWD we have inconsistencies between running
hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, TRUE, TRUE, TRUE). and hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, FALSE, TRUE, TRUE)., but if the append-mode parameter is ignored, this should not happen.
A testcase is needed here to better understand this.

Testcase for 18855 error

DEFINE TEMP-TABLE ttFirst
    FIELD a AS LOGICAL
    FIELD b AS INTEGER.

DEFINE TEMP-TABLE ttSecond
    FIELD a AS INTEGER
    FIELD c AS INTEGER
    INDEX idxPrimary IS PRIMARY UNIQUE a.

DEFINE VARIABLE hFirstTemp  AS HANDLE NO-UNDO.
DEFINE VARIABLE hSecondTemp AS HANDLE NO-UNDO.

hFirstTemp  = TEMP-TABLE ttFirst:HANDLE.
hSecondTemp = TEMP-TABLE ttSecond:HANDLE.

CREATE ttFirst.
ASSIGN ttFirst.a = yes
       ttFirst.b = 11.

CREATE ttSecond.
ASSIGN ttSecond.a = 33
       ttSecond.c = 33.

hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, TRUE, TRUE, TRUE).

DEFINE VARIABLE outputString AS LONGCHAR NO-UNDO.

outputString = outputString + "Contents of ttFirst:" + CHR(10).
FOR EACH ttFirst:
    outputString = outputString + 
                   "a: " + STRING(ttFirst.a) + ", " +
                   "b: " + STRING(ttFirst.b) + CHR(10).
END.

outputString = outputString + CHR(10) + "Contents of ttSecond:" + CHR(10).
FOR EACH ttSecond:
    outputString = outputString + 
                   "a: " + STRING(ttSecond.a) + ", " +
                   "c: " + STRING(ttSecond.c) + CHR(10).
END.

MESSAGE STRING(outputString) VIEW-AS ALERT-BOX.

The above code is throwing the error in Progress, because ttFirst.a(LOGICAL) is not type compatible with ttSecond.a(INTEGER). In FWD because we only check the legacy name, the error is not thrown.

Next steps

  • A thorough investigation is needed to determine which data types are considered compatible in Progress. It's clear that matching data types do not necessarily need to be identical. For instance, if ttFirst.a is of type INT64 and ttSecond.a is of type INTEGER, Progress does not throw an error. Understanding the exact compatibility rules will allow us to accurately replicate this behavior in FWD.
  • Create a testcase for the replace-mode issue to better understand the behavior.

#3 Updated by Ioana-Cristina Prioteasa over 1 year ago

I tested on the above testcase more combinations of data types.
These are the results:

TtFirst – SRC TtSecond – DEST COMPATIBLE
DATE DATETIME NO
DATETIME DATE NO
DATE DATETIME-TZ NO
DATETIME-TZ DATE NO
DATETIME DATETIME-TZ NO
DATETIME-TZ DATE NO
INT INT64 YES
INT64 INT YES
INT DECIMAL NO
DECIMAL INT NO
DECIMAL INT64 NO
INT64 DECIMAL NO
LOGICAL CHAR NO
CHAR LOGICAL NO

It seems that beside the case where the data types are equal, the only other match would be on INT and INT64.
In the case that we were to copy here an INT64 into an INT and it would not fit, the legacy behavior is throwing these errors in order:

While testing this another weird thing came up.
This code in progress does not raise an error:

DEFINE TEMP-TABLE ttFirst
    FIELD a AS CHAR
    FIELD b AS INTEGER.

DEFINE TEMP-TABLE ttSecond
    FIELD a AS INTEGER
    FIELD c AS INTEGER
.

DEFINE VARIABLE hFirstTemp  AS HANDLE NO-UNDO.
DEFINE VARIABLE hSecondTemp AS HANDLE NO-UNDO.

hFirstTemp  = TEMP-TABLE ttFirst:HANDLE.
hSecondTemp = TEMP-TABLE ttSecond:HANDLE.

CREATE ttSecond.
ASSIGN ttSecond.a = 33
       ttSecond.c = 33.

hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, FALSE, TRUE, TRUE).

DEFINE VARIABLE outputString AS LONGCHAR NO-UNDO.

outputString = outputString + "Contents of ttFirst:" + CHR(10).
FOR EACH ttFirst:
    outputString = outputString + 
                   "a: " + STRING(ttFirst.a) + ", " +
                   "b: " + STRING(ttFirst.b) + CHR(10).
END.

outputString = outputString + CHR(10) + "Contents of ttSecond:" + CHR(10).
FOR EACH ttSecond:
    outputString = outputString + 
                   "a: " + STRING(ttSecond.a) + ", " +
                   "c: " + STRING(ttSecond.c) + CHR(10).
END.

MESSAGE STRING(outputString) VIEW-AS ALERT-BOX.

If the source has no values inside, the error is never thrown, even if we do not have a primary key on the dest table. So it seems that this should be the first condition to check.

#4 Updated by Ioana-Cristina Prioteasa over 1 year ago

The type check for emitting the 11885 error has been implemented and we now we also ensure the srcBuf is not empty before attempting to emit the error, aligning with Progress behavior.
While investigating the overflow issue where INT64 to INT raised an error in Progress but not in FWD, I found an additional functional inconsistency for cases without overflow. For example:

DEFINE TEMP-TABLE ttFirst
    FIELD a AS INT64
    FIELD b AS INTEGER.

DEFINE TEMP-TABLE ttSecond
    FIELD a AS INT
    FIELD c AS INTEGER
    INDEX idxPrimary IS PRIMARY UNIQUE a.

CREATE ttFirst.
ASSIGN ttFirst.a = 30
       ttFirst.b = 11.

CREATE ttSecond.
ASSIGN ttSecond.a = 1
       ttSecond.c = 33.

In progress the result is:

While in FWD:

In TemporaryBuffer.copyAllRows, data should be copied via:

copy((DataModelObject) srcRec, (DataModelObject) dstRec, propsMap, null); 

However, propsMap is empty, leading to no properties being copied. This is due to its initialization in:
propsMap = createPropsMap(looseCopy, srcBufImpl, dstBufImpl, errorMode);

Within createPropsMap, the following type check only includes equal types:
if (srcType null || dstType null || !srcType.equals(dstType))
Updating this condition to allow compatibility between INT64 and INT resolves the issue:
         boolean typesCompatible = (srcType == dstType) ||
                                   (srcType == ParmType.INT && dstType == ParmType.INT64) ||
                                   (srcType == ParmType.INT64 && dstType == ParmType.INT);

         if (srcType == null || dstType == null || !typesCompatible)

Questions to Address:

1. Are there other places where assigning int and in64 does not match progress behavior? Here I only updated this specific function, would overriding equals for ParmType and passing yes for int and int64 fix other issues like this?
2. When an overflow occurs, FWD raises a 15747 error and halts (with the fix explained here). In Progress, two additional errors are shown (see #9397-3). Should FWD replicate this behavior to match Progress more closely, or is the current handling sufficient?

The second error Couldn't update field 'a' of target in a BUFFER-COPY statement. (5368) does not seem to be in either ErrorManager or thrown elsewhere in FWD..

#5 Updated by Ovidiu Maxiniuc over 1 year ago

Ioana-Cristina Prioteasa wrote:

1. Are there other places where assigning int and in64 does not match progress behavior? Here I only updated this specific function, would overriding equals for ParmType and passing yes for int and int64 fix other issues like this?

I understand your concern but it's difficult to say. The initial FWD implementations of 4GL features are done based on the reference manual and the developer's imagination. Then they are 'polished' when issues are discovered with customer projects. There were cases when the the customer used undocumented features but also cases where the documentation diverges from 4GL behaviour. We aim for the latter, even if it conflict with the ref manual.

2. When an overflow occurs, FWD raises a 15747 error and halts (with the fix explained here). In Progress, two additional errors are shown (see #9397-3). Should FWD replicate this behavior to match Progress more closely, or is the current handling sufficient?

Yes. FWD must mimic the OE behaviour entirely. There are a few methods in ErrorManager which allow you to raise a set of error conditions as you described. (Alternatively, I think there are usages when the first but the last use just displayError() method and only the last use recordOrThrowError()).

The second error Couldn't update field 'a' of target in a BUFFER-COPY statement. (5368) does not seem to be in either ErrorManager or thrown elsewhere in FWD..

Indeed, it is not, yet. Please address this issue as described above.

#6 Updated by Eric Faulhaber over 1 year ago

  • reviewer Alexandru Lungu, Ovidiu Maxiniuc added

#7 Updated by Ioana-Cristina Prioteasa over 1 year ago

  • Status changed from New to WIP
  • reviewer deleted (Alexandru Lungu, Ovidiu Maxiniuc)

#8 Updated by Ioana-Cristina Prioteasa over 1 year ago

  • Status changed from WIP to Review
  • reviewer Alexandru Lungu, Ovidiu Maxiniuc added

Committed on 9397a rev. 15585.
Added 5368 and 12304 errors, added type check for throwing 11885 error, fixed how AbstractTempTable.copyTempTable calls TemporaryBuffer.copyAllRows regarding skipUniqueConflicts parameter and in TemporaryBuffer.createPropsMap adjusted type check to also match INT and INT64.

From my point of view, the riskiest change here is the new error throws. I will continue with trying to create more testcases in Progress to try and obtain them in other ways and check if this still behaves as it should.

Alex/Ovidiu, please review. Thanks!

#9 Updated by Ovidiu Maxiniuc over 1 year ago

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

Review of 9397a rev. 15584/5.

In spite of the long list below, the update is actually good. These are hidden and edge-case scenarios we did not take into consideration until now. I am a bit concerned about the computational effort for index checking in TemporaryBuffer.copyAllRows() (which has to be executed on each copy operation) but I hope we can optimize it so it will not be observable at runtime.

  • AbstractTempTable.java:
    • line 578: a space between if and the ( is required as in if (!res);
    • lines 5782 and 5783: to avoid wrapping and unwrapping, use BufferImpl.doGetName(). Ex: ((BufferImpl) srcDMO).doGetName()
    • line 575: it's a bit strange how the parameters of this method evolved. skipUniqueConflicts is documented as being ignored if replaceMode is on. However, the append and replaceMode are also passed as parameters. I assume this was the result of the observations in your testcases. This change will require testing;
    • in case of using the new ErrorManager APIs I made a habit of putting the error text in comment on the next line. These APIs have the advantage of being more centralized and offer additional support (like translation/i18n), but as you see are a bit opaque is not annotated this way. This is not mandatory, but helps the human reader understand faster what is this error about (as opposed to looking up in ErrorManager source).
  • RecordBuffer.java, method copy:
    • line 3770: I do not think declaring ErrorConditionException being thrown is necessary. It is a unchecked Exception, and it is not even thrown directly;
    • lines 3806-3817: bad indentation. One extra tab, possible because these lines were put in a block while working on the issue;
    • lines 3887 and 3904: the e Exception is not checked at all. Although this is usually not an issue here, there more be more causes for executing these catch blocks. The id of the error condition should be checked and rethrow it if it is not 'interested' at this moment;
    • lines 3888 and 3905: I think propertyName is NOT the right argument. The property names are used by FWD internally. The legacy name is most likely expected, like: da.propertyMeta.getLegacyName();
    • lines 3889 and 3906: please use logical.FALSE (or logical.TRUE) constants, instead of creating new logical objects;
    • for ErrorManager.recordOrShowError(), see the above note about its opacity;

Regarding this cascading approach of catching an ErrorConditionException and use the ErrorManager to chain a subsequent one. I think this is new and I guess OE does something like this internally. Unfortunately, I think it will NOT work as you expect. At least in NO-ERROR (silent) mode, the errors are collected, but the ErrorConditionException is NOT propagated (instead the methods return false and statements ?). The new catch-es will not catch anything. I suggested in #9397-5 to use older ErrorManager.recordOrShowError(int[], String[] ...) but looking at the code this might not be possible because the individual error conditions are identified at different levels, not all at once.

  • TemporaryBuffer.java:
    • line 757: both entry should 'consume' a single H entry no (213), one per merge into trunk operation;
    • line 4330: isSrcEmpty is always false due to line 4260;
    • line 4340 and next: stream API is not desired in FWD because of the performance overhead. There are several lambdas which were debatable. Especially in persistence, we struggle to optimize things as much as possible;
      • line 4345 and 4354: what does this help? If the legacy name is null (or Property, for latter), probably there is a problem which we might want to handle.
      • lines 4369 and 4371 should be indented by one space to match the left-hand operand of && operators;
      • lines 4367 to 4371: == for comparing classes is perfectly safe (instead of equals method). JVM guarantees there are no different Class instances for same class;
    • line 4481: after commit *= -1; a break or something similar is necessary. Otherwise, as the while loops, commit will alternate between 1 and -1 and finish with an unexpected result. If the loop was supposed to continue this would have been an issue. This is a smart trick, but probably commit = (commit == 0) ? 0 : -1; would have been safer (and arguably faster).

I updated the % done to 50, but it is probably higher than that.

#10 Updated by Ioana-Cristina Prioteasa over 1 year ago

Addressed code review in 9397a rev. 15586.

Ovidiu Maxiniuc wrote:

  • TemporaryBuffer.java:
    • line 4481: after commit *= -1; a break or something similar is necessary. Otherwise, as the while loops, commit will alternate between 1 and -1 and finish with an unexpected result. If the loop was supposed to continue this would have been an issue. This is a smart trick, but probably commit = (commit == 0) ? 0 : -1; would have been safer (and arguably faster).

Regarding the above point, for these temp tables:

DEFINE TEMP-TABLE ttFirst
    FIELD a AS INT64
    FIELD b AS INTEGER.

DEFINE TEMP-TABLE ttSecond
    FIELD a AS INT
    FIELD c AS INTEGER
    INDEX idxPrimary IS PRIMARY UNIQUE a.

DEFINE VARIABLE hFirstTemp  AS HANDLE NO-UNDO.
DEFINE VARIABLE hSecondTemp AS HANDLE NO-UNDO.

hFirstTemp  = TEMP-TABLE ttFirst:HANDLE.
hSecondTemp = TEMP-TABLE ttSecond:HANDLE.

CREATE ttFirst.
ASSIGN ttFirst.a = 300000000000000
       ttFirst.b = 11.

CREATE ttFirst.
ASSIGN ttFirst.a = 30
       ttFirst.b = 11.

CREATE ttSecond.
ASSIGN ttSecond.a = 1
       ttSecond.c = 33.

hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, FALSE, TRUE, TRUE).

In this example, progress is throwing errors 15747, 5368, 12304 and then the output is:
Contents of ttFirst:
a: 300000000000000, b: 11
a: 30, b: 11

Contents of ttSecond:
a: 1, c: 33
a: 30, c: 0

This means that the copy operation continued for the second row even if the first had an error. So the commit should not be affected by this, if the second record is copied successfully is will be committed. This is addressed in the latest commit.

Ovidiu Maxiniuc wrote:

Regarding this cascading approach of catching an ErrorConditionException and use the ErrorManager to chain a subsequent one. I think this is new and I guess OE does something like this internally. Unfortunately, I think it will NOT work as you expect. At least in NO-ERROR (silent) mode, the errors are collected, but the ErrorConditionException is NOT propagated (instead the methods return false and statements ?). The new catch-es will not catch anything. I suggested in #9397-5 to use older ErrorManager.recordOrShowError(int[], String[] ...) but looking at the code this might not be possible because the individual error conditions are identified at different levels, not all at once.

I understand the concern, I left it like that for now. I will try to create some testcases for this to find a behavior not corresponding with progress. I am still looking into this.

#11 Updated by Ioana-Cristina Prioteasa over 1 year ago

I am currently testing different parameter combinations for COPY-TEMP-TABLE and have identified another inconsistency in behavior. This was tested with the existing modifications on branch 9397a.
For these temp tables:
DEFINE TEMP-TABLE ttFirst
    FIELD a AS INTEGER
    FIELD b AS INTEGER
    INDEX idxPrimary IS PRIMARY UNIQUE a.

DEFINE TEMP-TABLE ttSecond
    FIELD a AS INTEGER
    FIELD c AS INTEGER
    FIELD d AS INTEGER
    INDEX idxPrimary IS PRIMARY UNIQUE d.

DEFINE VARIABLE hFirstTemp  AS HANDLE NO-UNDO.
DEFINE VARIABLE hSecondTemp AS HANDLE NO-UNDO.

hFirstTemp  = TEMP-TABLE ttFirst:HANDLE.
hSecondTemp = TEMP-TABLE ttSecond:HANDLE.

CREATE ttFirst.
ASSIGN ttFirst.a = 1
       ttFirst.b = 11.
CREATE ttFirst.
ASSIGN ttFirst.a = 2
       ttFirst.b = 22.

CREATE ttSecond.
ASSIGN ttSecond.a = 33
       ttSecond.c = 33
       ttSecond.d = 1.
       CREATE ttSecond.
ASSIGN ttSecond.a = 333
       ttSecond.c = 333
       ttSecond.d = 3.

And for the copy operation: hSecondTemp:COPY-TEMP-TABLE(hFirstTemp, append-mode=FALSE, replace-mode=FALSE, loose-copy-mode=TRUE).
Progress output:
  • ttSecond already exists with 0. (132)
  • Error found during COPY-TEMP-TABLE operation on ttFirst and ttSecond. (12304)
  • Contents of ttFirst:
    a: 1, b: 11
    a: 2, b: 22
    
    Contents of ttSecond:
    a: 1, c: 0, d: 0
    
FWD output - 9397a latest:
  • ttSecond already exists with 0. (132)
  • Error found during COPY-TEMP-TABLE operation on ttFirst and ttSecond. (12304)
  • Contents of ttFirst:
    a: 1, b: 11
    a: 2, b: 22
    
    Contents of ttSecond:
    a: 1, c: 0, d: 0
    a: 333, c: 333, d: 3
    

Observations

  1. Error 12304 Behavior: The addition of error 12304 is consistent with Progress, indicating aligning behavior.
  2. Commit Logic Issue: The FWD results differ from Progress due to an issue in the commit logic within TemporaryBuffer.copyAllRows().

Root Cause

The inconsistency arises from the following logic in TemporaryBuffer.copyAllRows():

                     if (skipUniqueConflicts)
                     {
                        continue;
                     }
                     else
                     {
                        ErrorManager.recordOrShowError(e.getNumber(), e.getMessage(), false);
                        commit *= -1;
                        validationError = true;
                        break;
                     }

When the "already exists" error occurs, the commit variable is modified to -1, triggering a rollback instead of a commit. This behavior is incorrect in this context.

Fix

Removing the line commit *= -1; resolves the issue, ensuring that Progress and FWD produce identical results.

#12 Updated by Ovidiu Maxiniuc over 1 year ago

The result is a bit strange, before the fix. I understand that a: 1, c: 0, d: 0 is the row correctly copied, but the a: 333, c: 333, d: 3 should not be there. In fact both initial records of ttSecond should have been dropped when copy method started (because append is false).

I do not recall the right behaviour when an index collision occurs in non REPLACE mode. Is it all-or-nothing or just stop at the point and save at the current state. I reread the ref-manual for COPY-TEMP-TABLE, but this is not specified. However, based on the 4GL output you posted I understand that it's the latter. So in this case, the while which iterates the source records should stop and the transaction should be committed. Not rolled-back, since we would loose all copied records up-to the moment when the error condition was identified. That is, the semantics of commit values are restricted to /commit/ or /do-nothing/, but never /roll-back/.

Please test my theory. However, also in this case, I cannot explain the presence of a: 333, c: 333, d: 3.

#13 Updated by Ioana-Cristina Prioteasa over 1 year ago

  • Status changed from WIP to Review
Committed on 9397a rev. 15587:
  • removed logic to rollback when a validation error occurs.
  • Moved the 12304 error in copyAllRows to avoid throwing it when 11885 error is thrown.
  • refactored the maps construction to not use streams.

Note: I kept the overall commit logic because it is still used when these errors are thrown:

      catch (PersistenceException exc)
      {
         commit *= -1;
         DBUtils.handleException(DatabaseManager.TEMP_TABLE_DB, exc);
         ErrorManager.recordOrThrowError(exc);
      }
      catch (IllegalAccessException | InstantiationException exc)
      {
         commit *= -1;

         throw new RuntimeException("Error creating record", exc);
      }
      catch (InvocationTargetException exc)
      {
         commit *= -1;
         DBUtils.handleException(DatabaseManager.TEMP_TABLE_DB, exc);

         throw new RuntimeException("Error creating record", exc);
      }
      catch (StopConditionException exc)
      {
         // thrown by Persistence when a JDBC-level error was encountered; Hibernate session will
         // have been closed, don't try to commit or rollback below
         commit = 0;

         if (LOG.isLoggable(Level.SEVERE))
         {
            LOG.log(Level.SEVERE, "Error copying all temp table records", exc);
         }

         throw exc;
      }

I did not manage to reach this code.

Tested the solution for these cases:

Schema APPEND-MODE REPLACE-MODE LOOSE COPY
not matching F F T
T F T
F T T
T T T
matching F F F
T F F
F T F
T T F

For all of the above the FWD behaviour matches progress.
I also tested with LOOSE-COPY=false and not matching schema, this also aligns.
Calling the copy operation with NO-ERROR also works as expected.

Alex/Ovidiu, please review 9397a rev. 15586-15587.

My plan is to start testing in the meantime a larger customer application to see if something was overlooked.

#14 Updated by Alexandru Lungu over 1 year ago

Ioana, please design a 4GL Unit Tests suite according to 4GL_Unit_Testing. Include the cases you found in the development phase (including the table from #9397-13).

#15 Updated by Alexandru Lungu over 1 year ago

Review of 9397a:

  • Changes look good in terms of error handling.
  • for type checking:
    +                     if (srcProp == null ||
    +                        !(dstProp._fwdType == srcProp._fwdType) ||
    +                        (dstProp._fwdType == integer.class && srcProp._fwdType == int64.class) ||
    +                        (dstProp._fwdType == int64.class && srcProp._fwdType == integer.class))
    
    • This doesn't seem right; 3rd and 4th conditions look redundant. Last 2 conditions imply !(dstProp._fwdType == srcProp._fwdType) anyway. I think there is a parenthesis misplacement.
  • Unless you do stream work, you can remove the import.
  • I am not sure that commit *= -1 is right. Maybe it is, but from my understanding of #9397-11, I don't see how a rollback would have triggered such output. How should a COMMIT generate less records in a copy routine comparing to a ROLLBACK? Anyway, I think Ovidiu had more time to look into this area and can provide a better feedback.

#16 Updated by Ovidiu Maxiniuc over 1 year ago

Review of 9397a, r15587:

I see the issues from my previous review have been addressed.

But, as Alex mentioned above, there's something fishy in TemporaryBuffer.java: it seems that you did not finish negating the previous class check. It looked correct in previous revision, and now the meaning is reversed, and that's OK. Or maybe you mispaired (is there such a word?) the negated parenthesis, which should have been closed at the very end of the expression. At any rate, by applying the distributivity, I think should be something like:

                     if (srcProp == null ||
                         (dstProp._fwdType != srcProp._fwdType                                   &&
                          (dstProp._fwdType != integer.class || srcProp._fwdType != int64.class) &&
                          (dstProp._fwdType != int64.class   || srcProp._fwdType != integer.class)))
                     {
                        // not a match
                     }
Note the indentation which helps visual identification of the parentheses, even if the editor does not highlight them.

However, I think we can have a fail-fast faster than this. You kept original thinking and converted the stream implementation to a faster iterative one. There are 3 steps of this algorithm: (1) creation of dstPropsMap, (2) iterate it and populate the srcPropsMap, (3) compare the two maps. Why not processing all in a single loop? Iterate primaryIndex.components() and look for both source and destination Property. If any of them fails (is null), the final maps cannot be equals. Otherwise you can compare the classes as described above. And I think there is no need for storing the the results in dstPropsMap and srcPropsMap, as they were only used for deciding if the index is right.

Related to removal of commit *= -1;: I think that it's probably OK, but I am really not sure about the continue; at line 4494. Shouldn't we stop if a copy error happens (that is: using break instead)? Please test and confirm, if you haven't done it already.

#17 Updated by Ioana-Cristina Prioteasa over 1 year ago

Addressed the code review in 9397a rev. 15588:
  • Corrected the if statement, which was indeed missing a set of parentheses. Following the logic !(A || B) = !A && !B, the if condition suggested by Ovidiu in #9397-16 is equivalent to the one currently committed. I opted to retain the current version, as I find it more intuitive and easier to understand.
  • Refactored the logic to perform all operations within a single loop.
  • Revisited the use of continue. After additional testing, I confirmed that when a copy error occurs, the remaining records are still processed. This confirms that using continue is the correct behavior, not break.

Ovidiu, please review! Thank you!

#18 Updated by Ovidiu Maxiniuc over 1 year ago

  • Status changed from Review to Internal Test

I have reviewed 9397a rev. 15588.

All issues I identified are done. Please also remove the unnecessary imports from TemporaryBuffer. No review needed for this.

Go ahead and start the regression tests. Good job!

#19 Updated by Ioana-Cristina Prioteasa over 1 year ago

Committed to 9397a rev. 15589 a couple of quick fixes: removed unused import and corrected the use of getPropretyName() instead of getLegacyName(). As discussed in today's stand up, these don't need review.
I also added 5 new tests to the TestCopyTempTable 4GL unit test suite.

#20 Updated by Ioana-Cristina Prioteasa over 1 year ago

Testing plan for 9397a rev. 15585-15589:
  • Ioana[icp]: large customer application unit tests - done
  • Andrei[ai]: large customer Gui application regression tests and smoke test
  • Ioana[icp]: large customer application harness tests - done
  • Ioana[icp]/Lorian[ls]: Chui regression tests - done
  • Lorian[ls]: ETF tests - done
  • Ioana[icp]: convert and tests the new 4GL unit tests - done
  • Ioana[icp]: performance tests

#21 Updated by Lorian Sandu over 1 year ago

9397a has only runtime changes?

#22 Updated by Ioana-Cristina Prioteasa over 1 year ago

Lorian Sandu wrote:

9397a has only runtime changes?

Yes, no reconversion needed.

#23 Updated by Lorian Sandu over 1 year ago

Ioana, can you rebase the branch to latest trunk, please?

#24 Updated by Ioana-Cristina Prioteasa over 1 year ago

Lorian Sandu wrote:

Ioana, can you rebase the branch to latest trunk, please?

9397a is rebased and it is now at revision 15621.

#25 Updated by Andrei Iacob over 1 year ago

Chui regression tests passed ✅

#26 Updated by Lorian Sandu over 1 year ago

ETF also passed ✅

#27 Updated by Ioana-Cristina Prioteasa over 1 year ago

Added one more test to the TestCopyTempTable 4GL unit tests suite and committed to the testcases project in total 6 new tests. With 9397a changes these all successfully pass in FWD.
I also edited #9397-20 test plan to reflect the passed tests.

#28 Updated by Lorian Sandu over 1 year ago

Large customer gui application unit-tests passed ✅

#29 Updated by Andrei Iacob over 1 year ago

Smoketests of another large GUI application passed ✅

#30 Updated by Ioana-Cristina Prioteasa over 1 year ago

Completed performance testing, is seems unaffected as it is 1% better than the baseline.
Testing plan is complete, we can merge.

#31 Updated by Alexandru Lungu over 1 year ago

  • Status changed from Internal Test to Merge Pending

Please merge 9397a to trunk now. Adjust the %Done accordingly.

#32 Updated by Ioana-Cristina Prioteasa over 1 year ago

  • Status changed from Merge Pending to Test
  • % Done changed from 50 to 100

9397a is merged to trunk as rev. 15627.

#33 Updated by Ioana-Cristina Prioteasa over 1 year ago

9397a is also merged to 7156c as rev.15524.

#34 Updated by Alexandru Lungu about 1 year ago

  • Status changed from Test to Closed

This can be closed.

Also available in: Atom PDF