[ 
https://issues.apache.org/jira/browse/DERBY-4160?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12699162#action_12699162
 ] 

Knut Anders Hatlen commented on DERBY-4160:
-------------------------------------------

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.

> getMetaData().getIndexInfo crashes with "ERROR X0Y68: Column 'PARAM1' already 
> exists."
> --------------------------------------------------------------------------------------
>
>                 Key: DERBY-4160
>                 URL: https://issues.apache.org/jira/browse/DERBY-4160
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.4.2.0
>         Environment: FreeBSD java 1.6.0, 64-Bit Server VM; DataNucleus JDO
>            Reporter: ArtemGr
>
> 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

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to