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

Dag H. Wanvik commented on DERBY-6623:
--------------------------------------

This time, the instability is in the method 
EmbedDatabaseMetaData#getBestRowIdentifier.  The table in question looks like 
this:

{code}
create table brit3 (i int not null unique, j int not null unique)  -- cf line 
3405 in DatabaseMetaDataTest
{code}
Now, the Javadoc for the DBMD method says:

 "Retrieves a description of a table's optimal set of columns that uniquely 
identifies a row. They are ordered by SCOPE. "

In "metadata.properties" I see this internal query for this method:

{code}
getBestRowIdentifierUniqueConstraint=\
        SELECT CONS.CONSTRAINTID, IDX.DESCRIPTOR.numberOfOrderedColumns() AS 
NUMCOLS \
        FROM SYS.SYSSCHEMAS SCHEMAS, SYS.SYSTABLES TABS, \
                SYS.SYSCONSTRAINTS cons, SYS.SYSKEYS keys, SYS.SYSCONGLOMERATES 
IDX \
        WHERE TABS.TABLEID = conS.TABLEID AND SCHEMAS.SCHEMAID = TABS.SCHEMAID \
                AND conS.CONSTRAINTID = KEYS.CONSTRAINTID AND IDX.DESCRIPTOR IS 
NOT NULL \
                AND KEYS.CONGLOMERATEID = IDX.CONGLOMERATEID AND 
IDX.ISCONSTRAINT \
                AND conS.type = 'U' \
                AND ((1=1) OR ? IS NOT NULL) \
                AND (SCHEMAS.SCHEMANAME LIKE ?) \
                AND (TABS.TABLENAME=?) \
        ORDER BY NUMCOLS
{code}

Now, in this case, the table has two columns which both are declared as UNIQUE 
NOT NULL and the query returns both, but it does not specify an order between 
them.

The code that analyzes the query (EmbedDatabaseeMetaData#doGetBestRowId) has 
this section:

{code}
// see if there is a primary key, use it.
ps = getPreparedQuery("getBestRowIdentifierPrimaryKey");

:   (not the case here, so we proceed to look at unique columns)
// get the unique constraint with the fewest columns.
ps = getPreparedQuery("getBestRowIdentifierUniqueConstraint");
ps.setString(1,catalogPattern);
ps.setString(2,schemaPattern);
ps.setString(3,table);

rs = ps.executeQuery();
done = rs.next();
if (done) {
    constraintId = rs.getString(1);
}
{code}

As can be seen, once a row is read, that row is used. The test asserts it to be 
"J", but in the failing regression it was in fact "I", which is allowed since 
no ordering is specified on which constraint to return first. I presume what 
happened was that another query plan was used which gave the rows in the 
opposite order, causing the assert error.

Both unique constraints are equally good here, so which should be returned?  
Both? The API Javadoc doesn't really address this scenario, nor does the Derby 
code.
 



> DatabaseMetaDataTest fails intermittently
> -----------------------------------------
>
>                 Key: DERBY-6623
>                 URL: https://issues.apache.org/jira/browse/DERBY-6623
>             Project: Derby
>          Issue Type: Bug
>          Components: Test
>            Reporter: Dag H. Wanvik
>            Assignee: Dag H. Wanvik
>             Fix For: 10.11.0.0
>
>         Attachments: derby-6623.diff
>
>
> Saw this on the trunk 
> [[http://download.java.net/javadesktop/derby/request_5592737/javadb-task-3883745.html][regression
>  tests]]:
> testGetXXportedKeys:
> {code}
> junit.framework.AssertionFailedError: Column value mismatch @ column 
> 'FK_NAME', row 3:
>     Expected: >FKEY3<
>     Found:    >FKEY2<
>       at 
> org.apache.derbyTesting.junit.JDBC.assertRowInResultSet(JDBC.java:1303)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertRowInResultSet(JDBC.java:1215)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSetMinion(JDBC.java:1102)
>       at 
> org.apache.derbyTesting.junit.JDBC.assertFullResultSet(JDBC.java:1025)
>       at org.apache.derbyTesting.junit.JDBC.assertFullResultSet(JDBC.java:982)
>       at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.DatabaseMetaDataTest.assertFullResultSet(DatabaseMetaDataTest.java:3930)
>       at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.DatabaseMetaDataTest.testGetXXportedKeys(DatabaseMetaDataTest.java:4117)
>       at 
> org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:118)
>       at 
> org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:440)
>       at 
> org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:457)
> {code}



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to