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 ka...@apache.org on 2006/10/25 13:52:06 UTC
svn commit: r467612 - in /db/derby/code/trunk/java:
drda/org/apache/derby/impl/drda/
testing/org/apache/derbyTesting/functionTests/master/
testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/
testing/org/apache/derbyTesting/functionTest...
Author: kahatlen
Date: Wed Oct 25 04:52:05 2006
New Revision: 467612
URL: http://svn.apache.org/viewvc?view=rev&rev=467612
Log:
DERBY-815: Prevent unneeded object creation and excessive decoding in
parseSQLDTA_work()
Patch contributed by Dyre Tjeldvoll.
Modified:
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Wed Oct 25 04:52:05 2006
@@ -4111,9 +4111,10 @@
PreparedStatement ps = stmt.getPreparedStatement();
int codePoint;
EngineParameterMetaData pmeta = null;
- Vector paramDrdaTypes = new Vector();
- Vector paramLens = new Vector();
- ArrayList paramExtPositions = null;
+
+ // Clear params without releasing storage
+ stmt.clearDrdaParams();
+
int numVars = 0;
boolean rtnParam = false;
@@ -4135,17 +4136,17 @@
reader.readByte(); // id
for (int j = 0; j < numVarsInGrp; j++)
{
- paramDrdaTypes.addElement(new Byte(reader.readByte()));
+ final byte t = reader.readByte();
if (SanityManager.DEBUG)
trace("drdaType is: "+ "0x" +
- Integer.toHexString(((Byte ) paramDrdaTypes.lastElement()).byteValue()));
+ Integer.toHexString(t));
int drdaLength = reader.readNetworkShort();
if (SanityManager.DEBUG)
trace("drdaLength is: "+drdaLength);
- paramLens.addElement(new Integer(drdaLength));
+ stmt.addDrdaParam(t, drdaLength);
}
}
- numVars = paramDrdaTypes.size();
+ numVars = stmt.getDrdaParamCount();
if (SanityManager.DEBUG)
trace("numVars = " + numVars);
if (ps == null) // it is a CallableStatement under construction
@@ -4197,7 +4198,7 @@
for (int i = 0; i < numVars; i++)
{
- if ((((Byte)paramDrdaTypes.elementAt(i)).byteValue() & 0x1) == 0x1) // nullable
+ if ((stmt.getParamDRDAType(i+1) & 0x1) == 0x1) // nullable
{
int nullData = reader.readUnsignedByte();
if ((nullData & 0xFF) == FdocaConstants.NULL_DATA)
@@ -4214,15 +4215,8 @@
}
// not null, read and set it
- paramExtPositions = readAndSetParams(i, stmt,
- ((Byte)paramDrdaTypes.elementAt(i)).byteValue(),
- pmeta,
- paramExtPositions,
- ((Integer)(paramLens.elementAt(i))).intValue());
+ readAndSetParams(i, stmt, pmeta);
}
- stmt.cliParamExtPositions = paramExtPositions;
- stmt.cliParamDrdaTypes = paramDrdaTypes;
- stmt.cliParamLens = paramLens;
break;
case CodePoint.EXTDTA:
readAndSetAllExtParams(stmt, false);
@@ -4244,27 +4238,25 @@
}
/**
- * Read different types of input parameters and set them in PreparedStatement
+ * Read different types of input parameters and set them in
+ * PreparedStatement
* @param i index of the parameter
- * @param stmt drda statement
- * @param drdaType drda type of the parameter
+ * @param stmt drda statement
* @param pmeta parameter meta data
- * @param paramExtPositions ArrayList of parameters with extdta
- * @param paramLenNumBytes Number of bytes for encoding LOB Length
*
- * @return updated paramExtPositions
* @throws DRDAProtocolException
* @throws SQLException
*/
- private ArrayList readAndSetParams(int i, DRDAStatement stmt, int
- drdaType, EngineParameterMetaData pmeta,
- ArrayList paramExtPositions,
- int paramLenNumBytes)
+ private void readAndSetParams(int i,
+ DRDAStatement stmt,
+ EngineParameterMetaData pmeta)
throws DRDAProtocolException, SQLException
{
PreparedStatement ps = stmt.getPreparedStatement();
+
// mask out null indicator
- drdaType = ((drdaType | 0x01) & 0x000000ff);
+ final int drdaType = ((stmt.getParamDRDAType(i+1) | 0x01) & 0xff);
+ final int paramLenNumBytes = stmt.getParamLen(i+1);
if (ps instanceof CallableStatement)
{
@@ -4425,9 +4417,7 @@
long length = readLobLength(paramLenNumBytes);
if (length != 0) //can be -1 for CLI if "data at exec" mode, see clifp/exec test
{
- if (paramExtPositions == null)
- paramExtPositions = new ArrayList();
- paramExtPositions.add(new Integer(i));
+ stmt.addExtPosition(i);
}
else /* empty */
{
@@ -4446,7 +4436,6 @@
ps.setObject(i+1, paramVal);
}
}
- return paramExtPositions;
}
private long readLobLength(int extLenIndicator)
@@ -4475,15 +4464,15 @@
private void readAndSetAllExtParams(final DRDAStatement stmt, final boolean streamLOB)
throws SQLException, DRDAProtocolException
{
- int numExt = stmt.cliParamExtPositions.size();
- for (int i = 0; i < stmt.cliParamExtPositions.size(); i++)
+ final int numExt = stmt.getExtPositionCount();
+ for (int i = 0; i < numExt; i++)
{
- int paramPos = ((Integer) (stmt.cliParamExtPositions).get(i)).intValue();
+ int paramPos = stmt.getExtPosition(i);
final boolean doStreamLOB = (streamLOB && i == numExt -1);
readAndSetExtParam(paramPos,
stmt,
- ((Byte)stmt.cliParamDrdaTypes.elementAt(paramPos)).intValue(),
- ((Integer)(stmt.cliParamLens.elementAt(paramPos))).intValue(),
+ stmt.getParamDRDAType(paramPos+1),
+ stmt.getParamLen(paramPos+1),
doStreamLOB);
// Each extdta in it's own dss
if (i < numExt -1)
@@ -6452,7 +6441,7 @@
else // it's for a CallableStatement
{
hasdata = stmt.hasOutputParams();
- numCols = stmt.getNumParams();
+ numCols = stmt.getDrdaParamCount();
}
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java Wed Oct 25 04:52:05 2006
@@ -35,6 +35,7 @@
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
+import java.lang.reflect.Array;
import org.apache.derby.iapi.jdbc.BrokeredConnection;
import org.apache.derby.iapi.jdbc.BrokeredPreparedStatement;
@@ -98,10 +99,130 @@
private ArrayList resultSetKeyList; // ordered list of hash keys
private int numResultSets = 0;
- // State for parameter data
- protected Vector cliParamDrdaTypes = new Vector();
- protected Vector cliParamLens = new Vector();
- protected ArrayList cliParamExtPositions = null;
+ /** This class is used to keep track of the statement's parameters
+ * as they are received from the client. It uses arrays to track
+ * the DRDA type, the length in bytes and the externalness of each
+ * parameter. Arrays of int/byte are used rather than ArrayLists
+ * of Integer/Byte in order to re-use the same storage each time
+ * the statement is executed. */
+ private static class DrdaParamState {
+ private int typeLstEnd_ = 0;
+ private byte[] typeLst_ = new byte[10];
+ private int[] lenLst_ = new int[10];
+ private int extLstEnd_ = 0;
+ private int[] extLst_ = new int[10];
+
+ private static Object growArray(Object array) {
+ final int oldLen = Array.getLength(array);
+ Object tmp =
+ Array.newInstance(array.getClass().getComponentType(),
+ Math.max(oldLen,1)*2);
+ System.arraycopy(array, 0, tmp, 0, oldLen);
+ return tmp;
+ }
+
+ /**
+ * <code>clear</code> resets the arrays so that new parameters
+ * will be added at the beginning. No initialization or
+ * releasing of storage takes place unless the trim argument
+ * is true.
+ *
+ * @param trim - if true; release excess storage
+ */
+ protected void clear(boolean trim) {
+ typeLstEnd_ = 0;
+ extLstEnd_ = 0;
+ if (trim && typeLst_.length > 10) {
+ typeLst_ = new byte[10];
+ lenLst_ = new int[10];
+ extLst_ = new int[10];
+ }
+ }
+
+ /**
+ * <code>addDrdaParam</code> adds a new parameter with its
+ * DRDA type and byte length. The arrays are automatically
+ * grown if needed.
+ *
+ * @param t a <code>byte</code> value, the DRDA type of the
+ * parameter being added
+ * @param s an <code>int</code> value, the length in bytes of
+ * the parameter being added
+ */
+ protected void addDrdaParam(byte t, int s) {
+ if (typeLstEnd_ >= typeLst_.length) {
+ typeLst_ = (byte[])growArray(typeLst_);
+ lenLst_ = (int[])growArray(lenLst_);
+ }
+ typeLst_[typeLstEnd_] = t;
+ lenLst_[typeLstEnd_] = s;
+ ++typeLstEnd_;
+ }
+
+ /**
+ * <code>getDrdaParamCount</code> return the number of
+ * parameters added so far (since last clear).
+ *
+ * @return an <code>int</code> value, the number of parameters
+ */
+ protected int getDrdaParamCount() { return typeLstEnd_; }
+
+ /**
+ * <code>getDrdaType</code> returns a byte that represents the
+ * DRDA type of the ith parameter.
+ *
+ * @param i an <code>int</code> value, a parameter position
+ * (zero-based)
+ * @return a <code>byte</code> value, the DRDA type
+ */
+ protected byte getDrdaType(int i) { return typeLst_[i]; }
+
+ /**
+ * <code>getDrdaLen</code> returns the length in bytes of the
+ * ith parameter.
+ *
+ * @param i an <code>int</code> value, a parameter position
+ * (zero-based)
+ * @return an <code>int</code> value
+ */
+ protected int getDrdaLen(int i) { return lenLst_[i]; }
+
+ /**
+ * <code>addExtPos</code> marks parameter i as external. The
+ * array is grown as needed.
+ *
+ * @param p an <code>int</code> value, a parameter position
+ * (zero-based)
+ */
+ protected void addExtPos(int p) {
+ if (extLstEnd_ >= extLst_.length) {
+ extLst_ = (int[])growArray(extLst_);
+ }
+ extLst_[extLstEnd_] = p;
+ ++extLstEnd_;
+ }
+
+ /**
+ * <code>getExtPosCount</code> returns the number of
+ * parameters marked as external so far (since last clear).
+ *
+ * @return an <code>int</code> value, the number of external
+ * parameters.
+ */
+ protected int getExtPosCount() { return extLstEnd_; }
+
+ /**
+ * <code>getExtPos</code> returns the actual parameter position
+ * of the ith external parameter.
+ *
+ * @param i an <code>int</code> value, index into the list of
+ * external parameters, zero-based
+ * @return an <code>int</code> value, the parameter position
+ * of the ith external parameter (zero-based)
+ */
+ protected int getExtPos(int i) { return extLst_[i]; }
+ }
+ private DrdaParamState drdaParamState_ = new DrdaParamState();
// Query options sent on EXCSQLSTT
// These the default for ResultSets created for this statement.
@@ -974,10 +1095,8 @@
rslsetflg = null;
procName = null;
outputTypes = null;
- cliParamDrdaTypes = null;
- cliParamLens = null;
- cliParamExtPositions = null;
-
+ // Clear parameters and release excess storage
+ drdaParamState_.clear(true);
}
/**
@@ -1015,9 +1134,8 @@
resultSetKeyList = null;
numResultSets = 0;
- cliParamDrdaTypes = new Vector();
- cliParamLens = new Vector();
- cliParamExtPositions = null;
+ // Clear parameters without releasing storage
+ drdaParamState_.clear(false);
nbrrow = 0;
qryrowset = 0;
@@ -1104,42 +1222,76 @@
}
-
- /**
- * get parameter DRDAType
- *
- * @param index - starting with 1
- * @return DRDA Type of column
+ /** Clears the parameter state (type, length and ext information)
+ * stored in this statement, but does not release any
+ * storage. This reduces the cost of re-executing the statement
+ * since no new storage needs to be allocated. */
+ protected void clearDrdaParams() {
+ drdaParamState_.clear(false);
+ }
+
+ /** Get the number of external parameters in this
+ * statement. External means parameters that are transmitted in a
+ * separate DSS in the DRDA protocol.
+ * @return the number of external parameters
*/
- protected int getParamDRDAType(int index)
- {
-
- return ((Byte)cliParamDrdaTypes.get(index -1)).intValue();
+ protected int getExtPositionCount() {
+ return drdaParamState_.getExtPosCount();
}
+ /** Get the parameter position of the i'th external parameter
+ * @param i - zero-based index into list of external parameters
+ * @return the parameter position of the i'th external parameter
+ */
+ protected int getExtPosition(int i) {
+ return drdaParamState_.getExtPos(i);
+ }
+
+ /** Mark the pos'th parameter as external
+ * @param pos - zero-based index into list of external parameters
+ */
+ protected void addExtPosition(int pos) {
+ drdaParamState_.addExtPos(pos);
+ }
+
+ /** Get the number of parameters, internal and external, that has
+ * been added to this statement.
+ * @return the number of parameters
+ */
+ protected int getDrdaParamCount() {
+ return drdaParamState_.getDrdaParamCount();
+ }
+
+ /** Add another parameter to this statement.
+ * @param t - type of the parameter
+ * @param l - length in bytes of the parameter
+ */
+ protected void addDrdaParam(byte t, int l) {
+ drdaParamState_.addDrdaParam(t, l);
+ }
/**
- * set param DRDAType
+ * get parameter DRDAType
*
* @param index - starting with 1
- * @param type
+ * @return DRDA Type of column
*/
- protected void setParamDRDAType(int index, byte type)
- {
- cliParamDrdaTypes.addElement(new Byte(type));
-
- }
+ protected int getParamDRDAType(int index) {
+ return drdaParamState_.getDrdaType(index-1);
+ }
+
/**
* returns drda length of parameter as sent by client.
- * @param index
+ * @param index - starting with 1
* @return data length
*/
-
protected int getParamLen(int index)
{
- return ((Integer) cliParamLens.elementAt(index -1)).intValue();
+ return drdaParamState_.getDrdaLen(index-1);
}
+
+
/**
* get parameter precision or DB2 max (31)
*
@@ -1179,30 +1331,6 @@
return -1;
}
- /**
- * save parameter len sent by client
- * @param index parameter index starting with 1
- * @param value length of data value
- *
- */
- protected void setParamLen(int index, int value)
- {
- cliParamLens.add(index -1, new Integer(value));
- }
-
- /**
- * get the number of parameters for this statement
- *
- * @return number of parameters
- */
- protected int getNumParams()
- {
- if (cliParamDrdaTypes != null)
- return cliParamDrdaTypes.size();
- else
- return 0;
- }
-
/**
* get the number of result set columns for the current resultSet
*
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out Wed Oct 25 04:52:05 2006
@@ -79,6 +79,14 @@
Jira170: caught expected table not found
Iteration 1 successful: 555 parameter markers successfully prepared and executed.
Test jira125 successful: 557 parameter markers successfully prepared and executed.
+Inserting first row...
+ -> Succeeded.
+Inserting second row...
+ -> Succeeded.
+Now inserting 3rd row, using lobs from 1st row...
+ -> Succeeded.
+Now inserting 4th row, using lobs from 2nd row...
+ -> Succeeded.
JIRA-1454 repro with c2 len=12748
Fetched a row, c2.length=12748
JIRA-1454 repro with c2 len=12750
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out Wed Oct 25 04:52:05 2006
@@ -79,6 +79,14 @@
Jira170: caught expected table not found
Iteration 1 successful: 555 parameter markers successfully prepared and executed.
Test jira125 successful: 557 parameter markers successfully prepared and executed.
+Inserting first row...
+ -> Succeeded.
+Inserting second row...
+ -> Succeeded.
+Now inserting 3rd row, using lobs from 1st row...
+ -> Succeeded.
+Now inserting 4th row, using lobs from 2nd row...
+ -> Succeeded.
JIRA-1454 repro with c2 len=12748
Fetched a row, c2.length=12748
JIRA-1454 repro with c2 len=12750
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out Wed Oct 25 04:52:05 2006
@@ -79,6 +79,14 @@
Jira170: caught expected table not found
Iteration 1 successful: 555 parameter markers successfully prepared and executed.
Test jira125 successful: 557 parameter markers successfully prepared and executed.
+Inserting first row...
+ -> Succeeded.
+Inserting second row...
+ -> Succeeded.
+Now inserting 3rd row, using lobs from 1st row...
+ -> Succeeded.
+Now inserting 4th row, using lobs from 2nd row...
+ -> Succeeded.
JIRA-1454 repro with c2 len=12748
Fetched a row, c2.length=12748
JIRA-1454 repro with c2 len=12750
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java?view=diff&rev=467612&r1=467611&r2=467612
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java Wed Oct 25 04:52:05 2006
@@ -26,6 +26,7 @@
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
+import java.sql.Types;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
@@ -322,10 +323,12 @@
jira614Test_a(conn);
jira170Test(conn);
jira125Test(conn);
+ jira815Test(conn);
jira428Test(conn);
jira1454Test(conn);
jira1533Test_a(conn);
jira1533Test_b(conn);
+ conn.rollback();
conn.close();
// refresh conn before cleaning up
conn = ij.startJBMS();
@@ -1043,6 +1046,89 @@
System.out.println("Iteration 1 successful: " + (nCols + 1) +
" parameter markers successfully prepared and executed.");
}
+
+ /**
+ * The first patch for Jira-815 introduced a bug that resulted
+ * in a hang if a prepared statement was first executed with a
+ * lob value, and then re-executed with a null-value in place
+ * of the lob. This test case ensures that the same bug has
+ * not been re-introduced.
+ */
+ private static void jira815Test(Connection conn)
+ throws Exception
+ {
+ conn.setAutoCommit(false);
+ Statement st = conn.createStatement();
+ try {
+ st.execute("drop table tt1");
+ } catch (SQLException se) {}
+
+ st.execute("create table tt1 (CLICOL01 smallint not null)");
+ st.execute("alter table tt1 add clicol02 smallint");
+ st.execute("alter table tt1 add clicol03 int not null default 1");
+ st.execute("alter table tt1 add clicol04 int");
+ st.execute("alter table tt1 add clicol05 decimal(10,0) not null default 1");
+ st.execute("alter table tt1 add clicol51 blob(1G)");
+ st.execute("alter table tt1 add clicol52 blob(50)");
+ st.execute("alter table tt1 add clicol53 clob(2G) not null default ''");
+ st.execute("alter table tt1 add clicol54 clob(60)");
+ conn.commit();
+
+ PreparedStatement pSt =
+ conn.prepareStatement("insert into tt1 values (?,?,?,?,?,?,?,?,?)");
+ pSt.setShort(1, (short)500);
+ pSt.setShort(2, (short)501);
+ pSt.setInt(3, 496);
+ pSt.setInt(4, 497);
+ pSt.setDouble(5, 484);
+ pSt.setBytes(6, "404 bit".getBytes());
+ pSt.setBytes(7, "405 bit".getBytes());
+ pSt.setString(8, "408 bit");
+ pSt.setString(9, "409 bit");
+
+ System.out.println("Inserting first row...");
+ pSt.execute();
+ System.out.println(" -> Succeeded.");
+
+ pSt.setNull(2, Types.SMALLINT);
+ pSt.setNull(4, Types.DOUBLE);
+ pSt.setNull(7, Types.BLOB);
+ pSt.setNull(9, Types.CLOB);
+
+ System.out.println("\nInserting second row...");
+ pSt.execute();
+ System.out.println(" -> Succeeded.");
+
+ System.out.println("\nNow inserting 3rd row, using lobs from 1st row...");
+ ResultSet rs = st.executeQuery("select * from tt1");
+ if (rs.next()) {
+ pSt.setShort(1, rs.getShort(1));
+ pSt.setShort(2, rs.getShort(2));
+ pSt.setInt(3, rs.getInt(3));
+ pSt.setInt(4, rs.getInt(4));
+ pSt.setDouble(5, rs.getDouble(5));
+ pSt.setBlob(6, rs.getBlob(6));
+ pSt.setBlob(7, rs.getBlob(7));
+ pSt.setClob(8, rs.getClob(8));
+ pSt.setClob(9, rs.getClob(9));
+ pSt.execute();
+ System.out.println(" -> Succeeded.");
+ }
+
+ System.out.println("\nNow inserting 4th row, using lobs from 2nd row...");
+ if (rs.next()) {
+ pSt.setNull(2, Types.SMALLINT);
+ pSt.setNull(4, Types.DOUBLE);
+ pSt.setBlob(6, rs.getBlob(6));
+ pSt.setNull(7, Types.BLOB);
+ pSt.setClob(8, rs.getClob(8));
+ pSt.setNull(9, Types.CLOB);
+ pSt.execute();
+ System.out.println(" -> Succeeded.");
+ }
+ conn.commit();
+ }
+
// Jira 1533 involves two different bugs regarding the handling of large
// amounts of parameter data: first, the Network Server was incorrectly
// handling the desegmentation of continued DSS segements, and second,