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 @@
}
}
-