You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2005/10/31 05:33:46 UTC

svn commit: r329733 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/impl/store/raw/data/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/functio...

Author: mikem
Date: Sun Oct 30 20:33:42 2005
New Revision: 329733

URL: http://svn.apache.org/viewcvs?rev=329733&view=rev
Log:
merging fix for DERBY-662 from trunk to 10.1 codeline, which was committed
as svn 329494.

The change is an obvious fix to BaseDataFileFactory.java code which creates
a conglomerates container file name given it's conglomerate number.  This is
a simple hex conversion which was missing from one of the paths through the
code.

The path is almost never taken, but in the following circumstance during
redo crasch recovery this bug
could cause derby to delete the underlying file of a table.  The circumstances
are as follows:

1) The OS/filesystem must be case insensitive such that a request to delete
a file named C2080.dat would also remove c2080.dat. This is true in
windows default file systems, not true in unix/linux filesystems that
I am aware of.
2) The system must be shutdown not in a clean manner, such that a subsequent
access of the database causes a REDO recovery action of a drop table
statement. This means that a drop table statement must have happened
since the last checkpoint in the log file. Examples of things that cause
checkpoints are:
o clean shutdown from ij using the "exit" command
o clean shutdown of database using the "shutdown=true" url
o calling the checkpoint system procedure
o generating enough log activity to cause a regularly scheduled checkpoint.
3) If the conglomerate number of the above described drop table is TABLE_1,
then for a problem to occur there must also exist in the database a table
such that it's HEX(TABLE_2) = TABLE_1
4) Either TABLE_2 must not be accessed during REDO prior to the REDO operation
of the drop of TABLE_1 or there must be enough other table references during
the REDO phase to push the caching of of the open of TABLE_2 out of cache.

The fix adds a test case which before the fix will force a container not
found error on an existing table.


Added:
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dropcrash.out
      - copied unchanged from r329494, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dropcrash.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dropcrash2.out
      - copied unchanged from r329494, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dropcrash2.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/dropcrash.java
      - copied unchanged from r329494, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/dropcrash.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/dropcrash2.java
      - copied unchanged from r329494, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/dropcrash2.java
Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java?rev=329733&r1=329732&r2=329733&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java Sun Oct 30 20:33:42 2005
@@ -2223,7 +2223,7 @@
             else
             {
                 sb.append(stub ? 'D' : 'C');
-                sb.append(containerId.getContainerId());
+                sb.append(Long.toHexString(containerId.getContainerId()));
                 sb.append(".DAT");
             }
             return storageFactory.newStorageFile( sb.toString());

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall?rev=329733&r1=329732&r2=329733&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storerecovery.runall Sun Oct 30 20:33:42 2005
@@ -1,9 +1,11 @@
-store/LogChecksumSetup.java
-store/LogChecksumRecovery.java
-store/LogChecksumRecovery1.java
-store/MaxLogNumber.java
-store/MaxLogNumberRecovery.java
-store/oc_rec1.java
-store/oc_rec2.java
-store/oc_rec3.java
-store/oc_rec4.java
+store/LogChecksumSetup.java
+store/LogChecksumRecovery.java
+store/LogChecksumRecovery1.java
+store/MaxLogNumber.java
+store/MaxLogNumberRecovery.java
+store/oc_rec1.java
+store/oc_rec2.java
+store/oc_rec3.java
+store/oc_rec4.java
+store/dropcrash.java
+store/dropcrash2.java

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java?rev=329733&r1=329732&r2=329733&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/BaseTest.java Sun Oct 30 20:33:42 2005
@@ -1,316 +1,360 @@
-/*
-
-   Derby - Class org.apache.derbyTesting.functionTests.harness.procedure
-
-   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-*/
-
-package org.apache.derbyTesting.functionTests.tests.store;
-
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-import org.apache.derby.tools.ij;
-
-import java.sql.Connection;
-import java.sql.Statement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-
-
-/**
-Common utility functions that can be shared across store .java tests.
-<p>
-If more than one store tests wants a function, put it here rather than copy
-it.  Hopefully going forward, with enough utility functions adding new store
-tests will be easier.  New store tests should extend this test to pick
-up access to utility routines - see OnlineCompressTest.java as an example.
-
-**/
-public abstract class BaseTest
-{
-    private static boolean debug_system_procedures_created = false;
-
-    abstract void testList(Connection conn) throws SQLException;
-
-    void runTests(String[] argv)
-        throws Throwable
-    {
-   		ij.getPropertyArg(argv); 
-        Connection conn = ij.startJBMS();
-        System.out.println("conn from ij.startJBMS() = " + conn);
-        conn.setAutoCommit(false);
-
-        try
-        {
-            testList(conn);
-        }
-        catch (SQLException sqle)
-        {
-			org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
-                System.out, sqle);
-			sqle.printStackTrace(System.out);
-		}
-    }
-
-    public BaseTest()
-    {
-    }
-
-    protected void beginTest(
-    Connection  conn,
-    String      str)
-        throws SQLException
-    {
-        log("Beginning test: " + str);
-        conn.commit();
-    }
-
-    protected void testProgress(
-    String      str)
-        throws SQLException
-    {
-        log("Executing test: " + str);
-    }
-
-    protected void endTest(
-    Connection  conn,
-    String      str)
-        throws SQLException
-    {
-        conn.commit();
-        log("Ending test: " + str);
-    }
-
-    protected void log(String   str)
-    {
-        System.out.println(str);
-    }
-
-    protected void logError(String   str)
-    {
-        System.out.println("ERROR: " + str);
-    }
-
-    /**
-     * Simple wrapper to execute a sql string.
-     **/
-    public void executeQuery(
-    Connection  conn,
-    String      stmt_str,
-    boolean     commit_query)
-        throws SQLException
-    {
-        Statement stmt = conn.createStatement();
-        stmt.executeUpdate(stmt_str);
-        stmt.close();
-        if (commit_query)
-            conn.commit();
-    }
-
-    /**
-     * Call consistency checker on the table.
-     * <p>
-     **/
-    protected boolean checkConsistency(
-    Connection  conn,
-    String      schemaName,
-    String      tableName)
-		throws SQLException
-    {
-        Statement s = conn.createStatement();
-
-        ResultSet rs = 
-            s.executeQuery(
-                "values SYSCS_UTIL.SYSCS_CHECK_TABLE('" + 
-                schemaName + "', '" + 
-                tableName  + "')");
-
-        if (!rs.next())
-        {
-            if (SanityManager.DEBUG)
-            {
-                SanityManager.THROWASSERT("no value from values clause.");
-            }
-        }
-
-        boolean consistent = rs.getBoolean(1);
-
-        rs.close();
-
-        conn.commit();
-
-        return(consistent);
-    }
-
-    /**
-     * Create a system procedures to access SANE debug table routines.
-     * <p>
-     **/
-    protected void createDebugSystemProcedures(
-    Connection  conn)
-		throws SQLException
-    {
-        Statement s = conn.createStatement();
-        s.executeUpdate(
-            "CREATE FUNCTION D_CONGLOMID_PRINT(DBNAME VARCHAR(128), CONGLOMID INT) RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT EXTERNAL NAME 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid' LANGUAGE JAVA PARAMETER STYLE JAVA");
-        s.executeUpdate(
-            "CREATE FUNCTION DIAG_CONGLOMID(DBNAME VARCHAR(128), CONGLOMID INT) RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT EXTERNAL NAME 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid' LANGUAGE JAVA PARAMETER STYLE JAVA");
-        s.close();
-        conn.commit();
-
-        debug_system_procedures_created = true;
-    }
-
-    /**
-     * Return string with table information.
-     * <p>
-     * Dumps summary store information about the table, also dumps extra
-     * information about individual pages into the error log file.
-     **/
-    String dump_table(
-    Connection  conn,
-    String      schemaName,
-    String      tableName,
-    boolean     commit_transaction)
-		throws SQLException
-    {
-        if (!debug_system_procedures_created)
-            createDebugSystemProcedures(conn);
-
-        // run the following query:
-        //
-        // select
-        //     sys.systables.tablename,
-        //     sys.sysconglomerates.conglomeratenumber,
-        //     DIAG_CONGLOMID('wombat', conglomeratenumber)
-        // from sys.systables, sys.sysconglomerates
-        // where
-        //     sys.systables.tableid = sys.sysconglomerates.tableid and
-        //     sys.systables.schemaid = sys.sysconglomerates.schemaid and
-        //     sys.systables.tablename = tableName;
-        //
-        // TODO - really should join with schemaName too.
-
-        PreparedStatement ps = 
-            conn.prepareStatement(
-                "select sys.systables.tablename, sys.sysconglomerates.conglomeratenumber, DIAG_CONGLOMID('wombat', conglomeratenumber) from sys.systables, sys.sysconglomerates where sys.systables.tableid = sys.sysconglomerates.tableid and sys.systables.schemaid = sys.sysconglomerates.schemaid and sys.systables.tablename = ?");
-        ps.setString(1, tableName);
-        ResultSet rs = ps.executeQuery();
-
-        if (!rs.next())
-        {
-            if (SanityManager.DEBUG)
-            {
-                SanityManager.THROWASSERT("no value from values clause.");
-            }
-        }
-
-        String dump_table_info = rs.getString(3);
-
-        rs.close();
-
-        if (commit_transaction)
-            conn.commit();
-
-        return(dump_table_info);
-
-    }
-
-    /**
-     * Get lock table.
-     * <p>
-     * Returns a single string with a dump of the entire lock table.
-     * <p>
-     *
-	 * @return The lock table.
-     *
-     * @param conn                  The connection to use.
-     * @param include_system_locks  If true include non-user locks like those
-     *                              requested by background internal threads.
-     *
-     **/
-    protected String get_lock_info(
-    Connection  conn,
-    boolean     include_system_locks)
-		throws SQLException
-    {
-        // Run the following query to get the current locks in the system,
-        // toggling the "t.type='UserTransaction'" based on 
-        // include_system_locks input:
-        //
-        // select
-        //     cast(l.xid as char(8)) as xid,
-        //     cast(username as char(8)) as username,
-        //     cast(t.type as char(8)) as trantype,
-        //     cast(l.type as char(8)) as type,
-        //     cast(lockcount as char(3)) as cnt,
-        //     cast(mode as char(4)) as mode,
-        //     cast(tablename as char(12)) as tabname,
-        //     cast(lockname as char(10)) as lockname,
-        //     state,
-        //     status
-        // from
-        //     new org.apache.derby.diag.LockTable() l  
-        // right outer join new org.apache.derby.diag.TransactionTable() t
-        //     on l.xid = t.xid where l.tableType <> 'S' and 
-        //        t.type='UserTransaction'
-        // order by
-        //     tabname, type desc, mode, cnt, lockname;
-        String lock_query = 
-            "select cast(l.xid as char(8)) as xid, cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, cast(mode as char(4)) as mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from new org.apache.derby.diag.LockTable() l right outer join new org.apache.derby.diag.TransactionTable() t on l.xid = t.xid where l.tableType <> 'S' ";
-        if (!include_system_locks)
-            lock_query += "and t.type='UserTransaction' ";
-        
-        lock_query += "order by tabname, type desc, mode, cnt, lockname";
-
-        PreparedStatement ps = conn.prepareStatement(lock_query);
-
-        ResultSet rs = ps.executeQuery();
-
-        String lock_output = 
-        "xid     |username|trantype|type    |cnt|mode|tabname     |lockname  |state|status\n" +
-        "---------------------------------------------------------------------------------\n";
-        while (rs.next())
-        {
-            String username     = rs.getString(1);
-            String trantype     = rs.getString(2);
-            String type         = rs.getString(3);
-            String lockcount    = rs.getString(4);
-            String mode         = rs.getString(5);
-            String tabname      = rs.getString(6);
-            String lockname     = rs.getString(7);
-            String state        = rs.getString(8);
-            String status       = rs.getString(9);
-
-            lock_output +=
-                username + "|" +
-                trantype + "|" +
-                type     + "|" +
-                lockcount+ "|" +
-                mode     + "|" +
-                tabname  + "|" +
-                lockname + "|" +
-                state    + "|" +
-                status   + "\n";
-        }
-
-        rs.close();
-
-        return(lock_output);
-    }
-}
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.harness.procedure
+
+   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derbyTesting.functionTests.tests.store;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.tools.ij;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+
+
+/**
+Common utility functions that can be shared across store .java tests.
+<p>
+If more than one store tests wants a function, put it here rather than copy
+it.  Hopefully going forward, with enough utility functions adding new store
+tests will be easier.  New store tests should extend this test to pick
+up access to utility routines - see OnlineCompressTest.java as an example.
+
+**/
+public abstract class BaseTest
+{
+    private static boolean debug_system_procedures_created = false;
+
+    abstract void testList(Connection conn) throws SQLException;
+
+    void runTests(String[] argv)
+        throws Throwable
+    {
+   		ij.getPropertyArg(argv); 
+        Connection conn = ij.startJBMS();
+        System.out.println("conn from ij.startJBMS() = " + conn);
+        conn.setAutoCommit(false);
+
+        try
+        {
+            testList(conn);
+        }
+        catch (SQLException sqle)
+        {
+			org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
+                System.out, sqle);
+			sqle.printStackTrace(System.out);
+		}
+    }
+
+    public BaseTest()
+    {
+    }
+
+    protected void beginTest(
+    Connection  conn,
+    String      str)
+        throws SQLException
+    {
+        log("Beginning test: " + str);
+        conn.commit();
+    }
+
+    protected void testProgress(
+    String      str)
+        throws SQLException
+    {
+        log("Executing test: " + str);
+    }
+
+    protected void endTest(
+    Connection  conn,
+    String      str)
+        throws SQLException
+    {
+        conn.commit();
+        log("Ending test: " + str);
+    }
+
+    protected void log(String   str)
+    {
+        System.out.println(str);
+    }
+
+    protected void logError(String   str)
+    {
+        System.out.println("ERROR: " + str);
+    }
+
+    /**
+     * Simple wrapper to execute a sql string.
+     **/
+    public void executeQuery(
+    Connection  conn,
+    String      stmt_str,
+    boolean     commit_query)
+        throws SQLException
+    {
+        Statement stmt = conn.createStatement();
+        stmt.executeUpdate(stmt_str);
+        stmt.close();
+        if (commit_query)
+            conn.commit();
+    }
+
+    /**
+     * Call consistency checker on the table.
+     * <p>
+     **/
+    protected boolean checkConsistency(
+    Connection  conn,
+    String      schemaName,
+    String      tableName)
+		throws SQLException
+    {
+        Statement s = conn.createStatement();
+
+        ResultSet rs = 
+            s.executeQuery(
+                "values SYSCS_UTIL.SYSCS_CHECK_TABLE('" + 
+                schemaName + "', '" + 
+                tableName  + "')");
+
+        if (!rs.next())
+        {
+            if (SanityManager.DEBUG)
+            {
+                SanityManager.THROWASSERT("no value from values clause.");
+            }
+        }
+
+        boolean consistent = rs.getBoolean(1);
+
+        rs.close();
+
+        conn.commit();
+
+        return(consistent);
+    }
+
+    /**
+     * Call consistency checker on all the tables.
+     * <p>
+     **/
+    protected boolean checkAllConsistency(
+    Connection  conn)
+		throws SQLException
+    {
+        Statement s = conn.createStatement();
+
+        ResultSet rs = 
+            s.executeQuery(
+                "select schemaname, tablename, SYSCS_UTIL.SYSCS_CHECK_TABLE(schemaname, tablename) " + 
+                "from sys.systables a,  sys.sysschemas b where a.schemaid = b.schemaid");
+
+        int table_count = 0;
+
+        while (rs.next())
+        {
+            table_count++;
+            if (rs.getInt(3) != 1)
+            {
+                System.out.println(
+                    "Bad return from consistency check of " + 
+                    rs.getString(1) + "." + rs.getString(2));
+            }
+        }
+
+        if (table_count < 5)
+        {
+            // there are at least 5 system catalogs.
+            System.out.println(
+                "Something wrong with consistency check query, found only " + 
+                table_count + " tables.");
+        }
+
+        rs.close();
+        s.close();
+
+        conn.commit();
+
+        return(true);
+    }
+
+    /**
+     * Create a system procedures to access SANE debug table routines.
+     * <p>
+     **/
+    protected void createDebugSystemProcedures(
+    Connection  conn)
+		throws SQLException
+    {
+        Statement s = conn.createStatement();
+        s.executeUpdate(
+            "CREATE FUNCTION D_CONGLOMID_PRINT(DBNAME VARCHAR(128), CONGLOMID INT) RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT EXTERNAL NAME 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid' LANGUAGE JAVA PARAMETER STYLE JAVA");
+        s.executeUpdate(
+            "CREATE FUNCTION DIAG_CONGLOMID(DBNAME VARCHAR(128), CONGLOMID INT) RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT EXTERNAL NAME 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid' LANGUAGE JAVA PARAMETER STYLE JAVA");
+        s.close();
+        conn.commit();
+
+        debug_system_procedures_created = true;
+    }
+
+    /**
+     * Return string with table information.
+     * <p>
+     * Dumps summary store information about the table, also dumps extra
+     * information about individual pages into the error log file.
+     **/
+    String dump_table(
+    Connection  conn,
+    String      schemaName,
+    String      tableName,
+    boolean     commit_transaction)
+		throws SQLException
+    {
+        if (!debug_system_procedures_created)
+            createDebugSystemProcedures(conn);
+
+        // run the following query:
+        //
+        // select
+        //     sys.systables.tablename,
+        //     sys.sysconglomerates.conglomeratenumber,
+        //     DIAG_CONGLOMID('wombat', conglomeratenumber)
+        // from sys.systables, sys.sysconglomerates
+        // where
+        //     sys.systables.tableid = sys.sysconglomerates.tableid and
+        //     sys.systables.schemaid = sys.sysconglomerates.schemaid and
+        //     sys.systables.tablename = tableName;
+        //
+        // TODO - really should join with schemaName too.
+
+        PreparedStatement ps = 
+            conn.prepareStatement(
+                "select sys.systables.tablename, sys.sysconglomerates.conglomeratenumber, DIAG_CONGLOMID('wombat', conglomeratenumber) from sys.systables, sys.sysconglomerates where sys.systables.tableid = sys.sysconglomerates.tableid and sys.systables.schemaid = sys.sysconglomerates.schemaid and sys.systables.tablename = ?");
+        ps.setString(1, tableName);
+        ResultSet rs = ps.executeQuery();
+
+        if (!rs.next())
+        {
+            if (SanityManager.DEBUG)
+            {
+                SanityManager.THROWASSERT("no value from values clause.");
+            }
+        }
+
+        String dump_table_info = rs.getString(3);
+
+        rs.close();
+
+        if (commit_transaction)
+            conn.commit();
+
+        return(dump_table_info);
+
+    }
+
+    /**
+     * Get lock table.
+     * <p>
+     * Returns a single string with a dump of the entire lock table.
+     * <p>
+     *
+	 * @return The lock table.
+     *
+     * @param conn                  The connection to use.
+     * @param include_system_locks  If true include non-user locks like those
+     *                              requested by background internal threads.
+     *
+     **/
+    protected String get_lock_info(
+    Connection  conn,
+    boolean     include_system_locks)
+		throws SQLException
+    {
+        // Run the following query to get the current locks in the system,
+        // toggling the "t.type='UserTransaction'" based on 
+        // include_system_locks input:
+        //
+        // select
+        //     cast(l.xid as char(8)) as xid,
+        //     cast(username as char(8)) as username,
+        //     cast(t.type as char(8)) as trantype,
+        //     cast(l.type as char(8)) as type,
+        //     cast(lockcount as char(3)) as cnt,
+        //     cast(mode as char(4)) as mode,
+        //     cast(tablename as char(12)) as tabname,
+        //     cast(lockname as char(10)) as lockname,
+        //     state,
+        //     status
+        // from
+        //     new org.apache.derby.diag.LockTable() l  
+        // right outer join new org.apache.derby.diag.TransactionTable() t
+        //     on l.xid = t.xid where l.tableType <> 'S' and 
+        //        t.type='UserTransaction'
+        // order by
+        //     tabname, type desc, mode, cnt, lockname;
+        String lock_query = 
+            "select cast(l.xid as char(8)) as xid, cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, cast(mode as char(4)) as mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from new org.apache.derby.diag.LockTable() l right outer join new org.apache.derby.diag.TransactionTable() t on l.xid = t.xid where l.tableType <> 'S' ";
+        if (!include_system_locks)
+            lock_query += "and t.type='UserTransaction' ";
+        
+        lock_query += "order by tabname, type desc, mode, cnt, lockname";
+
+        PreparedStatement ps = conn.prepareStatement(lock_query);
+
+        ResultSet rs = ps.executeQuery();
+
+        String lock_output = 
+        "xid     |username|trantype|type    |cnt|mode|tabname     |lockname  |state|status\n" +
+        "---------------------------------------------------------------------------------\n";
+        while (rs.next())
+        {
+            String username     = rs.getString(1);
+            String trantype     = rs.getString(2);
+            String type         = rs.getString(3);
+            String lockcount    = rs.getString(4);
+            String mode         = rs.getString(5);
+            String tabname      = rs.getString(6);
+            String lockname     = rs.getString(7);
+            String state        = rs.getString(8);
+            String status       = rs.getString(9);
+
+            lock_output +=
+                username + "|" +
+                trantype + "|" +
+                type     + "|" +
+                lockcount+ "|" +
+                mode     + "|" +
+                tabname  + "|" +
+                lockname + "|" +
+                state    + "|" +
+                status   + "\n";
+        }
+
+        rs.close();
+
+        return(lock_output);
+    }
+}