Derby
  1. Derby
  2. DERBY-4160

getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already exists."

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.4.2.0
    • Fix Version/s: 10.10.2.0, 10.11.1.1
    • Component/s: SQL
    • Environment:
      FreeBSD java 1.6.0, 64-Bit Server VM; DataNucleus JDO
    • Urgency:
      Normal

      Description

      The following code in DataNucleus:
      rs = conn.getMetaData().getIndexInfo(catalogName, schemaName, tableName, false,
      true);
      triggers an Exception (http://gist.github.com/95679):

      Caused by: java.sql.SQLException: Column 'PARAM1' already exists.
      at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
      at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:119)
      at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
      ... 105 more
      Caused by: ERROR X0Y68: Column 'PARAM1' already exists.
      at org.apache.derby.iapi.error.StandardException.newException(StandardException.java:303)
      at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(DataDictionaryImpl.java:1678)
      at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(DataDictionaryImpl.java:1662)
      at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addSPSParams(DataDictionaryImpl.java:3682)
      at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(DataDictionaryImpl.java:3830)
      at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(SPSDescriptor.java:1112)
      at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:736)
      at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:642)
      at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(ExecSPSNode.java:177)
      at org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:447)
      at org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:88)
      at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:794)
      at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(EmbedPreparedStatement.java:128)
      ... 99 more

      1. d4160-1a.diff
        17 kB
        Knut Anders Hatlen
      2. D4160.java
        1 kB
        Knut Anders Hatlen

        Issue Links

          Activity

          ArtemGr created issue -
          Hide
          Knut Anders Hatlen added a comment -

          It is triggered when we try to add rows to SYS.SYSCOLUMNS in DataDictionaryImpl.updateSPS():

          if(firstCompilation)

          { /*beetle:5119, reason for doing add here instead of update *is with NOCOMPILE option of create statement/boot time SPS, *SPS statement is not compiled to find out the parameter info. *Because of the parameter info was not inserted at SPSDescriptor *creation time. As this is the first time we are compiling paramter *infor should be inserted instead of the update. */ addSPSParams(spsd, tc); }

          For some reason the rows already exist, even though the meta-data statement has not been compiled before.

          I'm wondering if this is related to the retry logic in SPSDescriptor.getPreparedStatement(boolean):

          // DERBY-2584: If the first attempt to compile the query fails,
          // we need to reset initiallyCompilable to make sure the
          // prepared plan is fully stored to disk. Save the initial
          // value here.
          final boolean compilable = initiallyCompilable;

          try

          { prepareAndRelease(lcc, null, nestedTC); updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC); }

          catch (StandardException se)
          {
          if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT))
          {
          if (nestedTC != null)

          { nestedTC.commit(); nestedTC.destroy(); nestedTC = null; }

          // if we couldn't do this with a nested xaction, retry with
          // parent-- we need to wait this time!
          initiallyCompilable = compilable;
          prepareAndRelease(lcc, null, null);
          updateSYSSTATEMENTS(lcc, RECOMPILE, null);
          }
          else throw se;
          }

          If the lock timeout in the nested transaction happens after addSPSParams() has been called, the rows will be there when we retry the operation in the user transaction since we commit the nested transaction instead of aborting it. I think we can't abort the nested transaction because it will also abort the parent transaction, but perhaps it is possible to use savepoints to make sure that all the changes made by the nested transaction are rolled back before we retry.

          Show
          Knut Anders Hatlen added a comment - It is triggered when we try to add rows to SYS.SYSCOLUMNS in DataDictionaryImpl.updateSPS(): if(firstCompilation) { /*beetle:5119, reason for doing add here instead of update *is with NOCOMPILE option of create statement/boot time SPS, *SPS statement is not compiled to find out the parameter info. *Because of the parameter info was not inserted at SPSDescriptor *creation time. As this is the first time we are compiling paramter *infor should be inserted instead of the update. */ addSPSParams(spsd, tc); } For some reason the rows already exist, even though the meta-data statement has not been compiled before. I'm wondering if this is related to the retry logic in SPSDescriptor.getPreparedStatement(boolean): // DERBY-2584 : If the first attempt to compile the query fails, // we need to reset initiallyCompilable to make sure the // prepared plan is fully stored to disk. Save the initial // value here. final boolean compilable = initiallyCompilable; try { prepareAndRelease(lcc, null, nestedTC); updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC); } catch (StandardException se) { if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT)) { if (nestedTC != null) { nestedTC.commit(); nestedTC.destroy(); nestedTC = null; } // if we couldn't do this with a nested xaction, retry with // parent-- we need to wait this time! initiallyCompilable = compilable; prepareAndRelease(lcc, null, null); updateSYSSTATEMENTS(lcc, RECOMPILE, null); } else throw se; } If the lock timeout in the nested transaction happens after addSPSParams() has been called, the rows will be there when we retry the operation in the user transaction since we commit the nested transaction instead of aborting it. I think we can't abort the nested transaction because it will also abort the parent transaction, but perhaps it is possible to use savepoints to make sure that all the changes made by the nested transaction are rolled back before we retry.
          Hide
          Knut Anders Hatlen added a comment -

          If this is easily reproducible for you, could you try to run with -Dderby.locks.deadlockTrace=true and see if you get a lock timeout?

          Show
          Knut Anders Hatlen added a comment - If this is easily reproducible for you, could you try to run with -Dderby.locks.deadlockTrace=true and see if you get a lock timeout?
          Hide
          ArtemGr added a comment -

          I did run with
          System.setProperty ("derby.locks.deadlockTrace", "true")

          what should I look for?

          Here is my log (widh deadlockTrace enabled):
          http://chicago045.server4you.de/derby.log

          Show
          ArtemGr added a comment - I did run with System.setProperty ("derby.locks.deadlockTrace", "true") what should I look for? Here is my log (widh deadlockTrace enabled): http://chicago045.server4you.de/derby.log
          Hide
          Knut Anders Hatlen added a comment -

          I was suspecting that we'd see a lock timeout, but I didn't find any in the log. Did you run with a fresh database or with one where you'd seen the error before? Did you set the property before the Derby driver was loaded?

          This last log shows that the error happened in getImportedKeys() so the problem does not seem to be limited to getIndexInfo().

          Show
          Knut Anders Hatlen added a comment - I was suspecting that we'd see a lock timeout, but I didn't find any in the log. Did you run with a fresh database or with one where you'd seen the error before? Did you set the property before the Derby driver was loaded? This last log shows that the error happened in getImportedKeys() so the problem does not seem to be limited to getIndexInfo().
          Hide
          ArtemGr added a comment - - edited

          > Did you run with a fresh database or with one where you'd seen the error before?
          Fresh one.
          On the first run with a fresh database DataNucleus creates the schemas. On the second run it checks them and runs into this error.
          > Did you set the property before the Derby driver was loaded?
          Yes.

          Show
          ArtemGr added a comment - - edited > Did you run with a fresh database or with one where you'd seen the error before? Fresh one. On the first run with a fresh database DataNucleus creates the schemas. On the second run it checks them and runs into this error. > Did you set the property before the Derby driver was loaded? Yes.
          Dag H. Wanvik made changes -
          Field Original Value New Value
          Issue & fix info [Existing Application Impact] [Release Note Needed]
          Hide
          Rick Hillegas added a comment -

          Triaged July 2, 2009: This does not seem to satify our definition of a crash. I don't see why a release note is needed.

          Show
          Rick Hillegas added a comment - Triaged July 2, 2009: This does not seem to satify our definition of a crash. I don't see why a release note is needed.
          Rick Hillegas made changes -
          Bug behavior facts [Crash]
          Urgency Normal
          Issue & fix info [Release Note Needed]
          Kathey Marsden made changes -
          Labels derby_triage10_5_2
          Hide
          Peter Jodeleit added a comment - - edited

          Got the same issue when changing the transaction isolation from READ_COMMITED to SERIALIZABLE.

          [EDIT]
          The issue does not show up all the time (twice of three runs of our integration test suite). Seems to be a timing issue because of incorrect synchronization.

          Show
          Peter Jodeleit added a comment - - edited Got the same issue when changing the transaction isolation from READ_COMMITED to SERIALIZABLE. [EDIT] The issue does not show up all the time (twice of three runs of our integration test suite). Seems to be a timing issue because of incorrect synchronization.
          Hide
          Dag H. Wanvik added a comment -

          Hi Peter, thanks for the update report. you wouldn't by any change have a repro you could post or let of of the devs use? It would increase your chances for getting this fixed.

          Show
          Dag H. Wanvik added a comment - Hi Peter, thanks for the update report. you wouldn't by any change have a repro you could post or let of of the devs use? It would increase your chances for getting this fixed.
          Hide
          Peter Jodeleit added a comment -

          Hi Dag,
          there seems to be a relation to bug DERBY-2584. I checked the log files of the weekend and the exception reported there seems similar [trace below].

          I could give you an outline of our integration test. It should be easy to extract a dedicated test from this, but i didn't tried yet (and i don't think i'll find time for this in the near future).
          What we do is:
          1) create a databases
          2) query the database meta data
          [3) create some table 4) perform some CRUD operations]
          5) Loop to step 1 for a few times

          As in DERBY-2584 if transaction isolation is READ_COMMITTED everything works as expected (bug did not show up for about 3 months with 10.8.2.2. or with 10.5.3.0 for more than two years, both with alomst daily execution of the test suite).

          This is the trace I got last friday:
          ERROR X0Y68: Column 'PARAM1' already exists.
          at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
          at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(Unknown Source)
          at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(Unknown Source)
          at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addSPSParams(Unknown Source)
          at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(Unknown Source)
          at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(Unknown Source)
          at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown Source)
          at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown Source)
          at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(Unknown Source)
          at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
          at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
          at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
          at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source)
          at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:306)
          at de.espirit.or.impl.generic.GenericTableSynchronizer.updateDB(GenericTableSynchronizer.java:120)
          at de.espirit.or.impl.generic.GenericSchemaSynchronizer.updateDB(GenericSchemaSynchronizer.java:145)
          at de.espirit.or.impl.schema.SchemaImpl.updateDBTables(SchemaImpl.java:409)
          at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:934)
          at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:77)
          at de.espirit.firstspirit.content.ContentManagerImpl$TemporalSessionHandler.syncSchemaWithDB(ContentManagerImpl.java:1310)

          This is the trace I got this weekend. As you can see, the call to "DatabaseMetaData.getColumns(..)" was successfull in this run. The only code change was an additional call to "DatabaseMetaData.getDatabaseProductName()" for logging.
          java.sql.SQLException: Java exception: '1: java.lang.ArrayIndexOutOfBoundsException'.
          at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
          at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
          at org.apache.derby.impl.jdbc.Util.javaException(Unknown Source)
          at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
          at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
          at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
          at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source)
          at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:313)
          ... 27 more
          Caused by: java.sql.SQLException: Java exception: '1: java.lang.ArrayIndexOutOfBoundsException'.
          at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
          at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
          ... 47 more
          Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
          at org.apache.derby.impl.sql.GenericParameterValueSet.initialize(Unknown Source)
          at org.apache.derby.impl.sql.execute.BaseActivation.setupActivation(Unknown Source)
          at org.apache.derby.impl.sql.GenericActivationHolder.<init>(Unknown Source)
          at org.apache.derby.impl.sql.GenericPreparedStatement.getActivation(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
          at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source)
          at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source)
          at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:313)
          at de.espirit.or.impl.generic.GenericTableSynchronizer.updateDB(GenericTableSynchronizer.java:121)
          at de.espirit.or.impl.generic.GenericSchemaSynchronizer.updateDB(GenericSchemaSynchronizer.java:145)
          at de.espirit.or.impl.schema.SchemaImpl.updateDBTables(SchemaImpl.java:409)
          at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:934)
          at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:77)
          at de.espirit.firstspirit.content.ContentManagerImpl$TemporalSessionHandler.syncSchemaWithDB(ContentManagerImpl.java:1310)

          I changed our code back to READ_COMMITTED now, perhaps I use the same workaround as in mentioned in DERBY-2584 (using READ_COMMITTED for database meta data operations and SERIALIZABLE for the rest).

          Show
          Peter Jodeleit added a comment - Hi Dag, there seems to be a relation to bug DERBY-2584 . I checked the log files of the weekend and the exception reported there seems similar [trace below] . I could give you an outline of our integration test. It should be easy to extract a dedicated test from this, but i didn't tried yet (and i don't think i'll find time for this in the near future). What we do is: 1) create a databases 2) query the database meta data [3) create some table 4) perform some CRUD operations] 5) Loop to step 1 for a few times As in DERBY-2584 if transaction isolation is READ_COMMITTED everything works as expected (bug did not show up for about 3 months with 10.8.2.2. or with 10.5.3.0 for more than two years, both with alomst daily execution of the test suite). This is the trace I got last friday: ERROR X0Y68: Column 'PARAM1' already exists. at org.apache.derby.iapi.error.StandardException.newException(Unknown Source) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(Unknown Source) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(Unknown Source) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addSPSParams(Unknown Source) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(Unknown Source) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(Unknown Source) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown Source) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown Source) at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(Unknown Source) at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source) at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source) at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source) at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source) at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:306) at de.espirit.or.impl.generic.GenericTableSynchronizer.updateDB(GenericTableSynchronizer.java:120) at de.espirit.or.impl.generic.GenericSchemaSynchronizer.updateDB(GenericSchemaSynchronizer.java:145) at de.espirit.or.impl.schema.SchemaImpl.updateDBTables(SchemaImpl.java:409) at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:934) at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:77) at de.espirit.firstspirit.content.ContentManagerImpl$TemporalSessionHandler.syncSchemaWithDB(ContentManagerImpl.java:1310) This is the trace I got this weekend. As you can see, the call to "DatabaseMetaData.getColumns(..)" was successfull in this run. The only code change was an additional call to "DatabaseMetaData.getDatabaseProductName()" for logging. java.sql.SQLException: Java exception: '1: java.lang.ArrayIndexOutOfBoundsException'. at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source) at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source) at org.apache.derby.impl.jdbc.Util.javaException(Unknown Source) at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source) at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source) at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source) at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source) at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source) at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:313) ... 27 more Caused by: java.sql.SQLException: Java exception: '1: java.lang.ArrayIndexOutOfBoundsException'. at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source) at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source) ... 47 more Caused by: java.lang.ArrayIndexOutOfBoundsException: 1 at org.apache.derby.impl.sql.GenericParameterValueSet.initialize(Unknown Source) at org.apache.derby.impl.sql.execute.BaseActivation.setupActivation(Unknown Source) at org.apache.derby.impl.sql.GenericActivationHolder.<init>(Unknown Source) at org.apache.derby.impl.sql.GenericPreparedStatement.getActivation(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source) at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source) at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source) at de.espirit.or.impl.generic.GenericTableSynchronizer.getColumns(GenericTableSynchronizer.java:313) at de.espirit.or.impl.generic.GenericTableSynchronizer.updateDB(GenericTableSynchronizer.java:121) at de.espirit.or.impl.generic.GenericSchemaSynchronizer.updateDB(GenericSchemaSynchronizer.java:145) at de.espirit.or.impl.schema.SchemaImpl.updateDBTables(SchemaImpl.java:409) at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:934) at de.espirit.or.impl.AbstractSessionHandler.syncSchemaWithDB(AbstractSessionHandler.java:77) at de.espirit.firstspirit.content.ContentManagerImpl$TemporalSessionHandler.syncSchemaWithDB(ContentManagerImpl.java:1310) I changed our code back to READ_COMMITTED now, perhaps I use the same workaround as in mentioned in DERBY-2584 (using READ_COMMITTED for database meta data operations and SERIALIZABLE for the rest).
          Gavin made changes -
          Workflow jira [ 12460833 ] Default workflow, editable Closed status [ 12799479 ]
          Hide
          Knut Anders Hatlen added a comment -

          The attached program (D4160.java) reliably reproduces the bug in my environment.

          java.sql.SQLException: Column 'PARAM1' already exists.
          	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:103)
          	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:288)
          	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:424)
          	at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:353)
          	at org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2396)
          	at org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:82)
          	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(EmbedPreparedStatement.java:152)
          	at org.apache.derby.impl.jdbc.EmbedPreparedStatement42.<init>(EmbedPreparedStatement42.java:41)
          	at org.apache.derby.jdbc.Driver42.newEmbedPreparedStatement(Driver42.java:59)
          	at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(EmbedConnection.java:2865)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(EmbedDatabaseMetaData.java:3791)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(EmbedDatabaseMetaData.java:3623)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(EmbedDatabaseMetaData.java:3674)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(EmbedDatabaseMetaData.java:3701)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetBestRowId(EmbedDatabaseMetaData.java:2160)
          	at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getBestRowIdentifier(EmbedDatabaseMetaData.java:2101)
          	at D4160$1.run(D4160.java:25)
          Caused by: java.sql.SQLException: Column 'PARAM1' already exists.
          	at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory.java:141)
          	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:73)
          	... 16 more
          Caused by: ERROR X0Y68: Column 'PARAM1' already exists.
          	at org.apache.derby.iapi.error.StandardException.newException(StandardException.java:265)
          	at org.apache.derby.iapi.error.StandardException.newException(StandardException.java:260)
          	at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(DataDictionaryImpl.java:2032)
          	at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(DataDictionaryImpl.java:2015)
          	at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addSPSParams(DataDictionaryImpl.java:4363)
          	at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(DataDictionaryImpl.java:4511)
          	at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(SPSDescriptor.java:1142)
          	at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:764)
          	at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:655)
          	at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(ExecSPSNode.java:167)
          	at org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:546)
          	at org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:99)
          	at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:1116)
          	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(EmbedPreparedStatement.java:134)
          	... 10 more
          
          Show
          Knut Anders Hatlen added a comment - The attached program (D4160.java) reliably reproduces the bug in my environment. java.sql.SQLException: Column 'PARAM1' already exists. at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:103) at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:288) at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:424) at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:353) at org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2396) at org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:82) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(EmbedPreparedStatement.java:152) at org.apache.derby.impl.jdbc.EmbedPreparedStatement42.<init>(EmbedPreparedStatement42.java:41) at org.apache.derby.jdbc.Driver42.newEmbedPreparedStatement(Driver42.java:59) at org.apache.derby.impl.jdbc.EmbedConnection.prepareMetaDataStatement(EmbedConnection.java:2865) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.prepareSPS(EmbedDatabaseMetaData.java:3791) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQueryUsingSystemTables(EmbedDatabaseMetaData.java:3623) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(EmbedDatabaseMetaData.java:3674) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getPreparedQuery(EmbedDatabaseMetaData.java:3701) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetBestRowId(EmbedDatabaseMetaData.java:2160) at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getBestRowIdentifier(EmbedDatabaseMetaData.java:2101) at D4160$1.run(D4160.java:25) Caused by: java.sql.SQLException: Column 'PARAM1' already exists. at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory.java:141) at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:73) ... 16 more Caused by: ERROR X0Y68: Column 'PARAM1' already exists. at org.apache.derby.iapi.error.StandardException.newException(StandardException.java:265) at org.apache.derby.iapi.error.StandardException.newException(StandardException.java:260) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(DataDictionaryImpl.java:2032) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(DataDictionaryImpl.java:2015) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addSPSParams(DataDictionaryImpl.java:4363) at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(DataDictionaryImpl.java:4511) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(SPSDescriptor.java:1142) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:764) at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(SPSDescriptor.java:655) at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(ExecSPSNode.java:167) at org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:546) at org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:99) at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:1116) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(EmbedPreparedStatement.java:134) ... 10 more
          Knut Anders Hatlen made changes -
          Attachment D4160.java [ 12629345 ]
          Hide
          Knut Anders Hatlen added a comment -

          On 15/Apr/09 I commented:

          If the lock timeout in the nested transaction happens after addSPSParams() has been called, the rows will be there when we retry the operation in the user transaction since we commit the nested transaction instead of aborting it. I think we can't abort the nested transaction because it will also abort the parent transaction, but perhaps it is possible to use savepoints to make sure that all the changes made by the nested transaction are rolled back before we retry.

          In the attached repro, it looks like that's indeed what's happening. There's a lock conflict that prevents the nested transaction from completing the creation of the SPS immediately, so it is retried in the parent transaction. But the nested transaction has already added rows for some of the parameters, so the retry in the parent transaction fails because it tries to insert duplicates.

          As already mentioned, aborting/rolling back the nested transaction before retrying will also cause the parent transaction to be aborted, so we cannot do that. It was suggested that we use savepoints instead. Unfortunately, savepoints are not supported in nested transactions, so that won't work either.

          One possible workaround might be to drop the added rows before retrying. I'm experimenting with adding

                  dropAllColumnDescriptors(uuid, tc);
          

          to the beginning of DataDictionaryImpl.addSPSParams(). That makes the repro stop failing. I'm running the regression test suite now to see if that change breaks something.

          Show
          Knut Anders Hatlen added a comment - On 15/Apr/09 I commented: If the lock timeout in the nested transaction happens after addSPSParams() has been called, the rows will be there when we retry the operation in the user transaction since we commit the nested transaction instead of aborting it. I think we can't abort the nested transaction because it will also abort the parent transaction, but perhaps it is possible to use savepoints to make sure that all the changes made by the nested transaction are rolled back before we retry. In the attached repro, it looks like that's indeed what's happening. There's a lock conflict that prevents the nested transaction from completing the creation of the SPS immediately, so it is retried in the parent transaction. But the nested transaction has already added rows for some of the parameters, so the retry in the parent transaction fails because it tries to insert duplicates. As already mentioned, aborting/rolling back the nested transaction before retrying will also cause the parent transaction to be aborted, so we cannot do that. It was suggested that we use savepoints instead. Unfortunately, savepoints are not supported in nested transactions, so that won't work either. One possible workaround might be to drop the added rows before retrying. I'm experimenting with adding dropAllColumnDescriptors(uuid, tc); to the beginning of DataDictionaryImpl.addSPSParams(). That makes the repro stop failing. I'm running the regression test suite now to see if that change breaks something.
          Knut Anders Hatlen made changes -
          Assignee Knut Anders Hatlen [ knutanders ]
          Knut Anders Hatlen made changes -
          Status Open [ 1 ] In Progress [ 3 ]
          Hide
          Knut Anders Hatlen added a comment -

          Actually, nested transactions do support savepoints. It was the more low-level internal transactions that didn't.

          Unfortunately, adding a savepoint at the beginning of the nested transaction and rolling back to the savepoint on error does not seem to fix the bug. That makes me wonder if the real problem here is not the lack of rollback before retrying, but rather that the other thread has compiled and stored the SPS when the current thread retries. If that's the problem (more debugging is needed to verify it), we may need logic to avoid the retry if it is the SPS has already been recompiled by someone else.

          Show
          Knut Anders Hatlen added a comment - Actually, nested transactions do support savepoints. It was the more low-level internal transactions that didn't. Unfortunately, adding a savepoint at the beginning of the nested transaction and rolling back to the savepoint on error does not seem to fix the bug. That makes me wonder if the real problem here is not the lack of rollback before retrying, but rather that the other thread has compiled and stored the SPS when the current thread retries. If that's the problem (more debugging is needed to verify it), we may need logic to avoid the retry if it is the SPS has already been recompiled by someone else.
          Knut Anders Hatlen made changes -
          Link This issue is related to DERBY-2584 [ DERBY-2584 ]
          Hide
          Knut Anders Hatlen added a comment -

          It looks like this is a race condition in the handling of the SYS.SYSSTATEMENTS.INITIALLY_COMPILABLE column. We have seen other race conditions in the handling of this column before, see for example DERBY-2584.

          The column tells whether a stored prepared statement is compiled when it's created, or if it has to be compiled later. In practice, this means it should be true for trigger statements, and false for meta-data statements (because meta-data statements are added to the database so early in the database creation or upgrade that there is no LanguageConnectionContext available yet, and they cannot be compiled).

          However, once a meta-data statement has been compiled, the value of the column is switched from false to true. So it doesn't actually tell whether the SPS was initially compilable, but rather whether it has been compiled at least once. This is used by DataDictionaryImpl.updateSPS() to decide whether it should update the existing SPS or create it from scratch.

          What happens in the repro, is: Two threads attempt to execute the same meta-data query. They both read the SPSDescriptor from the dictionary, and they both see that INITIALLY_COMPILABLE is false because the meta-data query has not been executed before. Both of them compile the query, and both of them try to store the SPS. Because of locking in the system tables, one of them has to wait for the other to complete before it goes ahead and stores it. Since it had previously seen that INITIALLY_COMPILABLE was false, it gets confused when it finds that the SPS is already in the database, and throws the above mentioned exception "ERROR X0Y68: Column 'PARAM1' already exists."

          I suppose we could add more logic to synchronize between the two threads to avoid the race condition. But I think the best solution would be to change the use of INITIALLY_COMPILABLE so that its value represents what its name suggests: whether or not the statement was initially compilable. Now, since this means INITIALLY_COMPILABLE won't change during the lifetime of the SPS, it also means that there won't be any race conditions when accessing it.

          This change means that DataDictionaryImpl.updateSPS() can no longer tell whether or not the SPS is already stored in the database based on that column. But that information is not strictly needed. It is currently used in order to decide whether the existing SPS should be updated or a new one created. We could instead change the code to always replace the existing one (that is, delete the existing one if one exists, and create a new one). This change will actually simplify this part of the code significantly, since we get a shared code path for the first compilation of an SPS and subsequent recompilations, whereas they currently have two separate code paths. Additionally, the redefinition of INITIALLY_COMPILABLE probably fixes DERBY-2584 as well, so that we can remove the current workaround that we have for that bug.

          Show
          Knut Anders Hatlen added a comment - It looks like this is a race condition in the handling of the SYS.SYSSTATEMENTS.INITIALLY_COMPILABLE column. We have seen other race conditions in the handling of this column before, see for example DERBY-2584 . The column tells whether a stored prepared statement is compiled when it's created, or if it has to be compiled later. In practice, this means it should be true for trigger statements, and false for meta-data statements (because meta-data statements are added to the database so early in the database creation or upgrade that there is no LanguageConnectionContext available yet, and they cannot be compiled). However, once a meta-data statement has been compiled, the value of the column is switched from false to true. So it doesn't actually tell whether the SPS was initially compilable, but rather whether it has been compiled at least once. This is used by DataDictionaryImpl.updateSPS() to decide whether it should update the existing SPS or create it from scratch. What happens in the repro, is: Two threads attempt to execute the same meta-data query. They both read the SPSDescriptor from the dictionary, and they both see that INITIALLY_COMPILABLE is false because the meta-data query has not been executed before. Both of them compile the query, and both of them try to store the SPS. Because of locking in the system tables, one of them has to wait for the other to complete before it goes ahead and stores it. Since it had previously seen that INITIALLY_COMPILABLE was false, it gets confused when it finds that the SPS is already in the database, and throws the above mentioned exception "ERROR X0Y68: Column 'PARAM1' already exists." I suppose we could add more logic to synchronize between the two threads to avoid the race condition. But I think the best solution would be to change the use of INITIALLY_COMPILABLE so that its value represents what its name suggests: whether or not the statement was initially compilable. Now, since this means INITIALLY_COMPILABLE won't change during the lifetime of the SPS, it also means that there won't be any race conditions when accessing it. This change means that DataDictionaryImpl.updateSPS() can no longer tell whether or not the SPS is already stored in the database based on that column. But that information is not strictly needed. It is currently used in order to decide whether the existing SPS should be updated or a new one created. We could instead change the code to always replace the existing one (that is, delete the existing one if one exists, and create a new one). This change will actually simplify this part of the code significantly, since we get a shared code path for the first compilation of an SPS and subsequent recompilations, whereas they currently have two separate code paths. Additionally, the redefinition of INITIALLY_COMPILABLE probably fixes DERBY-2584 as well, so that we can remove the current workaround that we have for that bug.
          Hide
          Knut Anders Hatlen added a comment -

          The attached patch, d4160-1a.diff, makes the following changes:

          • Use a savepoint to roll back the work done by the nested transaction if an error occurs. Although this wasn't what caused the problem (at least not in the repro), this sounds like the right thing to do.
          • Make DataDictionaryImpl.updateSPS() do exactly the same on the first compilation as it does on subsequent compilations. This way, we avoid the race condition since the threads that update the SPS don't need to know if it has been compiled before.
          • Remove the no longer needed workaround for DERBY-2584.
          • Add a test case to DatabaseMetaDataTest to verify the fix.

          The patch removes more code than it adds, so I think it also reduces code complexity and makes it easier to follow the logic.

          All regression tests ran cleanly with the patch.

          Show
          Knut Anders Hatlen added a comment - The attached patch, d4160-1a.diff, makes the following changes: Use a savepoint to roll back the work done by the nested transaction if an error occurs. Although this wasn't what caused the problem (at least not in the repro), this sounds like the right thing to do. Make DataDictionaryImpl.updateSPS() do exactly the same on the first compilation as it does on subsequent compilations. This way, we avoid the race condition since the threads that update the SPS don't need to know if it has been compiled before. Remove the no longer needed workaround for DERBY-2584 . Add a test case to DatabaseMetaDataTest to verify the fix. The patch removes more code than it adds, so I think it also reduces code complexity and makes it easier to follow the logic. All regression tests ran cleanly with the patch.
          Knut Anders Hatlen made changes -
          Attachment d4160-1a.diff [ 12630037 ]
          Knut Anders Hatlen made changes -
          Issue & fix info Patch Available [ 10102 ]
          Hide
          ASF subversion and git services added a comment -

          Commit 1570488 from Knut Anders Hatlen in branch 'code/trunk'
          [ https://svn.apache.org/r1570488 ]

          DERBY-4160: getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already exists."

          Use a shared code path for adding parameters to SYS.SYSCOLUMNS on the
          first compilation and subsequent compilations of a meta-data query.
          Previously, the first compilation took a different code path, but that
          caused problems if two threads compiled a meta-data query at the same
          time, and both threads thought they were first.

          Set a savepoint before attempting to write a stored prepared statement
          to the system tables in a nested transaction, and roll back to the
          savepoint if an error happens. This prevents partially stored prepared
          statements from lying around in the system tables after an error.

          Show
          ASF subversion and git services added a comment - Commit 1570488 from Knut Anders Hatlen in branch 'code/trunk' [ https://svn.apache.org/r1570488 ] DERBY-4160 : getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already exists." Use a shared code path for adding parameters to SYS.SYSCOLUMNS on the first compilation and subsequent compilations of a meta-data query. Previously, the first compilation took a different code path, but that caused problems if two threads compiled a meta-data query at the same time, and both threads thought they were first. Set a savepoint before attempting to write a stored prepared statement to the system tables in a nested transaction, and roll back to the savepoint if an error happens. This prevents partially stored prepared statements from lying around in the system tables after an error.
          Hide
          Knut Anders Hatlen added a comment -

          I think it is OK to backport this fix back to 10.5 (I'm not planning to port it that far back, though). Backporting it further is not safe in its current shape because of DERBY-1107 (fixed in 10.5). Meta-data SPSs created with the fix for this issue need to be dropped and recreated before they can be used by versions without the fix, otherwise the older version will get confused when it finds a compiled SPS whose INITIALLY_COMPILABLE column is still false. DERBY-1107 made Derby drop and recreate meta-data SPSs on all version changes, not only when upgrading across branches, so this should not be a problem on 10.5 and later.

          Show
          Knut Anders Hatlen added a comment - I think it is OK to backport this fix back to 10.5 (I'm not planning to port it that far back, though). Backporting it further is not safe in its current shape because of DERBY-1107 (fixed in 10.5). Meta-data SPSs created with the fix for this issue need to be dropped and recreated before they can be used by versions without the fix, otherwise the older version will get confused when it finds a compiled SPS whose INITIALLY_COMPILABLE column is still false. DERBY-1107 made Derby drop and recreate meta-data SPSs on all version changes, not only when upgrading across branches, so this should not be a problem on 10.5 and later.
          Knut Anders Hatlen made changes -
          Fix Version/s 10.11.0.0 [ 12324243 ]
          Issue & fix info Patch Available [ 10102 ]
          Hide
          ASF subversion and git services added a comment -

          Commit 1574389 from Knut Anders Hatlen in branch 'code/branches/10.10'
          [ https://svn.apache.org/r1574389 ]

          DERBY-4160: getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already exists."

          Merged revision 1570488 from trunk.

          Show
          ASF subversion and git services added a comment - Commit 1574389 from Knut Anders Hatlen in branch 'code/branches/10.10' [ https://svn.apache.org/r1574389 ] DERBY-4160 : getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already exists." Merged revision 1570488 from trunk.
          Knut Anders Hatlen made changes -
          Status In Progress [ 3 ] Resolved [ 5 ]
          Fix Version/s 10.10.1.4 [ 12324247 ]
          Resolution Fixed [ 1 ]
          Myrna van Lunteren made changes -
          Fix Version/s 10.10.2.0 [ 12326659 ]
          Fix Version/s 10.10.1.4 [ 12324247 ]
          Hide
          Myrna van Lunteren added a comment -

          bulk change to close all issues resolved but not closed and not changed since June 1, 2014.

          Show
          Myrna van Lunteren added a comment - bulk change to close all issues resolved but not closed and not changed since June 1, 2014.
          Myrna van Lunteren made changes -
          Status Resolved [ 5 ] Closed [ 6 ]

            People

            • Assignee:
              Knut Anders Hatlen
              Reporter:
              ArtemGr
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development