db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r984393 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/ drda/org/apache/derby/impl/drda/ engine/org/apache/derby/impl/jdbc/ engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/jd...
Date Wed, 11 Aug 2010 12:44:44 GMT
Author: rhillegas
Date: Wed Aug 11 12:44:44 2010
New Revision: 984393

URL: http://svn.apache.org/viewvc?rev=984393&view=rev
Log:
DERBY-4066: Allow LOBs as OUT/INOUT procedure arguments.

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Wed Aug 11
12:44:44 2010
@@ -1083,7 +1083,7 @@ public class NetCursor extends org.apach
             throws SqlException {
         // Only inform the tracker if the Blob is published to the user.
         if (toBePublished) {
-            netResultSet_.markLOBAsPublished(column);
+            if ( netResultSet_ != null ) { netResultSet_.markLOBAsPublished(column); }
         }
         // Check for locator
         int locator = locator(column);
@@ -1125,7 +1125,7 @@ public class NetCursor extends org.apach
             throws SqlException {
         // Only inform the tracker if the Clob is published to the user.
         if (toBePublished) {
-            netResultSet_.markLOBAsPublished(column);
+            if ( netResultSet_ != null ) { netResultSet_.markLOBAsPublished(column); }
         }
         // Check for locator
         int locator = locator(column);

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?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- 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 Aug 11
12:44:44 2010
@@ -4179,8 +4179,14 @@ class DRDAConnThread extends Thread {
 				writer.endDdm();
 				writer.startDdm(CodePoint.FDODTA);
 				writeFDODTA(stmt);
-				writer.endDdm();
-				writer.endDdmAndDss();
+                writer.endDdm();
+                writer.endDdmAndDss();
+
+                if (stmt.getExtDtaObjects() != null)
+                {
+                    // writeScalarStream() ends the dss
+                    writeEXTDTA(stmt);
+                }
 			}
 			else if (hasResultSet)
 			// DRDA spec says that we MUST return either an
@@ -4195,7 +4201,7 @@ class DRDAConnThread extends Thread {
 			// SQLCARD for us.
 				writeNullSQLCARDobject();
 		}
-		
+
 		//We need to marke that params are finished so that we know we 
 		// are ready to send resultset info.
 		stmt.finishParams();
@@ -4238,7 +4244,7 @@ class DRDAConnThread extends Thread {
 		}
 
 		} while(hasResultSet && (++rsNum < numResults));
-		
+		        
 		return;			// we are done
 	}
 
@@ -6897,7 +6903,7 @@ class DRDAConnThread extends Thread {
 			}
 			return;
 		}
-		
+
 		while(getMoreData)
 		{			
 			sentExtData = false;
@@ -7304,6 +7310,9 @@ class DRDAConnThread extends Thread {
                 return cs.getTime(index, getGMTCalendar());
             case DRDAConstants.DRDA_TYPE_NTIMESTAMP:
                 return cs.getTimestamp(index, getGMTCalendar());
+            case DRDAConstants.DRDA_TYPE_NLOBBYTES:
+            case  DRDAConstants.DRDA_TYPE_NLOBCMIXED:
+                return EXTDTAInputStream.getEXTDTAStream(cs, index, drdaType);
             default:
                 return cs.getObject(index);
         }
@@ -7922,7 +7931,7 @@ class DRDAConnThread extends Thread {
 					break;
 				case DRDAConstants.DRDA_TYPE_NLOBBYTES:
 				case DRDAConstants.DRDA_TYPE_NLOBCMIXED:
-				    
+
 					// do not send EXTDTA for lob of length 0, beetle 5967
 				    if( ! ((EXTDTAInputStream) val).isEmptyStream() ){
 						stmt.addExtDtaObject(val, index);
@@ -8624,7 +8633,6 @@ class DRDAConnThread extends Thread {
 
   void writeEXTDTA (DRDAStatement stmt) throws SQLException, DRDAProtocolException
   {
-
 	  ArrayList extdtaValues = stmt.getExtDtaObjects();
     // build the EXTDTA data, if necessary
     if (extdtaValues == null) 

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java Wed Aug 11
12:44:44 2010
@@ -296,8 +296,11 @@ class DRDAResultSet
 
 		// Column number is starting on 1
 		int colnum = ((Integer) rsExtPositions.get(index)).intValue() + 1;
-		
-		if (FdocaConstants.isNullable(getRsDRDAType(colnum)))
+
+        // if there is no type information, then we represent a CallableStatement
+        // and all parameters are nullable
+        if ( rsDRDATypes == null ) { return true; }
+		else if (FdocaConstants.isNullable(getRsDRDAType(colnum)))
 			return true;
 		else 
 			return false;

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java Wed Aug
11 12:44:44 2010
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.BufferedInputStream;
 import java.io.Reader;
+import java.sql.CallableStatement;
 import java.sql.ResultSet;
 import java.sql.Blob;
 import java.sql.Clob;
@@ -48,13 +49,24 @@ class EXTDTAInputStream extends InputStr
 
     private InputStream binaryInputStream = null;
  
+    /** DRDA Type of column/parameter */
+    int ndrdaType;
+
+    //
+    // Used when this class wraps a ResultSet
+    //
     
     /** ResultSet that contains the stream*/
     EngineResultSet rs;
     /** Column index starting with 1 */
     int columnNumber;
-    /** DRDA Type of column */
-    int ndrdaType;
+
+    //
+    // Used when this class wraps a CallableStatement
+    //
+    private Clob _clob;
+    private Blob _blob;
+    
       
 	
 	private EXTDTAInputStream(ResultSet rs,
@@ -67,6 +79,18 @@ class EXTDTAInputStream extends InputStr
         this.ndrdaType = ndrdaType;
     }
 
+	private EXTDTAInputStream(Clob clob, int ndrdaType ) 
+    {
+        _clob = clob;
+        this.ndrdaType = ndrdaType;
+    }
+
+	private EXTDTAInputStream(Blob blob, int ndrdaType ) 
+    {
+        _blob = blob;
+        this.ndrdaType = ndrdaType;
+    }
+
     
 	/**
 	 * Create a new EXTDTAInputStream.  Before read the stream must be 
@@ -102,6 +126,39 @@ class EXTDTAInputStream extends InputStr
 		
 	}
 
+	/**
+	 * Create a new EXTDTAInputStream from a CallableStatement.
+	 * 
+	 * 
+	 * @param cs
+	 *            CallableStatement from which to retrieve the lob
+	 * @param column
+	 *            column number
+	 * @param drdaType
+	 *            FD:OCA type of object one of
+	 * 			   DRDAConstants.DRDA_TYPE_NLOBBYTES
+	 * 			   DRDAConstants.DRDA_TYPE_LOBBYTES
+	 * 			   DRDAConstants.DRDA_TYPE_NLOBCMIXED
+	 *  		   DRDAConstants.DRDA_TYPE_LOBCMIXED
+	 */
+	public static EXTDTAInputStream getEXTDTAStream(CallableStatement cs, int column, int drdaType)
+        throws SQLException
+    {
+ 	    
+		int ndrdaType = drdaType | 1; //nullable drdaType
+
+        switch ( ndrdaType )
+        {
+        case DRDAConstants.DRDA_TYPE_NLOBBYTES:
+            return new EXTDTAInputStream( cs.getBlob( column ), ndrdaType );
+        case DRDAConstants.DRDA_TYPE_NLOBCMIXED:
+            return new EXTDTAInputStream( cs.getClob( column ), ndrdaType );
+        default:
+            badDRDAType( ndrdaType );
+			return null;
+        }
+	}
+
 	
 	
 	/**
@@ -212,10 +269,16 @@ class EXTDTAInputStream extends InputStr
 	}
 
 
-    protected boolean isEmptyStream() throws SQLException{
-            return (rs.getLength(columnNumber) == 0);
-        
-        }
+    protected boolean isEmptyStream() throws SQLException
+    {
+        return (length() == 0);
+    }
+    private long length() throws SQLException
+    {
+        if ( rs != null ) { return rs.getLength(columnNumber); }
+        else if ( _clob != null ) { return _clob.length(); }
+        else { return _blob.length(); }
+    }
     
     
     /**
@@ -235,16 +298,15 @@ class EXTDTAInputStream extends InputStr
 	// BLOBS
 	if (ndrdaType == DRDAConstants.DRDA_TYPE_NLOBBYTES) 
 	{ 	    	
-	    is = this.rs.getBinaryStream(this.columnNumber);
-	    if (is == null) 
-              return;
+	    is = getBinaryStream();
+	    if (is == null) { return; }
 	}
 	    // CLOBS
 	else if (ndrdaType ==  DRDAConstants.DRDA_TYPE_NLOBCMIXED)
 	{	
 	    try {
 	        
-	        r = this.rs.getCharacterStream(this.columnNumber);
+	        r = getCharacterStream();
 		    	
 	        if(r == null){	            
                     return;
@@ -261,20 +323,31 @@ class EXTDTAInputStream extends InputStr
 		    }
 		    
 		}
-	    else
-		{
-		    if (SanityManager.DEBUG)
-			{
-			    SanityManager.THROWASSERT("NDRDAType: " + ndrdaType +
-						      " not valid EXTDTA object type");
-			}
-		}
+        else { badDRDAType( ndrdaType ); }
 	if (! is.markSupported()) {
 	    is = new BufferedInputStream(is);
 	    }
 	    
  	this.binaryInputStream=is;
     }
+    private InputStream getBinaryStream() throws SQLException
+    {
+        if ( rs != null ) { return rs.getBinaryStream(this.columnNumber); }
+        else { return _blob.getBinaryStream(); }
+    }
+    private Reader getCharacterStream() throws SQLException
+    {
+        if ( rs != null ) { return rs.getCharacterStream(this.columnNumber); }
+        else { return _clob.getCharacterStream(); }
+    }
+    private static void badDRDAType( int drdaType )
+    {
+        if (SanityManager.DEBUG)
+        {
+            SanityManager.THROWASSERT("NDRDAType: " + drdaType +
+                                      " not valid EXTDTA object type");
+        }
+    }
     
         
     protected void finalize() throws Throwable{
@@ -283,7 +356,7 @@ class EXTDTAInputStream extends InputStr
 
     /**
      * Is the value null?  Null status is obtained from the underlying 
-     * EngineResultSet, so that it can be determined before the stream
+     * EngineResultSet or LOB, so that it can be determined before the stream
      * is retrieved.
      * 
      * @return true if this value is null
@@ -291,7 +364,7 @@ class EXTDTAInputStream extends InputStr
      */
     public boolean isNull() throws SQLException
     {
-        return this.rs.isNull(columnNumber);
-     
+        if ( rs != null ) { return rs.isNull(columnNumber); }
+        else { return (_clob == null) && (_blob == null); }
     }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
Wed Aug 11 12:44:44 2010
@@ -564,31 +564,50 @@ public abstract class EmbedCallableState
 			throw Util.notImplemented();
 		}
 
-		/**
-	     * JDBC 2.0
-	     *
-	     * Get a BLOB OUT parameter.
-	     *
-	     * @param i the first parameter is 1, the second is 2, ...
-	     * @return an object representing a BLOB
-	     * @exception SQLException if a database-access error occurs.
-	     */
-	    public Blob getBlob (int i) throws SQLException {
-			throw Util.notImplemented();
+    /**
+     * JDBC 2.0
+     *
+     * Get a BLOB OUT parameter.
+     *
+     * @param i the first parameter is 1, the second is 2, ...
+     * @return an object representing a BLOB
+     * @exception SQLException if a database-access error occurs.
+     */
+    public Blob getBlob (int parameterIndex) throws SQLException {
+		checkStatus();
+		try {
+			DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);
+			Blob v = (Blob) param.getObject();
+			wasNull = (v == null);
+			return v;
+		} catch (StandardException e)
+		{
+			throw EmbedResultSet.noStateChangeException(e);
 		}
+    }
 
-	    /**
-	     * JDBC 2.0
-	     *
-	     * Get a CLOB OUT parameter.
-	     *
-	     * @param i the first parameter is 1, the second is 2, ...
-	     * @return an object representing a CLOB
-	     * @exception SQLException if a database-access error occurs.
-	     */
-	    public Clob getClob (int i) throws SQLException {
-			throw Util.notImplemented();
+    /**
+     * JDBC 2.0
+     *
+     * Get a CLOB OUT parameter.
+     *
+     * @param i the first parameter is 1, the second is 2, ...
+     * @return an object representing a CLOB
+     * @exception SQLException if a database-access error occurs.
+     */
+    public Clob getClob (int parameterIndex) throws SQLException {
+		checkStatus();
+		try {
+			DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);
+			Clob v = (Clob) param.getObject();
+			wasNull = (v == null);
+			return v;
+		} catch (StandardException e)
+		{
+			throw EmbedResultSet.noStateChangeException(e);
 		}
+    }
+    
 	public void addBatch() throws SQLException {
 
 		checkStatus();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java
Wed Aug 11 12:44:44 2010
@@ -176,25 +176,14 @@ public class CreateAliasNode extends DDL
                         int currentMode =  ((Integer) (((Vector) parameters[2]).elementAt(i))).intValue();
                         modes[i] = currentMode;
   
-                        boolean isOutputParameter =
-                            ( (currentMode == JDBC30Translation.PARAMETER_MODE_OUT) || (currentMode
== JDBC30Translation.PARAMETER_MODE_IN_OUT) );
-                        
                         //
-                        // We used to forbid LOBs as method parameters. DERBY-4066 lifted
this
-                        // restriction except for the output parameters of
-                        // procedures. In that case, we are not able to send the
-                        // output LOB across the network to a client today. In addition,
we still don't support XML values as parameters.
+                        // We still don't support XML values as parameters.
                         // Presumably, the XML datatype would map to a JDBC java.sql.SQLXML
type.
                         // We have no support for that type today.
                         //
                         if ( !types[ i ].isUserDefinedType() )
                         {
-                            if
-                                (
-                                 ( TypeId.getBuiltInTypeId(types[i].getJDBCTypeId()).isLongConcatableTypeId()
&& isOutputParameter )
-                                 ||
-                                 (TypeId.getBuiltInTypeId(types[i].getJDBCTypeId()).isXMLTypeId())
-                                 )
+                            if (TypeId.getBuiltInTypeId(types[i].getJDBCTypeId()).isXMLTypeId())
                             { throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED,
names[i]); }
                         }
                     }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java?rev=984393&r1=984392&r2=984393&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
Wed Aug 11 12:44:44 2010
@@ -559,7 +559,7 @@ public class ParameterMappingTest extend
                     int jopt = jdbcTypes[opt];
                     if (jopt == Types.NULL)
                         continue;
-                    
+
                     CallableStatement csp = conn.prepareCall("CALL PMP.TYPE_AS(?, ?, ?)");
                     
                     boolean bothRegistered = true;
@@ -632,6 +632,7 @@ public class ParameterMappingTest extend
         Connection conn = getConnection();
         PreparedStatement ps;
         CallableStatement cs;
+        Clob outVal;
 
         //
         // Clob input parameter
@@ -665,9 +666,9 @@ public class ParameterMappingTest extend
         //
         // Clob output parameter
         //
-        expectCompilationError
+        ps = chattyPrepare
             (
-             BAD_TYPE,
+             conn,
              "create procedure clobOut\n" +
              "( out c clob )\n" +
              "language java\n" +
@@ -675,13 +676,22 @@ public class ParameterMappingTest extend
              "no sql\n" +
              "external name '" + getClass().getName() + ".clobOut'\n"
              );
+        ps.execute();
+        ps.close();
         
+        cs = chattyPrepareCall( conn, "call clobOut( ? )" );
+        cs.registerOutParameter( 1, Types.CLOB );
+        cs.execute();
+        outVal = cs.getClob( 1 );
+        assertEquals( "abc", outVal.getSubString( 1L, (int) outVal.length() ) );
+        cs.close();
+
         //
         // Clob inout parameter
         //
-        expectCompilationError
+        ps = chattyPrepare
             (
-             BAD_TYPE,
+             conn,
              "create procedure clobInOut\n" +
              "( inout c clob )\n" +
              "language java\n" +
@@ -689,6 +699,17 @@ public class ParameterMappingTest extend
              "no sql\n" +
              "external name '" + getClass().getName() + ".clobInOut'\n"
              );
+        ps.execute();
+        ps.close();
+        
+        cs = chattyPrepareCall( conn, "call clobInOut( ? )" );
+        cs.setClob( 1, new StringColumnVTI.SimpleClob( "ghi" ) );
+        cs.registerOutParameter( 1, Types.CLOB );
+        cs.execute();
+        outVal = cs.getClob( 1 );
+        assertEquals( "ihg", outVal.getSubString( 1L, (int) outVal.length() ) );
+        cs.close();
+
     }
 
     /**
@@ -699,6 +720,7 @@ public class ParameterMappingTest extend
         Connection conn = getConnection();
         PreparedStatement ps;
         CallableStatement cs;
+        Blob outVal;
 
         //
         // Blob input parameter
@@ -726,9 +748,9 @@ public class ParameterMappingTest extend
         //
         // Blob output parameter
         //
-        expectCompilationError
+        ps = chattyPrepare
             (
-             BAD_TYPE,
+             conn,
              "create procedure blobOut\n" +
              "( out c blob )\n" +
              "language java\n" +
@@ -736,13 +758,22 @@ public class ParameterMappingTest extend
              "no sql\n" +
              "external name '" + getClass().getName() + ".blobOut'\n"
              );
+        ps.execute();
+        ps.close();
+
+        cs = chattyPrepareCall( conn, "call blobOut( ? )" );
+        cs.registerOutParameter( 1, Types.BLOB );
+        cs.execute();
+        outVal = cs.getBlob( 1 );
+        assertEquals( "abc", getBlobValue( outVal ) );
+        cs.close();
         
         //
         // Blob inout parameter
         //
-        expectCompilationError
+        ps = chattyPrepare
             (
-             BAD_TYPE,
+             conn,
              "create procedure blobInOut\n" +
              "( inout c blob )\n" +
              "language java\n" +
@@ -750,6 +781,16 @@ public class ParameterMappingTest extend
              "no sql\n" +
              "external name '" + getClass().getName() + ".blobInOut'\n"
              );
+        ps.execute();
+        ps.close();
+
+        cs = chattyPrepareCall( conn, "call blobInOut( ? )" );
+        cs.setBlob( 1, new StringColumnVTI.SimpleBlob( "ghi".getBytes( UTF8 ) ) );
+        cs.registerOutParameter( 1, Types.BLOB );
+        cs.execute();
+        outVal = cs.getBlob( 1 );
+        assertEquals( "ihg", getBlobValue( outVal ) );
+        cs.close();
     }
 
     /*
@@ -3693,10 +3734,29 @@ public class ParameterMappingTest extend
     }
 
     private static void checkProcedureOutput(int param, int paramType, byte[] val) {
+        boolean isBlob =  ( jdbcTypes[ paramType ] == Types.BLOB );
         if (param == 2)
-            assertEquals("0x4,0x3",showFirstTwo(val));
+        {
+            if ( isBlob )
+            {
+                assertEquals("0x82,0x43",showFirstTwo(val));
+            }
+            else
+            {
+                assertEquals("0x4,0x3",showFirstTwo(val));
+            }
+        }
         else if (param == 3)
-            assertEquals("0x9,0xfe",showFirstTwo(val));
+        {
+            if ( isBlob )
+            {
+                assertEquals("0x1,0x2",showFirstTwo(val));
+            }
+            else
+            {
+                assertEquals("0x9,0xfe",showFirstTwo(val));
+            }
+        }
     }
     
     private static void checkProcedureOutput(int param, int paramType, Date val) {



Mime
View raw message