Hi There:

  I am seeing delete clob data from a table does not reclaim the disk space. 
The same behavior does not happen to blob. For Blob, after delete, the database 
size will decrease. However, for Clob, after delete, the database size remaind 
the same. If we check the compression space after delete clob using 
SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE, the size is smaller after delete clob 
rows. And, this is the same with blob.

   Is this a bug or expected behavior?

   I am attaching the repro for you to review.

   Note the output indicate the databaseSize() did not change after delete clob 
data from TAB table:
===========================
The database size: 11494963
delete rows from TAB
The database size: 11494963


      
import java.sql.*;
import java.io.*;
import org.apache.derby.tools.JDBCDisplayUtil;
import org.apache.derbyTesting.functionTests.util.streams.CharAlphabet;
import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader;
import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetStream;

public class TestInPlaceCompressWithPKViolation {

    public static void main(String[] args) throws Exception{
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
        Connection conn = 
DriverManager.getConnection("jdbc:derby:testdb;create=true");
        createTable(conn);
        PreparedStatement ps = conn.prepareStatement("INSERT INTO TAB 
VALUES(1,?)");
        int clobLength = 3000000;
        for (int i = 0; i < 5; i ++) {
            Reader streamReader = new LoopingAlphabetReader(clobLength,
                                                        
CharAlphabet.modernLatinLowercase());
            ps.setCharacterStream(1,streamReader,clobLength);
            try {
                ps.executeUpdate();
            } catch (SQLException se) {
                System.out.println(se.getMessage());
            }
        }
            //compressAndCheckSpaceTable(conn);
        System.out.println("The database size: " + databaseSize(new 
File("testdb")));
        //System.out.println("Call compressAndCheckSpaceTable again");
            //compressAndCheckSpaceTable(conn);
            Statement s2 = conn.createStatement();
            s2.executeUpdate("delete from TAB");
            s2.close();
            System.out.println("delete rows from TAB");
            System.out.println("The database size: " + databaseSize(new 
File("testdb")));
            //compressAndCheckSpaceTable(conn);
    }


    private static void createTable(Connection conn) throws SQLException {
        Statement s = conn.createStatement();
        try {
             s.executeUpdate("DROP TABLE TAB");
             } catch (SQLException se) {
             }
        s.executeUpdate("CREATE TABLE TAB (I INT PRIMARY KEY, C CLOB)");
        s.close();

    }
    
    private static void compressAndCheckSpaceTable(Connection conn) throws 
SQLException {
        Statement s = conn.createStatement();
        showSpaceTable("*****spaceTable before 
SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP','TAB',1,1,1)",conn);
        s.executeUpdate("call 
SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP','TAB',1,1,1)");
        showSpaceTable("*****spaceTable after 
SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP','TAB',1,1,1)",conn);
        s.executeUpdate("CALL SYSCS_UTIL.SYSCS_COMPRESS_TABLE('APP','TAB',1)");
        showSpaceTable("*****spaceTable after 
SYSCS_UTIL.SYSCS_COMPRESS_TABLE('APP','TAB',1)",conn);
        s.close();
        
    }

    private static void showSpaceTable(String label, Connection conn) throws 
SQLException{
        Statement s = conn.createStatement();
        System.out.println(label);
        ResultSet rs = s.executeQuery("select * from new 
org.apache.derby.diag.SpaceTable('APP','TAB') t WHERE CONGLOMERATENAME = 
'TAB'");
        PrintWriter out = new PrintWriter(System.out);
        JDBCDisplayUtil.DisplayResults(out,s, conn);
        out.flush();

    }

        private static long databaseSize(File dbname) {
            long length = 0;
            if (dbname.isDirectory()) {
                String[] children = dbname.list();
                for (int i=0; i<children.length; i++) 
                    length = length + databaseSize(new File(dbname, 
children[i]));
                return length;
            }
            else
                return dbname.length(); 
        }
}

Reply via email to