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

Rick Hillegas commented on DERBY-6670:
--------------------------------------

Since calling database procedures causes Derby to create an internal savepoint, 
this problem can also be caused by dropping the table inside a dbproc and then 
raising an exception. To see this, first compile the following class…

{noformat}
import java.sql.*;

public class zz
{
    public  static  void    dropTable( String tableName )
        throws SQLException
    {
        Connection  conn = DriverManager.getConnection( 
"jdbc:default:connection" );

        conn.prepareStatement( "drop table " + tableName ).execute();

        throw new SQLException( "Oh sorry, an error occurred." );
    }
}
{noformat}

…then run the following script…

{noformat}
connect 'jdbc:derby:memory:db;create=true';

create procedure dropTable( tableName varchar( 128 ) )
language java parameter style java modifies sql data
external name 'zz.dropTable';

create table t( a int primary key initially deferred );

autocommit off;

insert into t( a ) values ( 1 ), ( 1 );

call dropTable( 'T' );

commit;

-- table has duplicate primary key values
select * from t;
{noformat}


> Rollback to savepoint allows violation of deferrable constraints
> ----------------------------------------------------------------
>
>                 Key: DERBY-6670
>                 URL: https://issues.apache.org/jira/browse/DERBY-6670
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.11.0.0
>            Reporter: Knut Anders Hatlen
>
> The bug is illustrated by the following code snippet:
> {code}
>         Connection c = 
> DriverManager.getConnection("jdbc:derby:memory:db;create=true");
>         c.setAutoCommit(false);
>         Statement s = c.createStatement();
>         s.execute("create table t1(x int primary key initially deferred)");
>         s.execute("insert into t1 values 1,1,1,1");
>         Savepoint sp = c.setSavepoint();
>         s.execute("drop table t1");
>         c.rollback(sp);
>         // Since there are four identical rows in T1, this call should have
>         // failed because the primary key was violated.
>         c.commit();
>         // Instead, it succeeds, and all four rows are committed, as can
>         // be seen here:
>         ResultSet rs = s.executeQuery("select * from t1");
>         while (rs.next()) {
>             System.out.println(rs.getInt(1));
>         }
>         // Insert yet another row, so that we have five identical rows ...
>         s.execute("insert into t1 values 1");
>         // ... and now commit complains ...
>         c.commit();
> {code}
> With auto-commit off, add duplicates into a deferred primary key. Then set a 
> savepoint, drop the table, and roll back to the savepoint.
> Apparently, when you drop the table, information about any constraint 
> violations seen on that table is lost, and that information is not restored 
> when the drop table operation is undone by the rollback to savepoint.
> So when you commit the transaction after having rolled back the drop 
> operation, no deferred checking of constraints happens, and the duplicates 
> you have inserted are committed.



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

Reply via email to