Index: org/postgresql/core/ParameterList.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/ParameterList.java,v
retrieving revision 1.8
diff -c -r1.8 ParameterList.java
*** org/postgresql/core/ParameterList.java	8 Jul 2005 17:38:28 -0000	1.8
--- org/postgresql/core/ParameterList.java	21 May 2006 11:06:05 -0000
***************
*** 40,52 ****
      int getParameterCount();
      
      /**
!      * Get the number of parameters in this list. This value may be different,
!      * and might be zero.
       * 
!      * @return the number of in parameters in this list
       */
      int getInParameterCount();
  
  
      /**
       * Return the oids of the parameters in this list.  May be null for
--- 40,57 ----
      int getParameterCount();
      
      /**
!      * Get the number of IN parameters in this list. 
       * 
!      * @return the number of IN parameters in this list
       */
      int getInParameterCount();
  
+     /**
+      * Get the number of OUT parameters in this list. 
+      * 
+      * @return the number of OUT parameters in this list
+      */
+     int getOutParameterCount();
  
      /**
       * Return the oids of the parameters in this list.  May be null for
Index: org/postgresql/core/v2/FastpathParameterList.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v2/FastpathParameterList.java,v
retrieving revision 1.8
diff -c -r1.8 FastpathParameterList.java
*** org/postgresql/core/v2/FastpathParameterList.java	4 Jul 2005 18:50:28 -0000	1.8
--- org/postgresql/core/v2/FastpathParameterList.java	21 May 2006 11:06:05 -0000
***************
*** 40,45 ****
--- 40,49 ----
      public int getInParameterCount() {
          return paramValues.length;
      }
+     public int getOutParameterCount()
+     {
+         return 0;
+     }
      public int getParameterCount()
      {
          return paramValues.length;
Index: org/postgresql/core/v2/SimpleParameterList.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v2/SimpleParameterList.java,v
retrieving revision 1.7
diff -c -r1.7 SimpleParameterList.java
*** org/postgresql/core/v2/SimpleParameterList.java	4 Jul 2005 18:50:28 -0000	1.7
--- org/postgresql/core/v2/SimpleParameterList.java	21 May 2006 11:06:06 -0000
***************
*** 27,38 ****
   *
   * @author Oliver Jowett (oliver@opencloud.com)
   */
! class SimpleParameterList implements ParameterList {
      SimpleParameterList(int paramCount) {
          this.paramValues = new Object[paramCount];
      }
!     public void registerOutParameter(int index, int sqlType ){};
!     public void registerOutParameter(int index, int sqlType, int precision ){};
      
      public int getInParameterCount() {
          return paramValues.length;
--- 27,48 ----
   *
   * @author Oliver Jowett (oliver@opencloud.com)
   */
! class SimpleParameterList implements ParameterList 
! {
!     
!     
      SimpleParameterList(int paramCount) {
          this.paramValues = new Object[paramCount];
+         
      }
!     public void registerOutParameter(int index, int sqlType )
!     {
!         
!     };
!     public void registerOutParameter(int index, int sqlType, int precision )
!     {
!       
!     };
      
      public int getInParameterCount() {
          return paramValues.length;
***************
*** 41,46 ****
--- 51,60 ----
      {
          return paramValues.length;
      }
+     public int getOutParameterCount()
+     {
+         return 1;
+     }
      public int[] getTypeOIDs() {
          return null;
      }
***************
*** 76,82 ****
      public void setBytea(int index, byte[] data, int offset, int length) throws SQLException {
          if (index < 1 || index > paramValues.length)
              throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
! 
          paramValues[index - 1] = new StreamWrapper(data, offset, length);
      }
  
--- 90,96 ----
      public void setBytea(int index, byte[] data, int offset, int length) throws SQLException {
          if (index < 1 || index > paramValues.length)
              throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
!         
          paramValues[index - 1] = new StreamWrapper(data, offset, length);
      }
  
***************
*** 90,96 ****
      public void setNull(int index, int oid) throws SQLException {
          if (index < 1 || index > paramValues.length)
              throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
! 
          paramValues[index - 1] = NULL_OBJECT;
      }
  
--- 104,110 ----
      public void setNull(int index, int oid) throws SQLException {
          if (index < 1 || index > paramValues.length)
              throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
!         
          paramValues[index - 1] = NULL_OBJECT;
      }
  
***************
*** 147,153 ****
      void checkAllParametersSet() throws SQLException {
          for (int i = 0; i < paramValues.length; i++)
          {
!             if (paramValues[i] == null)
                  throw new PSQLException(GT.tr("No value specified for parameter {0}.", new Integer(i + 1)), PSQLState.INVALID_PARAMETER_VALUE);
          }
      }
--- 161,167 ----
      void checkAllParametersSet() throws SQLException {
          for (int i = 0; i < paramValues.length; i++)
          {
!             if ( paramValues[i] == null)
                  throw new PSQLException(GT.tr("No value specified for parameter {0}.", new Integer(i + 1)), PSQLState.INVALID_PARAMETER_VALUE);
          }
      }
Index: org/postgresql/core/v3/CompositeParameterList.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/CompositeParameterList.java,v
retrieving revision 1.8
diff -c -r1.8 CompositeParameterList.java
*** org/postgresql/core/v3/CompositeParameterList.java	4 Jul 2005 18:50:29 -0000	1.8
--- org/postgresql/core/v3/CompositeParameterList.java	21 May 2006 11:06:06 -0000
***************
*** 52,61 ****
      {
          return total;
      }
!     public int getInParameterCount() {
          return total;
      }
! 
      public int[] getTypeOIDs() {
          int oids[] = new int[total];
          for (int i=0; i<offsets.length; i++) {
--- 52,65 ----
      {
          return total;
      }
!     public int getInParameterCount() 
!     {
          return total;
      }
!     public int getOutParameterCount()
!     {
!         return 0;
!     }
      public int[] getTypeOIDs() {
          int oids[] = new int[total];
          for (int i=0; i<offsets.length; i++) {
Index: org/postgresql/core/v3/SimpleParameterList.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/core/v3/SimpleParameterList.java,v
retrieving revision 1.11
diff -c -r1.11 SimpleParameterList.java
*** org/postgresql/core/v3/SimpleParameterList.java	24 Nov 2005 06:18:28 -0000	1.11
--- org/postgresql/core/v3/SimpleParameterList.java	21 May 2006 11:06:06 -0000
***************
*** 71,80 ****
      {
          return paramValues.length;
      }
      public int getInParameterCount() 
      {
          int count=0;
!         for( int i=0; i< paramTypes.length;i++)
          {
              if (direction[i] != OUT )
              {
--- 71,93 ----
      {
          return paramValues.length;
      }
+     public int getOutParameterCount()
+     {
+         int count=0;
+         for( int i=paramTypes.length; --i >= 0;)
+         {
+             if ((direction[i] & OUT) == OUT )
+             {
+                 count++;
+             }
+         }
+         return count;
+         
+     }
      public int getInParameterCount() 
      {
          int count=0;
!         for( int i=paramTypes.length; --i >= 0;)
          {
              if (direction[i] != OUT )
              {
***************
*** 126,132 ****
      public void checkAllParametersSet() throws SQLException {
          for (int i = 0; i < paramTypes.length; ++i)
          {
!             if (direction[i] != OUT && paramValues[i] == null)
                  throw new PSQLException(GT.tr("No value specified for parameter {0}.", new Integer(i + 1)), PSQLState.INVALID_PARAMETER_VALUE);
          }
      }
--- 139,145 ----
      public void checkAllParametersSet() throws SQLException {
          for (int i = 0; i < paramTypes.length; ++i)
          {
!             if ((direction[i]&OUT) != OUT && paramValues[i] == null)
                  throw new PSQLException(GT.tr("No value specified for parameter {0}.", new Integer(i + 1)), PSQLState.INVALID_PARAMETER_VALUE);
          }
      }
Index: org/postgresql/jdbc2/AbstractJdbc2Statement.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v
retrieving revision 1.88
diff -c -r1.88 AbstractJdbc2Statement.java
*** org/postgresql/jdbc2/AbstractJdbc2Statement.java	1 Feb 2006 18:52:13 -0000	1.88
--- org/postgresql/jdbc2/AbstractJdbc2Statement.java	21 May 2006 11:06:09 -0000
***************
*** 138,145 ****
          this.preparedQuery = connection.getQueryExecutor().createParameterizedQuery(parsed_sql);
          this.preparedParameters = preparedQuery.createParameterList();
  
!         this.testReturn = new int[preparedParameters.getInParameterCount()+1];
!         this.functionReturnType = new int[preparedParameters.getInParameterCount()+1];
  
  
          resultsettype = rsType;
--- 138,146 ----
          this.preparedQuery = connection.getQueryExecutor().createParameterizedQuery(parsed_sql);
          this.preparedParameters = preparedQuery.createParameterList();
  
!         int inParamCount =  preparedParameters.getInParameterCount() + 1;
!         this.testReturn = new int[inParamCount];
!         this.functionReturnType = new int[inParamCount];
  
  
          resultsettype = rsType;
***************
*** 366,392 ****
  
              // figure out how many columns
              int cols = rs.getMetaData().getColumnCount();
!             callResult = new Object[cols];
              
              // move them into the result set
!             for ( int i=0; i < cols; i++)
              {
!                 callResult[i] = rs.getObject(i+1);
!                 int columnType = rs.getMetaData().getColumnType(1);
!                 if (columnType != functionReturnType[i])
                  {
                      // this is here for the sole purpose of passing the cts
!                     if ( columnType == Types.DOUBLE && functionReturnType[i] == Types.REAL )
                      {
                          // return it as a float
!                         if ( callResult[i] != null)
!                             callResult[i] = new Float(((Double)callResult[i]).floatValue());
                      }
                      else
                      {    
! 	                    throw new PSQLException (GT.tr("A CallableStatement function was executed and the return was of type {0} however type {1} was registered.",
! 	                            new Object[]{
! 	                                "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType[i] }),
  	                      PSQLState.DATA_TYPE_MISMATCH);
                      }
                  }
--- 367,407 ----
  
              // figure out how many columns
              int cols = rs.getMetaData().getColumnCount();
!             
!             int outParameterCount = preparedParameters.getOutParameterCount() ;
!             
!             if ( cols != outParameterCount )
!                 throw new PSQLException(GT.tr("A CallableStatement was excecuted with an invalid number of parameters"),PSQLState.SYNTAX_ERROR);
!             
!             // allocate enough space for all possible parameters without regard to in/out            
!             callResult = new Object[preparedParameters.getParameterCount()+1];
              
              // move them into the result set
!             for ( int i=0,j=0; i < cols; i++,j++)
              {
!                 // find the next out parameter, the assumption is that the functionReturnType 
!                 // array will be initialized with 0 and only out parameters will have values
!                 // other than 0. 0 is the value for java.sql.Types.NULL, which should not 
!                 // conflict
!                 while( j< functionReturnType.length && functionReturnType[j]==0) j++;
!                 
!                 callResult[j] = rs.getObject(i+1);
!                 int columnType = rs.getMetaData().getColumnType(i+1);
! 
!                 if (columnType != functionReturnType[j])
                  {
                      // this is here for the sole purpose of passing the cts
!                     if ( columnType == Types.DOUBLE && functionReturnType[j] == Types.REAL )
                      {
                          // return it as a float
!                         if ( callResult[j] != null)
!                             callResult[j] = new Float(((Double)callResult[j]).floatValue());
                      }
                      else
                      {    
! 	                    throw new PSQLException (GT.tr("A CallableStatement function was executed and the out parameter {0} was of type {1} however type {2} was registered.",
! 	                            new Object[]{""+i+1,
! 	                                "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType[j] }),
  	                      PSQLState.DATA_TYPE_MISMATCH);
                      }
                  }
Index: org/postgresql/test/jdbc2/CallableStmtTest.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/test/jdbc2/CallableStmtTest.java,v
retrieving revision 1.18
diff -c -r1.18 CallableStmtTest.java
*** org/postgresql/test/jdbc2/CallableStmtTest.java	14 Dec 2005 14:26:08 -0000	1.18
--- org/postgresql/test/jdbc2/CallableStmtTest.java	21 May 2006 11:06:09 -0000
***************
*** 9,14 ****
--- 9,15 ----
  */
  package org.postgresql.test.jdbc2;
  
+ import org.postgresql.Driver;
  import org.postgresql.test.TestUtil;
  import java.sql.*;
  
***************
*** 21,27 ****
  public class CallableStmtTest extends TestCase
  {
      private Connection con;
! 
      public CallableStmtTest (String name)
      {
          super(name);
--- 22,28 ----
  public class CallableStmtTest extends TestCase
  {
      private Connection con;
!     
      public CallableStmtTest (String name)
      {
          super(name);
Index: org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java,v
retrieving revision 1.1
diff -c -r1.1 Jdbc3CallableStatementTest.java
*** org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java	4 Jul 2005 19:19:31 -0000	1.1
--- org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java	21 May 2006 11:06:10 -0000
***************
*** 11,20 ****
--- 11,23 ----
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
+ import java.sql.SQLException;
  import java.sql.Statement;
  import java.sql.Types;
  
+ import org.postgresql.Driver;
  import org.postgresql.test.TestUtil;
+ import org.postgresql.util.PSQLState;
  
  import junit.framework.TestCase;
  
***************
*** 26,31 ****
--- 29,35 ----
   */
  public class Jdbc3CallableStatementTest extends TestCase
  {
+         
      Connection con;
  
      /* (non-Javadoc)
***************
*** 37,44 ****
          Statement stmt = con.createStatement ();
          stmt.execute("create temp table numeric_tab (MAX_VAL NUMERIC(30,15), MIN_VAL NUMERIC(30,15), NULL_VAL NUMERIC(30,15) NULL)");
          stmt.execute("insert into numeric_tab values ( 999999999999999,0.000000000000001, null)");
  
!         boolean ret = stmt.execute("create or replace function "
                      			 + "Numeric_Proc( OUT IMAX NUMERIC(30,15), OUT IMIN NUMERIC(30,15), OUT INUL NUMERIC(30,15))  as "
                      			 + "'begin " 
                      			 + 	"select max_val into imax from numeric_tab;"
--- 41,50 ----
          Statement stmt = con.createStatement ();
          stmt.execute("create temp table numeric_tab (MAX_VAL NUMERIC(30,15), MIN_VAL NUMERIC(30,15), NULL_VAL NUMERIC(30,15) NULL)");
          stmt.execute("insert into numeric_tab values ( 999999999999999,0.000000000000001, null)");
+         stmt.execute("CREATE OR REPLACE FUNCTION myiofunc(a INOUT int, b OUT int) AS 'BEGIN b := a; a := 1; END;' LANGUAGE plpgsql");
+         stmt.execute("CREATE OR REPLACE FUNCTION myif(a INOUT int, b IN int) AS 'BEGIN a := b; END;' LANGUAGE plpgsql");
  
!         stmt.execute("create or replace function "
                      			 + "Numeric_Proc( OUT IMAX NUMERIC(30,15), OUT IMIN NUMERIC(30,15), OUT INUL NUMERIC(30,15))  as "
                      			 + "'begin " 
                      			 + 	"select max_val into imax from numeric_tab;"
***************
*** 48,54 ****
--- 54,87 ----
                      			 + " end;' "
                      			 + "language 'plpgsql';");
          
+         stmt.execute( "CREATE OR REPLACE FUNCTION test_somein_someout("
+                 + "pa IN int4,"
+                 + "pb OUT varchar,"  
+                 + "pc OUT int8)"
+                 + " AS "
+                 
+                 + "'begin "
+                 + "pb := ''out'';"
+                 + "pc := pa + 1;"
+                 + "end;'"
  
+                 + "LANGUAGE 'plpgsql' VOLATILE;"
+ 
+                  );  
+         stmt.execute("CREATE OR REPLACE FUNCTION test_allinout("
+                 + "pa INOUT int4,"
+                 + "pb INOUT varchar," 
+                 + "pc INOUT int8)"
+                 + " AS " 
+                 + "'begin "
+                 + "pa := pa + 1;"
+                 + "pb := ''foo out'';"
+                 + "pc := pa + 1;"
+                 + "end;'"
+                 + "LANGUAGE 'plpgsql' VOLATILE;"
+             );
+         
+         
      }
      /* (non-Javadoc)
       * @see junit.framework.TestCase#tearDown()
***************
*** 57,70 ****
      {
          Statement stmt = con.createStatement();
          stmt.execute("drop function Numeric_Proc(out decimal, out decimal, out decimal)");
          stmt.close();
          
      }
      
!     public void testNumeric() throws Throwable
      {
          try
          {
          CallableStatement call = con.prepareCall( "{ call Numeric_Proc(?,?,?) }" ) ;
      
          call.registerOutParameter(1,Types.NUMERIC,15);
--- 90,171 ----
      {
          Statement stmt = con.createStatement();
          stmt.execute("drop function Numeric_Proc(out decimal, out decimal, out decimal)");
+         stmt.execute("drop function test_somein_someout(int4)");
+         stmt.execute("drop function test_allinout( inout int4, inout varchar, inout int8)");
+         stmt.execute("drop function myiofunc(a INOUT int, b OUT int) ");
+         stmt.execute("drop function myif(a INOUT int, b IN int)");
          stmt.close();
          
      }
+     public void testSomeInOut() throws Throwable
+     {
+         
+                    
+         CallableStatement call = con.prepareCall( "{ call test_somein_someout(?,?,?) }" ) ;
+         
+         call.registerOutParameter(2,Types.VARCHAR);
+         call.registerOutParameter(3,Types.BIGINT);
+         call.setInt(1,20);
+         call.execute();
      
!     }
!     public void testNotEnoughParameters() throws Throwable
!     {
!         
!         CallableStatement cs = con.prepareCall("{call myiofunc(?,?)}");
!         cs.setInt(1,2);
!         cs.registerOutParameter(2,Types.INTEGER);
!         try
!         {
!             cs.execute();
!             fail("Should throw an exception ");
!         }
!         catch( SQLException ex)
!         {
!             assertTrue(ex.getSQLState().equalsIgnoreCase(PSQLState.SYNTAX_ERROR.getState()));
!         }
!         
!     }
!     public void testTooManyParameters() throws Throwable
      {
+ 
+         CallableStatement cs = con.prepareCall("{call myif(?,?)}");
          try
          {
+             cs.setInt(1,1);
+             cs.setInt(2,2);
+             cs.registerOutParameter(1,Types.INTEGER);
+             cs.registerOutParameter(2,Types.INTEGER);
+             cs.execute();
+             fail("should throw an exception");
+         }
+         catch( SQLException ex )
+         {
+             assertTrue(ex.getSQLState().equalsIgnoreCase(PSQLState.SYNTAX_ERROR.getState()));
+         }
+         
+     }
+     public void testAllInOut() throws Throwable
+     {
+         
+         CallableStatement call = con.prepareCall( "{ call test_allinout(?,?,?) }" ) ;
+         
+         call.registerOutParameter(1,Types.INTEGER);
+         call.registerOutParameter(2,Types.VARCHAR);
+         call.registerOutParameter(3,Types.BIGINT);
+         call.setInt(1,20);
+         call.setString(2,"hi");
+         call.setInt(3,123);
+         call.execute();
+         call.getInt(1);
+         call.getString(2);
+         call.getLong(3);
+    
+     }
+ 
+     public void testNumeric() throws Throwable
+     {
+         
          CallableStatement call = con.prepareCall( "{ call Numeric_Proc(?,?,?) }" ) ;
      
          call.registerOutParameter(1,Types.NUMERIC,15);
***************
*** 78,84 ****
      
          ret=call.getBigDecimal(2);
          assertTrue ("correct return from getNumeric ()",
!                                       ret.equals (new java.math.BigDecimal("0.000000000000001")));
          try
          {
              ret = call.getBigDecimal(3);
--- 179,185 ----
      
          ret=call.getBigDecimal(2);
          assertTrue ("correct return from getNumeric ()",
!                                   ret.equals (new java.math.BigDecimal("0.000000000000001")));
          try
          {
              ret = call.getBigDecimal(3);
***************
*** 87,120 ****
              assertTrue("This should be null",call.wasNull());
          }
      
!         }
!         catch(Exception ex)
!         {
!             fail(ex.getMessage());
!         }
      }
      public void testGetObjectDecimal() throws Throwable
      {
          try
          {
!         Statement stmt = con.createStatement();
!         stmt.execute("create temp table decimal_tab ( max_val numeric(30,15), min_val numeric(30,15), nul_val numeric(30,15) )");
!         stmt.execute("insert into decimal_tab values (999999999999999.000000000000000,0.000000000000001,null)");
!         boolean ret = stmt.execute("create or replace function "
!    			 + "decimal_proc( OUT pmax numeric, OUT pmin numeric, OUT nval numeric)  as "
!    			 + "'begin " 
!    			 + 	"select max_val into pmax from decimal_tab;"
!    			+ 	"select min_val into pmin from decimal_tab;"
!   			 + 	"select nul_val into nval from decimal_tab;"
!   			 		
!    			 + " end;' "
!    			 + "language 'plpgsql';");
          }
          catch (Exception ex)
          {
              fail ( ex.getMessage());
              throw ex;
          }
          try 
          {
              CallableStatement cstmt = con.prepareCall("{ call decimal_proc(?,?,?) }");
--- 188,220 ----
              assertTrue("This should be null",call.wasNull());
          }
      
!         
!         
      }
      public void testGetObjectDecimal() throws Throwable
      {
          try
          {
!             Statement stmt = con.createStatement();
!             stmt.execute("create temp table decimal_tab ( max_val numeric(30,15), min_val numeric(30,15), nul_val numeric(30,15) )");
!             stmt.execute("insert into decimal_tab values (999999999999999.000000000000000,0.000000000000001,null)");
!     
!             boolean ret = stmt.execute("create or replace function "
!        			 + "decimal_proc( OUT pmax numeric, OUT pmin numeric, OUT nval numeric)  as "
!        			 + "'begin " 
!        			 + 	"select max_val into pmax from decimal_tab;"
!        			+ 	"select min_val into pmin from decimal_tab;"
!       			 + 	"select nul_val into nval from decimal_tab;"
!       			 		
!        			 + " end;' "
!        			 + "language 'plpgsql';");
          }
          catch (Exception ex)
          {
              fail ( ex.getMessage());
              throw ex;
          }
+ 
          try 
          {
              CallableStatement cstmt = con.prepareCall("{ call decimal_proc(?,?,?) }");
***************
*** 234,243 ****
              cstmt.getBoolean(3);
              assertTrue(cstmt.wasNull());
          }
!         catch ( Exception ex )
!         {
!             fail(ex.getMessage());
!         }
          finally
          {
              try
--- 334,340 ----
              cstmt.getBoolean(3);
              assertTrue(cstmt.wasNull());
          }
!         
          finally
          {
              try
