Project

General

Profile

Bug #10208

do not convert the schema in incremental mode if it hasn't changed

Added by Greg Shah about 1 year ago. Updated 11 months ago.

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

100%

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

Related issues

Related to Conversion Tools - Feature #6083: schema (.df) changes in incremental conversion mode should only reconvert those programs that reference the changed schema Closed
Related to Base Language - Bug #10613: Incremental conversion issue: temp-table dmo does not get converted Closed

History

#1 Updated by Greg Shah about 1 year ago

Customers have reported that we always convert the schema in incremental mode (see #10175-26). For large projects, this can add a significant amount of time. It doesn't make any sense if the .df files are unchanged. Even if they are changed, then we should force a full conversion instead of incremental.

Can we just disable M0 in incremental mode?

#2 Updated by Constantin Asofiei about 1 year ago

Greg Shah wrote:

Can we just disable M0 in incremental mode?

The problem with is that for #9457 app, front-end schema parsing takes a lot (the problem is from AnnotatedAst.nearest IIRC).

Disabling M0 will need to be done only for the main db, and not the temp schemas. Otherwise, I would suggest disabling schema parsing on front-end for incremental (or maybe just change build.xml to use F0 instead of F2).

#3 Updated by Greg Shah about 1 year ago

  • Assignee set to Dănuț Filimon

#4 Updated by Greg Shah about 1 year ago

  • Related to Feature #6083: schema (.df) changes in incremental conversion mode should only reconvert those programs that reference the changed schema added

#5 Updated by Greg Shah about 1 year ago

Disabling M0 will need to be done only for the main db, and not the temp schemas.

Before #6083, we could implement something to bypass the permanent schemata in M0 during incremental mode. After #6083, there is no need to bypass because we would only convert those tables and nothing more.

Otherwise, I would suggest disabling schema parsing on front-end for incremental (or maybe just change build.xml to use F0 instead of F2).

This seems like a quick win.

#6 Updated by Dănuț Filimon about 1 year ago

As far as I can tell, there doesn't seem to be any information (e.g. hash) for the schema file in the cvtdb database. There's only the cvt/data folder which stores the information about the schema, it will be helpful if we create a table in cvtdb h2 database that can be used for the incremental conversion (just like the FILE_SIGNATURE table).

#7 Updated by Greg Shah about 1 year ago

I don't object, but can we just add the schemata to the FILE_SIGNATURE table?

#8 Updated by Dănuț Filimon about 1 year ago

Greg Shah wrote:

I don't object, but can we just add the schemata to the FILE_SIGNATURE table?

Yes, I will do this instead.

#9 Updated by Dănuț Filimon about 1 year ago

My current implementation works like this:
  1. SchemaLoader.importSchema() should call ConversionData.saveFileHash(srcfile); to save the df (If the df is not changes, this means that the dict, p2o will be the same).
  2. Add SchemaLoader.hasSchemaChanges() to go over the current metadata import file and other import files.
  3. Add an additional ConversionData.mustConvertFile that avoids checking for .ast (I am not sure if there are any hint files for schema?)
  4. During the incremental conversion check of the conversion files, set mode.schema to false if SchameLoader.hasSchemaChanges() returns false.

#10 Updated by Dănuț Filimon about 1 year ago

  • Status changed from New to WIP

#11 Updated by Greg Shah about 1 year ago

The approach seems correct to me.

I am not sure if there are any hint files for schema?

Yes, there are schema hints files. See Conversion Hints.

Constantin: Do we already detect that UAST .hints file changes are a cause to reconvert the associated program?

#12 Updated by Constantin Asofiei about 1 year ago

Greg Shah wrote:

Constantin: Do we already detect that UAST .hints file changes are a cause to reconvert the associated program?

Not at this time. There is also #4867 for .ext-hints

#13 Updated by Dănuț Filimon about 1 year ago

I've made a few changes as mentioned in #10208-9, but I am wondering if there are any other conversion steps I should be avoiding. I have the following:
  • SchemaLoader - already skipped by the changes
  • Schema Fixups (data dictionary)
  • P2O Generation (database schema files)
  • P2O Post-processing (database schema files)
  • Generate Plain Old Java Objects (database DMOs)

Maybe not all of them, but only the conversion steps that process the schemas and create their respective p2o/dict/schema files. Currently investigating...

#14 Updated by Dănuț Filimon about 1 year ago

I created 10208a from trunk/16005 and committed an initial version in 10208a/16006. The changes are for #10208-9.

#15 Updated by Dănuț Filimon about 1 year ago

#10208-13 can be achieved by correctly setting CvtRunMode.skipDBSchema, I made it protected and did the following for a test:

            if (mode.schema)
            {
               SchemaLoader loader = new SchemaLoader();
               mode.schema = loader.hasSchemaChanges();
               ((ConversionDriver.CvtRunMode) mode).skipDBSchema = !mode.schema;
            }
I'll have to consider something a bit cleaner.

#16 Updated by Dănuț Filimon about 1 year ago

Greg, the skipDBSchema is quite old. I suggest removing it and using the schema flag to do the job.

#17 Updated by Greg Shah about 1 year ago

Dănuț Filimon wrote:

Greg, the skipDBSchema is quite old. I suggest removing it and using the schema flag to do the job.

Doing that would be consistent in M0 and M1 modes but inconsistent in F2 and F3 modes. Please check what the impact is in those cases.

#18 Updated by Dănuț Filimon about 1 year ago

In our weekly meeting, I mentioned that I would not modify how the M0, M1, F2 and F3 modes are used. I decided to take a similar approach and create a similar mode to CvtRunMode called IncrementalCvtRunMode. The only difference is that the IncrementalCvtRunMode will only be merged with the JobDefinition.mode during the incremental conversion.

#19 Updated by Dănuț Filimon about 1 year ago

I committed 10208a/16007. Added IncrementalCvtRunMode and used to skip most of the phases that involve the database schema.

#20 Updated by Dănuț Filimon 12 months ago

Rebased 10208a to latest trunk/16074, the branch is now at revision 16076.

#21 Updated by Dănuț Filimon 12 months ago

  • % Done changed from 0 to 100
  • Status changed from WIP to Review
  • reviewer Greg Shah added

Committed 10208a/16077. Removed IncrementalCvtRunMode, omitting the schema related phases can be achieved using the existent schema, skipDBSchema, omitSchemaBrew flags.

Greg, please review.

#22 Updated by Greg Shah 12 months ago

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

Code Review Task Branch 10208a Revisons 16075 through 16077

Overall the changes are a good first pass. In most cases, this will avoid conversion. The problem is that if there is any .df that has changed, then ALL of the .df files are converted, even the ones that haven't changed. We should only convert the changed schemata.

#23 Updated by Dănuț Filimon 12 months ago

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

Greg Shah wrote:

Code Review Task Branch 10208a Revisons 16075 through 16077

Overall the changes are a good first pass. In most cases, this will avoid conversion. The problem is that if there is any .df that has changed, then ALL of the .df files are converted, even the ones that haven't changed. We should only convert the changed schemata.

I've made the changes and committed 10208a/16078. Please review.

#24 Updated by Greg Shah 12 months ago

Code Review Tk Branch 10208a Revision 16078

Overall, I agree with the changes for when we are running incremental conversion. Are the changes to SchemaLoader.importAll() safe in a full conversion mode?

#25 Updated by Dănuț Filimon 12 months ago

  • Status changed from Review to Internal Test

Greg Shah wrote:

Code Review Tk Branch 10208a Revision 16078

Overall, I agree with the changes for when we are running incremental conversion. Are the changes to SchemaLoader.importAll() safe in a full conversion mode?

Changes are safe, I've tested hotel_gui in the following scnarios:
  • full conversion
  • added a new file, then ran incremental conversion
  • added a new file, modified hotel.df, then ran incremental conversion

#26 Updated by Greg Shah 12 months ago

OK, then add a comment to explain that in full conversion mode, all schemata will be detected as "changed" and will be converted.

#27 Updated by Dănuț Filimon 12 months ago

Committed 10208a/16079, added a detailed javadoc to schemasChanged set class members in TransformDriver and SchemaLoader.

#28 Updated by Dănuț Filimon 12 months ago

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

I started working on the regression test plan and found this issue while testing a customer application:

     [java] Processing mutable schema '<replaced>'...
     [java] ERROR:
     [java] com.goldencode.p2j.schema.SchemaException: Error importing schema data: <replaced>
     [java]     at com.goldencode.p2j.schema.SchemaLoader.importSchema(SchemaLoader.java:597)
     [java]     at com.goldencode.p2j.schema.SchemaLoader.importAll(SchemaLoader.java:485)
     [java]     at com.goldencode.p2j.convert.TransformDriver.runSchemaLoader(TransformDriver.java:361)
     [java]     at com.goldencode.p2j.convert.TransformDriver.front(TransformDriver.java:263)
     [java]     at com.goldencode.p2j.convert.TransformDriver.executeJob(TransformDriver.java:1022)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.main(ConversionDriver.java:1225)
     [java] Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: ./data/<replaced>.df (No such file or directory)
     [java]     at com.goldencode.p2j.convert.db.ConversionData.computeFileHash(ConversionData.java:380)
     [java]     at com.goldencode.p2j.convert.db.ConversionData.saveFileHash(ConversionData.java:396)
     [java]     at com.goldencode.p2j.schema.SchemaLoader.importSchema(SchemaLoader.java:593)
     [java]     ... 5 more
     [java] Caused by: java.io.FileNotFoundException: ./data/<replaced>.df (No such file or directory)
     [java]     at java.base/java.io.FileInputStream.open0(Native Method)
     [java]     at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
     [java]     at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
     [java]     at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111)
     [java]     at com.goldencode.p2j.convert.db.ConversionData.computeFileHash(ConversionData.java:353)
     [java]     ... 7 more
     [java]

The df file does not exist, but a namespace is defined in p2j.cfg.xml.

#29 Updated by Dănuț Filimon 12 months ago

  • Status changed from WIP to Review
  • % Done changed from 90 to 100

The solution is simple, only save the file hash if we use a df file:

         if (useDfFile)
         {
            ConversionData.saveFileHash(srcfile);
         }
I am not sure what to expect from a mutable schema with no df file. Since there is no df file, I think the schema will not be used by the application.

Committed 10208a/16080. Greg, please review.

#30 Updated by Greg Shah 12 months ago

  • Status changed from Review to Internal Test

Code Review Task Branch 10208a Revision 16080

The change is good.

#31 Updated by Dănuț Filimon 11 months ago

Rebased 10208a to latest trunk/16110, the branch is now at revision 16116.

#32 Updated by Dănuț Filimon 11 months ago

Found an issue with ETF conversion, I will be investigating.

#33 Updated by Dănuț Filimon 11 months ago

There's a scenario in ETF where the schemasChanged is null, but also should contain all the schemas because we are not running incremental. I am thinking of doing the following:
  • schemasChanged = null means all schemas should be converted as we are not running an incremental conversion
  • calling getSchemaChanges() will always initialize schemasChanged to a HashSet

#34 Updated by Dănuț Filimon 11 months ago

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

Currently working on a fix.

#35 Updated by Dănuț Filimon 11 months ago

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

Committed 10208a/16117. Fixed full conversion problem where schemasChanged was null and the standard.df was skipped.

Greg, please review. I will restart the test plan.

#36 Updated by Greg Shah 11 months ago

  • Status changed from Review to Internal Test

Code Review Task Branch 10208a Revision 16117

I like it.

#37 Updated by Dănuț Filimon 11 months ago

I tested incremental conversion for two customers and even if the schema was not changed, it was still running the SchemaLoader and other steps. The commands I used were:

 
   <target name="convert.zset" 
           depends="init, check-zfile-set" 
           description="Convert the 4GL source code to Java source code, using the z-file set file as input." 
           if="zfile-set">
      <record name="cvt_${LOG_STAMP}.log" action="start"/>
      <java classname="com.goldencode.p2j.convert.ConversionDriver" 
            fork="true" 
            failonerror="true" 
            dir="${basedir}">
         <jvmarg value="-server"/>
         <jvmarg value="-Xmx${conversionHeap}"/>
         <jvmarg value="-XX:-OmitStackTraceInFastThrow"/>
         <jvmarg value="-DP2J_HOME=${p2j.home}"/>
         <arg value="-ZId2"/>
         <arg value="f2+m0+cb"/>
         <arg value="${zfile}"/>
         <classpath refid="compile.classpath"/>
      </java>
      <record name="cvt_${LOG_STAMP}.log" action="stop"/>
   </target>

and

   <target name="convert.zset" 
           depends="init, check-zfile-set" 
           description="Convert the 4GL source code to Java source code, using the z-file set file as input." 
           if="zfile-set">
      <record name="cvt_${LOG_STAMP}.log" action="start"/>
      <java classname="com.goldencode.p2j.convert.ConversionDriver" 
            fork="true" 
            failonerror="true" 
            dir="${basedir}">
         <jvmarg value="-server"/>
         <jvmarg value="-Xmx${conversionHeap}"/>
         <jvmarg value="-XX:-OmitStackTraceInFastThrow"/>
         <jvmarg value="-DP2J_HOME=${p2j.home}"/>
         <arg value="-ZId2"/>
         <arg value="f2+m0+cb"/>
         <arg value="${zfile}"/>
         <classpath refid="compile.classpath"/> 
      </java>
      <record name="cvt_${LOG_STAMP}.log" action="stop"/>
   </target>
The second resulted in the following error:
     [java] ------------------------------------------------------------------------------
     [java] Detecting Frame Interfaces
     [java] ------------------------------------------------------------------------------
     [java]
     [java] Elapsed job time:  00:00:00.072
     [java] EXPRESSION EXECUTION ERROR:
     [java] ---------------------------
     [java] frameInterfaces    = createMapFrameAstKeyToString("frameInterfaces")
     [java]                      ^  { org.h2.jdbc.JdbcSQLDataException: Deserialization failed, cause: "java.lang.NullPointerException: Cannot invoke ""com.goldencode.ast.Aast.duplica>
     [java] ---------------------------
     [java] ERROR:
     [java] java.lang.RuntimeException: ERROR!  Active Rule:
     [java] -----------------------
     [java]       RULE REPORT
     [java] -----------------------
     [java] Rule Type :   INIT
     [java] Source AST:  null
     [java] Copy AST  :  null
     [java] Condition :  frameInterfaces    = createMapFrameAstKeyToString("frameInterfaces")
     [java] Loop      :  false
     [java] --- END RULE REPORT ---
     [java]
     [java]
     [java]
     [java]     at com.goldencode.p2j.pattern.PatternEngine.run(PatternEngine.java:1111)
     [java]     at com.goldencode.p2j.convert.TransformDriver.processTrees(TransformDriver.java:591)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.generateFrames(ConversionDriver.java:845)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.back(ConversionDriver.java:581)
     [java]     at com.goldencode.p2j.convert.TransformDriver.executeJob(TransformDriver.java:1010)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.main(ConversionDriver.java:1315)
     [java] Caused by: com.goldencode.expr.ExpressionException: Expression execution error @1:22
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:495)
     [java]     at com.goldencode.p2j.pattern.Rule.apply(Rule.java:500)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.applyGlobal(PatternEngine.java:1754)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.run(PatternEngine.java:1041)
     [java]     ... 5 more
     [java] Caused by: java.lang.RuntimeException: org.h2.jdbc.JdbcSQLDataException: Deserialization failed, cause: "java.lang.NullPointerException: Cannot invoke ""com.goldencode.ast>
     [java]     at com.goldencode.p2j.convert.db.H2Map.lambda$new$0(H2Map.java:236)
     [java]     at com.goldencode.p2j.convert.db.DBHelper.executeQuery(DBHelper.java:452)
     [java]     at com.goldencode.p2j.convert.db.H2Map.<init>(H2Map.java:239)
     [java]     at com.goldencode.p2j.convert.db.ConversionData.createMap(ConversionData.java:833)
     [java]     at com.goldencode.p2j.pattern.CommonAstSupport$Library.createMapFrameAstKeyToString(CommonAstSupport.java:6309)
     [java]     at com.goldencode.expr.CE14478.execute(Unknown Source)
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:398)
     [java]     ... 8 more
     [java] Caused by: org.h2.jdbc.JdbcSQLDataException: Deserialization failed, cause: "java.lang.NullPointerException: Cannot invoke ""com.goldencode.ast.Aast.duplicate()"" because >
     [java]     at org.h2.message.DbException.getJdbcSQLException(DbException.java:590)
     [java]     at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
     [java]     at org.h2.message.DbException.get(DbException.java:194)
     [java]     at org.h2.util.JdbcUtils.deserialize(JdbcUtils.java:435)
     [java]     at org.h2.jdbc.JdbcConnection.convertToDefaultObject(JdbcConnection.java:2058)
     [java]     at org.h2.jdbc.JdbcResultSet.getObject(JdbcResultSet.java:525)
     [java]     at com.goldencode.p2j.convert.db.H2Map.lambda$new$0(H2Map.java:211)
     [java]     ... 14 more
     [java] Caused by: java.lang.NullPointerException: Cannot invoke "com.goldencode.ast.Aast.duplicate()" because "ast" is null
     [java]     at com.goldencode.p2j.uast.FrameAstKey.readExternal(FrameAstKey.java:265)
     [java]     at java.base/java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:2306)
     [java]     at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2255)
     [java]     at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1733)
     [java]     at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:509)
     [java]     at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:467)
     [java]     at org.h2.util.JdbcUtils.deserialize(JdbcUtils.java:433)
     [java]     ... 17 more
     [java]
Both converted the schema when they should have not.

#38 Updated by Dănuț Filimon 11 months ago

Committed 10208a/16118. SchemaLoader should have schemasChanged passed in runSchemaLoader().

Mutable databases will always cause the schema to be converted, the problem was that I was having the schemasChanged set with the mutable database, but I was not using the collection in runSchemaLoader(). I retested incremental conversion with the fix on the same application and it was ok.

I am not sure about the frames problem since it seems to get stuck there, so I am running another full conversion.

#39 Updated by Dănuț Filimon 11 months ago

Testing went well, Radu also got the error from #10208-37 and it was related to trunk/16111 (since he converted with trunk/16110 + 10208a, he found the same issue).

Conclusion, testing passed and 10208a can be merged.

#40 Updated by Greg Shah 11 months ago

I'm OK with a merge but please coordinate with Constantin to ensure that we don't negatively affect customer deliveries for today.

#41 Updated by Constantin Asofiei 11 months ago

  • Status changed from Internal Test to Merge Pending

You can merge to trunk now.

#42 Updated by Dănuț Filimon 11 months ago

  • Status changed from Merge Pending to Test
  • version_resolved set to trunk/16124

Branch 10208a was merged into trunk as rev. 16124 and archived.

#43 Updated by Greg Shah 11 months ago

  • Status changed from Test to Closed

#44 Updated by Dănuț Filimon 10 months ago

  • Related to Bug #10613: Incremental conversion issue: temp-table dmo does not get converted added

Also available in: Atom PDF