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	1 May 2006 22:46:14 -0000
***************
*** 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);
                      }
                  }
--- 366,403 ----
  
              // figure out how many columns
              int cols = rs.getMetaData().getColumnCount();
!             
!             // 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++;
!                 
!                 if ( j >= callResult.length )
!                     throw new PSQLException(GT.tr("A CallableStatement was excecuted with and invalid number of parameters"),PSQLState.SYNTAX_ERROR);
!                 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/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	1 May 2006 22:46:16 -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)
***************
*** 48,54 ****
--- 52,85 ----
                      			 + " 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);
--- 88,169 ----
      {
          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.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
!     {
!         Statement stmt = con.createStatement();
!         stmt.execute("CREATE OR REPLACE FUNCTION myiofunc(a INOUT int, b OUT int) AS 'BEGIN b := a; a := 1; END;' LANGUAGE plpgsql");
!         
!         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
      {
+         Statement stmt = con.createStatement();
+         stmt.execute("CREATE OR REPLACE FUNCTION myiofunc(a INOUT int, b OUT int) AS 'BEGIN b := a; a := 1; END;' LANGUAGE plpgsql");
+         
+         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 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);
--- 177,183 ----
      
          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(?,?,?) }");
--- 186,218 ----
              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
--- 332,338 ----
              cstmt.getBoolean(3);
              assertTrue(cstmt.wasNull());
          }
!         
          finally
          {
              try
