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 dj...@apache.org on 2006/02/03 16:52:30 UTC

svn commit: r374696 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/tests/largedata/

Author: djd
Date: Fri Feb  3 07:52:26 2006
New Revision: 374696

URL: http://svn.apache.org/viewcvs?rev=374696&view=rev
Log:
DERBY-856 modify EmbedPreparedStatement.setCharacterStreamInternal to take a long
for the length, and perform the > max int check in the method.

Contributed by V.Narayanan <V....@Sun.COM>

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LobLimits.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimits.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java?rev=374696&r1=374695&r2=374696&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java Fri Feb  3 07:52:26 2006
@@ -611,33 +611,44 @@
 	}
 
     protected void setCharacterStreamInternal(int parameterIndex,
-						Reader reader, int length)
+						Reader reader, long length)
 	    throws SQLException
 	{
-        // currently the max number of chars that can be inserted
-        // into a clob field is Integer.MAX_INT ( 2Gb -1)
-        // setClob or setCharacterStream interfaces will eventually call 
-        // this method and in setClob, a long is casted to an int; hence
         // check for -ve length
         if (length < 0) 
           throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
       
-		checkStatus();
+        checkStatus();
 
-		int jdbcTypeId = getParameterJDBCType(parameterIndex);
-	    
-		    
-        if (reader == null)
-        {
-            setNull(parameterIndex, jdbcTypeId);
-            return;
+	    int jdbcTypeId = getParameterJDBCType(parameterIndex);
+
+
+        if (reader == null)  {
+             setNull(parameterIndex, jdbcTypeId);
+             return;
         }
 
-		try {
+        /*
+           The value stored should not exceed the maximum value that can be 
+           stored in an integer 
+           This checking needs to be done because currently derby does not
+           support Clob sizes greater than 2G-1 
+        */
+   	    if (length > Integer.MAX_VALUE)
+               throw newSQLException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
+                  preparedStatement.getParameterTypes()
+                  [parameterIndex-1].getSQLstring());
+        /*
+            We cast the length from long to int. This would'nt be appropriate if
+            the limit of 2G-1 is decided to be increased at a later stage. 
+        */
+        int intLength = (int)length;		    
+
+	    try {
            
             LimitReader limitIn = new LimitReader(reader);
 			ParameterValueSet pvs = getParms();
-            int usableLength = length;
+            int usableLength = intLength;
             ReaderToUTF8Stream utfIn = null;
 
             // Currently long varchar does not allow for truncation of trailing
@@ -662,19 +673,21 @@
                 // usableLength is the length of the data from stream that can
                 // be inserted which is min(colWidth,length) provided 
                 // length - colWidth has trailing blanks only
-                if (colWidth < length)
+                // we have used intLength into which the length variable had
+                // been cast to an int and stored  
+                if (colWidth < intLength)
                     usableLength = colWidth;
                 
                 // keep information with the stream about how much data needs 
                 // to be truncated, and colWidth info to give proper truncation
                 // message
                 utfIn = new ReaderToUTF8Stream(
-                            limitIn, colWidth, length - usableLength);
+                            limitIn, colWidth, intLength - usableLength);
             }
             else
             {
                 utfIn = new ReaderToUTF8Stream(
-                            limitIn,usableLength,length - usableLength);
+                            limitIn,usableLength,intLength - usableLength);
             }
 
             limitIn.setLimit(usableLength);
@@ -1225,7 +1238,7 @@
             // stream using x.getCharacterStream() because EmbedClob.length()
             // will read from the stream and drain the stream. 
             // Hence the need to declare this local variable - streamLength
-            int streamLength = (int) x.length();
+            long streamLength = x.length();
 
             setCharacterStreamInternal(i, x.getCharacterStream(), streamLength);
         }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LobLimits.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LobLimits.out?rev=374696&r1=374695&r2=374696&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LobLimits.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LobLimits.out Fri Feb  3 07:52:26 2006
@@ -80,6 +80,12 @@
 ========================================
 Rows deleted =2
 ========================================
+START ClobTest #13 (setClob with 4Gb clobinsertClob of size = 4294967296
+ Rows inserted with clob of size (4294967296) =0
+========================================
+DERBY DOES NOT SUPPORT INSERT OF 4GB CLOB 
+EXPECTED SQL Exception: (22003) The resulting value is outside the range for the data type CLOB(2147483647).
+========================================
 START BlobTest #1insertBlob of size = 2147483647
  Rows inserted with blob of size (2147483647) =2
 ========================================

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimits.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimits.java?rev=374696&r1=374695&r2=374696&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimits.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimits.java Fri Feb  3 07:52:26 2006
@@ -403,6 +403,23 @@
 
        deleteTable(conn, deleteClob, 2);
        
+       // Negative tests use the setClob API to insert a 4GB clob
+
+       long _4GB =  4*1024*1024*(1024L);
+
+       ClobImpl _4GBClob = new ClobImpl(new RandomCharReader(new java.util.Random(),_4GB),_4GB);		
+
+       try
+       {
+           insertClob_SetClob("ClobTest #13 (setClob with 4Gb clob",conn,insertClob,_4GBClob,
+                   _4GB,0,1,0);
+       }
+       catch(SQLException sqle)
+       {
+           System.out.println("DERBY DOES NOT SUPPORT INSERT OF 4GB CLOB ");
+           expectedException(sqle);
+       }
+
        // ADD NEW TESTS HERE
    }
 
@@ -914,6 +931,59 @@
 
    }
 
+  /**
+    * insert clob, using a setClob api.
+    * @param cloblen
+    *            length of clob to insert
+    * @param clob
+    *            clob to insert
+    * @param start
+    *            start id value for insert
+    * @param rows
+    *            insert rows number of rows
+    * @param expectedRows
+    *            rows expected to be inserted
+   */
+    private static void insertClob_SetClob(String testId, Connection conn,
+            PreparedStatement ps, java.sql.Clob clob, long cloblen, int start,
+            int rows, int expectedRows) throws SQLException {
+        System.out.println("========================================");
+        System.out.println("START " + testId + "insertClob of size = "
+                + cloblen);
+        long ST = 0;
+        if (trace)
+           ST = System.currentTimeMillis();
+        int count = 0;
+
+        try {
+            
+            for (int i = start; i < start + rows; i++) {
+                ps.setInt(1, i);
+                ps.setInt(2, 0);
+                ps.setLong(3, cloblen);
+                ps.setClob(4, clob);
+                count += ps.executeUpdate();
+            }
+            conn.commit();
+            if (trace) {
+                System.out.println("Insert Clob (" + cloblen + ")" + " rows= "
+                        + count + " = "
+                        + (long) (System.currentTimeMillis() - ST));
+
+            }
+        } catch (SQLException e) {
+            verifyTest(count, expectedRows,
+                    " Rows inserted with clob of size (" + cloblen + ") =");
+            System.out.println("========================================");
+            throw e;
+        }
+
+        verifyTest(count, expectedRows,
+                " Rows inserted with clob of size (" + cloblen + ") =");
+        System.out.println("========================================");
+
+    }
+
    /**
     * select from clob table
     * @param cloblen  select expects to retrieve a clob of this length
@@ -1340,18 +1410,18 @@
  * Class to generate random char data, generates 1,2,3bytes character.
  */
 class RandomCharReader extends java.io.Reader {
-   private int length;
-   private int numTrailingSpaces;
+   private long length;
+   private long numTrailingSpaces;
 
    private java.util.Random dpr;
 
-   RandomCharReader(java.util.Random dpr, int length) {
+   RandomCharReader(java.util.Random dpr, long length) {
        this.length = length;
        this.dpr = dpr;
        this.numTrailingSpaces = 0;
    }
 
-   RandomCharReader(java.util.Random dpr, int length,int numTrailingSpaces) {
+   RandomCharReader(java.util.Random dpr, long length,long numTrailingSpaces) {
        this.length = length;
        this.dpr = dpr;
        this.numTrailingSpaces = numTrailingSpaces;
@@ -1459,7 +1529,7 @@
            return -1;
 
        if (len > length)
-           len = length;
+           len = (int)length;
 
        for (int i = 0; i < len; i++) {
            data[off + i] = getChar();
@@ -1474,6 +1544,75 @@
    }
 }
 
+/**
+ * Class used to simulate a 4GB Clob implementation to 
+ * check whether derby implements such large Clobs correctly.
+ * Derby throws an error if the clob size exceeds 2GB
+ **/
+
+class ClobImpl implements java.sql.Clob {
+  long length;
+  Reader myReader;
+ 
+  public ClobImpl(Reader myReader,long length) {
+      this.length = length;
+      this.myReader = myReader;
+  }
+
+  public long length() throws SQLException {
+      return length;
+  }
+
+  public String getSubString(long pos, int length) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public java.io.Reader getCharacterStream() throws SQLException {
+      return myReader;
+  }
+
+  public java.io.InputStream getAsciiStream() throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public long position(String searchstr, long start) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public long position(Clob searchstr, long start) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public int setString(long pos, String str) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public int setString(long pos, String str, int offset, int len) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public java.io.OutputStream setAsciiStream(long pos) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public java.io.Writer setCharacterStream(long pos) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public void truncate(long len) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public void free() throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+  public Reader getCharacterStream(long pos, long length) throws SQLException {
+      throw new SQLException("Not implemented");
+  }
+
+}
+
 /***
  * Class to simulate a 4Gb blob impl in order to test if Derby
  * handles such large blobs correctly. The main methods here are
@@ -1553,4 +1692,3 @@
     }
     
 }
-