Thread: JDBC CStmt (inline this time)

JDBC CStmt (inline this time)

From
Paul Bethe
Date:
Sorry all for the clutter - I am new to
listserver/patch style submission I guess the correct
way is to inline all the files..  sorry for the
previous attachments.

        Paul B

*** jdbc2/CallableStatement.java    Wed Feb 20 15:29:23
2002
---
/home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
Mon Nov 19 17:33:38 2001
***************
*** 7,13 ****

  import java.sql.*;
  import java.math.*;
! import org.postgresql.util.*;
  /*
   * CallableStatement is used to execute SQL stored
procedures.
   *
--- 7,13 ----

  import java.sql.*;
  import java.math.*;
!
  /*
   * CallableStatement is used to execute SQL stored
procedures.
   *
***************
*** 46,91 ****
       */
      public CallableStatement(Connection c, String q)
throws SQLException
      {
!         super(c, q, false); // don't parse yet..
!         modifyJdbcCall ();
!         parseSqlStmt (); // now parse the reformed stmt..
!     }
!
!     /**
!      * this method will turn a string of the form
!      * {? = call <some_function> (?, [?,..]) }
!      * into the PostgreSQL format which is
!      * select <some_function> (?, [?, ...]) as result
!      *
!      */
!     private void modifyJdbcCall () throws SQLException
{
!         originalSql = sql; // save for error msgs..
!         int index = sql.indexOf ("="); // is implied func
or proc?
!         if (index != -1) isFunction = true;
!         index = sql.indexOf ("call");
!         if (index == -1)
!             throw new PSQLException
("postgresql.call.malformed",
!                                      new Object[]{sql, JDBC_SYNTAX});
!         sql = sql.replace ('{', ' '); // replace these
characters
!         sql = sql.replace ('}', ' ');
!         sql = sql.replace (';', ' ');
!
!         sql = (isFunction ? "?" : "") + sql.substring
(index + 4);
!         sql = "select " + sql + " as " + RESULT_COLUMN +
";";
!     }
!
!     // internals
!     static final String JDBC_SYNTAX = "{[? =] call
<some_function> ([? [,?]*]) }";
!     static final String RESULT_COLUMN = "result";
!     String originalSql = "";
!     boolean isFunction;
!     // functionReturnType contains the user supplied
value to check
!     // testReturn contains a modified version to make
it easier to
!     // check the getXXX methods..
!     int functionReturnType;
!     int testReturn;
!     boolean returnTypeSet;
!     Object result;

      /*
       * Before executing a stored procedure call you
must explicitly
--- 46,53 ----
       */
      public CallableStatement(Connection c, String q)
throws SQLException
      {
!         super(c, q);
!     }

      /*
       * Before executing a stored procedure call you
must explicitly
***************
*** 96,103 ****
       * the getXXX method whose Java type XXX
corresponds to the
       * parameter's registered SQL type.
       *
-      * ONLY 1 RETURN PARAMETER if {?= call ..} syntax
is used
-      *
       * @param parameterIndex the first parameter is 1,
the second is 2,...
       * @param sqlType SQL type code defined by
java.sql.Types; for
       * parameters of type Numeric or Decimal use the
version of
--- 58,63 ----
***************
*** 105,160 ****
       * @exception SQLException if a database-access
error occurs.
       */
      public void registerOutParameter(int
parameterIndex, int sqlType) throws SQLException
!         {
!             if (parameterIndex != 1)
!                 throw new PSQLException
("postgresql.call.noinout");
!             if (!isFunction)
!                 throw new PSQLException
("postgresql.call.procasfunc", originalSql);
!
!             // functionReturnType contains the user supplied
value to check
!             // testReturn contains a modified version to make
it easier to
!             // check the getXXX methods..
!             functionReturnType = sqlType;
!             testReturn = sqlType;
!             if (functionReturnType == Types.CHAR ||
!                 functionReturnType == Types.LONGVARCHAR)
!                 testReturn = Types.VARCHAR;
!             else if (functionReturnType == Types.FLOAT)
!                 testReturn = Types.REAL; // changes to
streamline later error checking
!             returnTypeSet = true;
!         }
!
!     /**
!      * allow calls to execute update
!      * @return 1 if succesful call otherwise 0
!      */
!     public int executeUpdate() throws SQLException
!     {
!         //        System.out.println ("Executing " +
compileQuery());
!         java.sql.ResultSet rs = super.executeQuery
(compileQuery());
!         if (isFunction) {
!             if (!rs.next ())
!                 throw new PSQLException
("postgresql.call.noreturnval"); // TODO-props
!             result = rs.getObject (1);
!             int columnType = rs.getMetaData().getColumnType
(1);
!             if (columnType != functionReturnType)
!                 throw new PSQLException
("postgresql.call.wrongrtntype",
!                                          new Object[]{
!                     getSqlTypeName (columnType), getSqlTypeName
(functionReturnType) });
!         }
!         rs.close ();
!         return 1;
!     }
!
!
!     /**
!      * allow calls to execute update
!      * @return true if succesful
!      */
!     public boolean execute() throws SQLException
!     {
!         return (executeUpdate() == 1);
!     }

      /*
       * You must also specify the scale for
numeric/decimal types:
--- 65,71 ----
       * @exception SQLException if a database-access
error occurs.
       */
      public void registerOutParameter(int
parameterIndex, int sqlType) throws SQLException
!         {}

      /*
       * You must also specify the scale for
numeric/decimal types:
***************
*** 171,210 ****
       */
      public void registerOutParameter(int
parameterIndex, int sqlType,
                                       int scale) throws SQLException
!         {
!             registerOutParameter (parameterIndex, sqlType);
// ignore for now..
!         }
!
!     /*
!      * override this method to check for set @ 1 when
declared function..
!      *
!      * @param paramIndex the index into the inString
!      * @param s a string to be stored
!      * @exception SQLException if something goes wrong
!      */
!     protected void set(int paramIndex, String s) throws
SQLException
!     {
!         if (paramIndex == 1 && isFunction) // need to
registerOut instead
!             throw new PSQLException
("postgresql.call.funcover");
!         super.set (paramIndex, s); // else set as usual..
!     }
!
!         /*
!      * Helper - this compiles the SQL query from the
various parameters
!      * This is identical to toString() except it throws
an exception if a
!      * parameter is unused.
!      */
!     protected synchronized String compileQuery()
!     throws SQLException
!     {
!         if (isFunction && !returnTypeSet)
!             throw new
PSQLException("postgresql.call.noreturntype");
!         if (isFunction) { // set entry 1 to dummy entry..
!             inStrings[0] = ""; // dummy entry which ensured
that noone overrode
!             // and calls to setXXX (2,..) really went to
first arg in a function call..
!         }
!         return super.compileQuery ();
!     }

      // Old api?
      //public boolean isNull(int parameterIndex) throws
SQLException {
--- 82,88 ----
       */
      public void registerOutParameter(int
parameterIndex, int sqlType,
                                       int scale) throws SQLException
!         {}

      // Old api?
      //public boolean isNull(int parameterIndex) throws
SQLException {
***************
*** 223,229 ****
      public boolean wasNull() throws SQLException
      {
          // check to see if the last access threw an
exception
!         return (result == null);
      }

      // Old api?
--- 101,107 ----
      public boolean wasNull() throws SQLException
      {
          // check to see if the last access threw an
exception
!         return false; // fake it for now
      }

      // Old api?
***************
*** 241,248 ****
       */
      public String getString(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.VARCHAR,
"String");
!         return (String)result;
      }
      //public String getVarChar(int parameterIndex)
throws SQLException {
      //     return null;
--- 119,125 ----
       */
      public String getString(int parameterIndex) throws
SQLException
      {
!         return null;
      }
      //public String getVarChar(int parameterIndex)
throws SQLException {
      //     return null;
***************
*** 261,269 ****
       */
      public boolean getBoolean(int parameterIndex)
throws SQLException
      {
!         checkIndex (parameterIndex, Types.BIT, "Boolean");
!         if (result == null) return false;
!         return ((Boolean)result).booleanValue ();
      }

      /*
--- 138,144 ----
       */
      public boolean getBoolean(int parameterIndex)
throws SQLException
      {
!         return false;
      }

      /*
***************
*** 275,283 ****
       */
      public byte getByte(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.TINYINT,
"Byte");
!         if (result == null) return 0;
!         return (byte)((Integer)result).intValue ();
      }

      /*
--- 150,156 ----
       */
      public byte getByte(int parameterIndex) throws
SQLException
      {
!         return 0;
      }

      /*
***************
*** 289,299 ****
       */
      public short getShort(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.SMALLINT,
"Short");
!         if (result == null) return 0;
!         return (short)((Integer)result).intValue ();
      }
-

      /*
       * Get the value of an INTEGER parameter as a Java
int.
--- 162,169 ----
       */
      public short getShort(int parameterIndex) throws
SQLException
      {
!         return 0;
      }

      /*
       * Get the value of an INTEGER parameter as a Java
int.
***************
*** 304,312 ****
       */
      public int getInt(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.INTEGER, "Int");
!         if (result == null) return 0;
!         return ((Integer)result).intValue ();
      }

      /*
--- 174,180 ----
       */
      public int getInt(int parameterIndex) throws
SQLException
      {
!         return 0;
      }

      /*
***************
*** 318,326 ****
       */
      public long getLong(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.BIGINT, "Long");
!         if (result == null) return 0;
!         return ((Long)result).longValue ();
      }

      /*
--- 186,192 ----
       */
      public long getLong(int parameterIndex) throws
SQLException
      {
!         return 0;
      }

      /*
***************
*** 332,340 ****
       */
      public float getFloat(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.REAL, "Float");
!         if (result == null) return 0;
!         return ((Float)result).floatValue ();
      }

      /*
--- 198,204 ----
       */
      public float getFloat(int parameterIndex) throws
SQLException
      {
!         return (float) 0.0;
      }

      /*
***************
*** 346,354 ****
       */
      public double getDouble(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.DOUBLE,
"Double");
!         if (result == null) return 0;
!         return ((Double)result).doubleValue ();
      }

      /*
--- 210,216 ----
       */
      public double getDouble(int parameterIndex) throws
SQLException
      {
!         return 0.0;
      }

      /*
***************
*** 365,372 ****
      public BigDecimal getBigDecimal(int parameterIndex,
int scale)
      throws SQLException
      {
!         checkIndex (parameterIndex, Types.NUMERIC,
"BigDecimal");
!         return ((BigDecimal)result);
      }

      /*
--- 227,233 ----
      public BigDecimal getBigDecimal(int parameterIndex,
int scale)
      throws SQLException
      {
!         return null;
      }

      /*
***************
*** 379,386 ****
       */
      public byte[] getBytes(int parameterIndex) throws
SQLException
      {
!         checkIndex (parameterIndex, Types.VARBINARY,
"Bytes");
!         return ((byte [])result);
      }

      // New API (JPM) (getLongVarBinary)
--- 240,246 ----
       */
      public byte[] getBytes(int parameterIndex) throws
SQLException
      {
!         return null;
      }

      // New API (JPM) (getLongVarBinary)
***************
*** 397,404 ****
       */
      public java.sql.Date getDate(int parameterIndex)
throws SQLException
      {
!         checkIndex (parameterIndex, Types.DATE, "Date");
!         return (java.sql.Date)result;
      }

      /*
--- 257,263 ----
       */
      public java.sql.Date getDate(int parameterIndex)
throws SQLException
      {
!         return null;
      }

      /*
***************
*** 410,417 ****
       */
      public java.sql.Time getTime(int parameterIndex)
throws SQLException
      {
!         checkIndex (parameterIndex, Types.TIME, "Time");
!         return (java.sql.Time)result;
      }

      /*
--- 269,275 ----
       */
      public java.sql.Time getTime(int parameterIndex)
throws SQLException
      {
!         return null;
      }

      /*
***************
*** 424,431 ****
      public java.sql.Timestamp getTimestamp(int
parameterIndex)
      throws SQLException
      {
!         checkIndex (parameterIndex, Types.TIMESTAMP,
"Timestamp");
!         return (java.sql.Timestamp)result;
      }


//----------------------------------------------------------------------
--- 282,288 ----
      public java.sql.Timestamp getTimestamp(int
parameterIndex)
      throws SQLException
      {
!         return null;
      }


//----------------------------------------------------------------------
***************
*** 460,467 ****
      public Object getObject(int parameterIndex)
      throws SQLException
      {
!         checkIndex (parameterIndex);
!         return result;
      }

      // ** JDBC 2 Extensions **
--- 317,323 ----
      public Object getObject(int parameterIndex)
      throws SQLException
      {
!         return null;
      }

      // ** JDBC 2 Extensions **
***************
*** 471,480 ****
          throw org.postgresql.Driver.notImplemented();
      }

!     public java.math.BigDecimal getBigDecimal(int
parameterIndex) throws SQLException
      {
!         checkIndex (parameterIndex, Types.NUMERIC,
"BigDecimal");
!         return ((BigDecimal)result);
      }

      public Blob getBlob(int i) throws SQLException
--- 327,335 ----
          throw org.postgresql.Driver.notImplemented();
      }

!     public java.math.BigDecimal getBigDecimal(int i)
throws SQLException
      {
!         throw org.postgresql.Driver.notImplemented();
      }

      public Blob getBlob(int i) throws SQLException
***************
*** 512,587 ****
          throw org.postgresql.Driver.notImplemented();
      }

-     // no custom types allowed yet..
      public void registerOutParameter(int
parameterIndex, int sqlType, String typeName) throws
SQLException
      {
          throw org.postgresql.Driver.notImplemented();
      }

-
-
-     /** helperfunction for the getXXX calls to check
isFunction and index == 1
-      */
-     private void checkIndex (int parameterIndex, int
type, String getName)
-         throws SQLException {
-         checkIndex (parameterIndex);
-         if (type != this.testReturn)
-             throw new
PSQLException("postgresql.call.wrongget",
-                                     new Object[]{getSqlTypeName (testReturn),
-                                                      getName,
-                                                      getSqlTypeName (type)});
-     }
-     /** helperfunction for the getXXX calls to check
isFunction and index == 1
-      * @param parameterIndex index of getXXX (index)
-      * check to make sure is a function and index == 1
-      */
-     private void checkIndex (int parameterIndex) throws
SQLException {
-         if (!isFunction)
-             throw new
PSQLException("postgresql.call.noreturntype");
-         if (parameterIndex != 1)
-             throw new
PSQLException("postgresql.call.noinout");
-     }
-
-     /** helper function for creating msg with type
names
-      * @param sqlType a java.sql.Types.XX constant
-      * @return String which is the name of the
constant..
-      */
-     private static String getSqlTypeName (int sqlType)
{
-         switch (sqlType)
-             {
-             case Types.BIT:
-                 return "BIT";
-             case Types.SMALLINT:
-                 return "SMALLINT";
-             case Types.INTEGER:
-                 return "INTEGER";
-             case Types.BIGINT:
-                 return "BIGINT";
-             case Types.NUMERIC:
-                 return "NUMERIC";
-             case Types.REAL:
-                 return "REAL";
-             case Types.DOUBLE:
-                 return "DOUBLE";
-             case Types.FLOAT:
-                 return "FLOAT";
-             case Types.CHAR:
-                 return "CHAR";
-             case Types.VARCHAR:
-                 return "VARCHAR";
-             case Types.DATE:
-                 return "DATE";
-             case Types.TIME:
-                 return "TIME";
-             case Types.TIMESTAMP:
-                 return "TIMESTAMP";
-             case Types.BINARY:
-                 return "BINARY";
-             case Types.VARBINARY:
-                 return "VARBINARY";
-             default:
-                 return "UNKNOWN";
-             }
-     }
  }

--- 367,376 ----
*** jdbc2/Connection.java    Sat Feb 16 00:33:29 2002
---
/home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
Tue Jan 15 01:55:13 2002
***************
*** 135,145 ****

      public java.sql.CallableStatement
prepareCall(String sql, int resultSetType, int
resultSetConcurrency) throws SQLException
      {
!         //        throw new
PSQLException("postgresql.con.call");
!         CallableStatement s = new
CallableStatement(this,sql);
!         s.setResultSetType(resultSetType);
!         s.setResultSetConcurrency(resultSetConcurrency);
!         return s;
      }

      /*
--- 135,145 ----

      public java.sql.CallableStatement
prepareCall(String sql, int resultSetType, int
resultSetConcurrency) throws SQLException
      {
!         throw new PSQLException("postgresql.con.call");
!         //CallableStatement s = new
CallableStatement(this,sql);
!         //s.setResultSetType(resultSetType);
!         //s.setResultSetConcurrency(resultSetConcurrency);
!         //return s;
      }

      /*
***
/home/paulb/postgresql-7.2/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
Thu Feb 21 16:11:28 2002
---
/home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
Tue Jan 15 02:37:33 2002
***************
*** 46,51 ****
--- 46,54 ----

      /*
       * Constructor for the PreparedStatement class.
+      * Split the SQL statement into segments -
separated by the arguments.
+      * When we rebuild the thing with the arguments, we
can substitute the
+      * args and join the whole thing together.
       *
       * @param conn the instanatiating connection
       * @param sql the SQL statement with ? for IN
markers
***************
*** 53,88 ****
       */
      public PreparedStatement(Connection connection,
String sql) throws SQLException
      {
-         this (connection, sql, true); // need to parse
-     }
-
-     /*
-      * Constructor for the PreparedStatement class.
-      *
-      * @param conn the instanatiating connection
-      * @param sql the SQL statement with ? for IN
markers
-      * @param needsParsing if a descendant (aka
CallableStmt will do it's own parse)
-      * @exception SQLException if something bad occurs
-      */
-     protected PreparedStatement(Connection connection,
String sql, boolean needsParsing) throws SQLException
-     {
          super(connection);
-         this.connection = connection;
-         this.sql = sql;
-         if (needsParsing)
-             parseSqlStmt ();
-     }

-     /**
-      * Split the SQL statement into segments -
separated by the arguments.
-      * When we rebuild the thing with the arguments, we
can substitute the
-      * args and join the whole thing together.
-      */
-     protected void parseSqlStmt () throws SQLException
{
          Vector v = new Vector();
          boolean inQuotes = false;
          int lastParmEnd = 0, i;

          for (i = 0; i < sql.length(); ++i)
          {
              int c = sql.charAt(i);
--- 56,70 ----
       */
      public PreparedStatement(Connection connection,
String sql) throws SQLException
      {
          super(connection);

          Vector v = new Vector();
          boolean inQuotes = false;
          int lastParmEnd = 0, i;

+         this.sql = sql;
+         this.connection = connection;
+
          for (i = 0; i < sql.length(); ++i)
          {
              int c = sql.charAt(i);
***************
*** 136,142 ****
       * This is identical to toString() except it throws
an exception if a
       * parameter is unused.
       */
!     protected synchronized String compileQuery()
      throws SQLException
      {
          sbuf.setLength(0);
--- 118,124 ----
       * This is identical to toString() except it throws
an exception if a
       * parameter is unused.
       */
!     private synchronized String compileQuery()
      throws SQLException
      {
          sbuf.setLength(0);
***************
*** 832,838 ****
       * @param s a string to be stored
       * @exception SQLException if something goes wrong
       */
!     protected void set(int paramIndex, String s) throws
SQLException
      {
          if (paramIndex < 1 || paramIndex >
inStrings.length)
              throw new PSQLException("postgresql.prep.range");
--- 814,820 ----
       * @param s a string to be stored
       * @exception SQLException if something goes wrong
       */
!     private void set(int paramIndex, String s) throws
SQLException
      {
          if (paramIndex < 1 || paramIndex >
inStrings.length)
              throw new PSQLException("postgresql.prep.range");

*** errors.properties    Thu Feb 21 14:38:35 2002
---
/home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/errors.properties
Wed Sep  5 23:03:37 2001
***************
*** 72,85 ****
  postgresql.unusual:Something unusual has occured to
cause the driver to fail. Please report this
exception: {0}
  postgresql.unimplemented:This method is not yet
implemented.
  postgresql.unexpected:An unexpected result was
returned by a query.
-
- # proposed changes for CallableStatements
- postgresql.call.noreturntype:A CallableStatement
Function was declared but no call to
'registerOutParameter (1, <some_type>)' was made.
- postgresql.call.noinout:PostgreSQL only supports
function return value [@ 1] (no OUT or INOUT
arguments)
- postgresql.call.procasfunc:This Statement [{0}]
defines a procedure call (needs ?= call <stmt> to be
considered a function.
- postgresql.call.malformed:Malformed stmt [{0}] usage
: {1}
- postgresql.call.funcover:Cannot execute Query a call
to setXXX (1, ..) was made where argument 1 is the
return value of a function.
- postgresql.call.wrongget:Parameter of type {0} was
registered but call to get{1} (sqltype={2}) was made.
- postgresql.call.noreturnval:A CallableStatement
Function was executed with nothing returned.
- postgresql.call.wrongrtntype:A CallableStatement
Function was executed and the return was of type ({0})
however type={1} was registered.
-
--- 72,74 ----
*** test/JDBC2Tests.java    Wed Feb 20 16:26:46 2002
---
/home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
Mon Nov 19 17:33:39 2001
***************
*** 227,235 ****
          // Fastpath/LargeObject
          suite.addTestSuite(BlobTest.class);

-         //Callable Statement
-         suite.addTestSuite(CallableStmtTest.class);
-
          // That's all folks
          return suite;
      }
--- 227,232 ----
** new class
test/jdbc2/CallableStmtTest.java
package org.postgresql.test.jdbc2;

import org.postgresql.test.JDBC2Tests;
import junit.framework.TestCase;
import java.io.*;
import java.sql.*;

/*
 * CallableStatement tests.
 * @author Paul Bethe
 */
public class CallableStmtTest extends TestCase
{
    private Connection con;

    public CallableStmtTest (String name)
    {
        super(name);
    }

    protected void setUp() throws Exception
    {
        con = JDBC2Tests.openDB();
        Statement stmt = con.createStatement ();
        stmt.execute ("CREATE OR REPLACE FUNCTION
testspg__getString (varchar) " +
                      "RETURNS varchar AS ' DECLARE inString alias
for $1; begin "+
                      "return ''bob''; end; ' LANGUAGE 'plpgsql';");
        stmt.execute ("CREATE OR REPLACE FUNCTION
testspg__getDouble (float) " +
                      "RETURNS float AS ' DECLARE inString alias for
$1; begin " +
                      "return 42.42; end; ' LANGUAGE 'plpgsql';");
        stmt.execute ("CREATE OR REPLACE FUNCTION
testspg__getInt (int) RETURNS int " +
                      " AS 'DECLARE    inString alias for $1; begin " +
                      "return 42; end;' LANGUAGE 'plpgsql';");
        stmt.execute ("CREATE OR REPLACE FUNCTION
testspg__getNumeric (numeric) " +
                      "RETURNS numeric AS ' DECLARE    inString alias
for $1; " +
                      "begin    return 42; end; ' LANGUAGE 'plpgsql';");
        stmt.close ();
    }

    protected void tearDown() throws Exception
    {
        Statement stmt = con.createStatement ();
        stmt.execute ("drop FUNCTION testspg__getString
(varchar);");
        stmt.execute ("drop FUNCTION testspg__getDouble
(float);");
        stmt.execute ("drop FUNCTION testspg__getInt
(int);");
        stmt.execute ("drop FUNCTION testspg__getNumeric
(numeric);");
        JDBC2Tests.closeDB(con);
    }


    final String func = "{ ? = call ";
    final String pkgName = "testspg__";
    //    protected void runTest () throws Throwable {
    //testGetString ();
    //}

    public void testGetDouble () throws Throwable {
        // System.out.println ("Testing CallableStmt
Types.DOUBLE");
        CallableStatement call = con.prepareCall (func +
pkgName + "getDouble (?) }");
        call.setDouble (2, (double)3.04);
        call.registerOutParameter (1, Types.DOUBLE);
        call.execute ();
        double result = call.getDouble (1);
        assertTrue ("correct return from getString ()",
result == 42.42);
    }

    public void testGetInt () throws Throwable {
        // System.out.println ("Testing CallableStmt
Types.INTEGER");
        CallableStatement call = con.prepareCall (func +
pkgName + "getInt (?) }");
        call.setInt (2, 4);
        call.registerOutParameter (1, Types.INTEGER);
        call.execute ();
        int result = call.getInt (1);
        assertTrue ("correct return from getString ()",
result == 42);
    }

    public void testGetNumeric () throws Throwable {
        // System.out.println ("Testing CallableStmt
Types.NUMERIC");
        CallableStatement call = con.prepareCall (func +
pkgName + "getNumeric (?) }");
        call.setBigDecimal (2, new java.math.BigDecimal(4));
        call.registerOutParameter (1, Types.NUMERIC);
        call.execute ();
        java.math.BigDecimal result = call.getBigDecimal
(1);
        assertTrue ("correct return from getString ()",
                    result.equals (new java.math.BigDecimal(42)));
    }

    public void testGetString () throws Throwable {
        // System.out.println ("Testing CallableStmt
Types.VARCHAR");
        CallableStatement call = con.prepareCall (func +
pkgName + "getString (?) }");
        call.setString (2, "foo");
        call.registerOutParameter (1, Types.VARCHAR);
        call.execute ();
        String result = call.getString (1);
        assertTrue ("correct return from getString ()",
result.equals ("bob"));

    }

}


__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com

Re: JDBC CStmt (inline this time)

From
Bruce Momjian
Date:
This has been saved for the 7.3 release:

    http://candle.pha.pa.us/cgi-bin/pgpatches2

---------------------------------------------------------------------------

Paul Bethe wrote:
> Sorry all for the clutter - I am new to
> listserver/patch style submission I guess the correct
> way is to inline all the files..  sorry for the
> previous attachments.
>
>         Paul B
>
> *** jdbc2/CallableStatement.java    Wed Feb 20 15:29:23
> 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
> Mon Nov 19 17:33:38 2001
> ***************
> *** 7,13 ****
>
>   import java.sql.*;
>   import java.math.*;
> ! import org.postgresql.util.*;
>   /*
>    * CallableStatement is used to execute SQL stored
> procedures.
>    *
> --- 7,13 ----
>
>   import java.sql.*;
>   import java.math.*;
> !
>   /*
>    * CallableStatement is used to execute SQL stored
> procedures.
>    *
> ***************
> *** 46,91 ****
>        */
>       public CallableStatement(Connection c, String q)
> throws SQLException
>       {
> !         super(c, q, false); // don't parse yet..
> !         modifyJdbcCall ();
> !         parseSqlStmt (); // now parse the reformed stmt..
> !     }
> !
> !     /**
> !      * this method will turn a string of the form
> !      * {? = call <some_function> (?, [?,..]) }
> !      * into the PostgreSQL format which is
> !      * select <some_function> (?, [?, ...]) as result
> !      *
> !      */
> !     private void modifyJdbcCall () throws SQLException
> {
> !         originalSql = sql; // save for error msgs..
> !         int index = sql.indexOf ("="); // is implied func
> or proc?
> !         if (index != -1) isFunction = true;
> !         index = sql.indexOf ("call");
> !         if (index == -1)
> !             throw new PSQLException
> ("postgresql.call.malformed",
> !                                      new Object[]{sql, JDBC_SYNTAX});
> !         sql = sql.replace ('{', ' '); // replace these
> characters
> !         sql = sql.replace ('}', ' ');
> !         sql = sql.replace (';', ' ');
> !
> !         sql = (isFunction ? "?" : "") + sql.substring
> (index + 4);
> !         sql = "select " + sql + " as " + RESULT_COLUMN +
> ";";
> !     }
> !
> !     // internals
> !     static final String JDBC_SYNTAX = "{[? =] call
> <some_function> ([? [,?]*]) }";
> !     static final String RESULT_COLUMN = "result";
> !     String originalSql = "";
> !     boolean isFunction;
> !     // functionReturnType contains the user supplied
> value to check
> !     // testReturn contains a modified version to make
> it easier to
> !     // check the getXXX methods..
> !     int functionReturnType;
> !     int testReturn;
> !     boolean returnTypeSet;
> !     Object result;
>
>       /*
>        * Before executing a stored procedure call you
> must explicitly
> --- 46,53 ----
>        */
>       public CallableStatement(Connection c, String q)
> throws SQLException
>       {
> !         super(c, q);
> !     }
>
>       /*
>        * Before executing a stored procedure call you
> must explicitly
> ***************
> *** 96,103 ****
>        * the getXXX method whose Java type XXX
> corresponds to the
>        * parameter's registered SQL type.
>        *
> -      * ONLY 1 RETURN PARAMETER if {?= call ..} syntax
> is used
> -      *
>        * @param parameterIndex the first parameter is 1,
> the second is 2,...
>        * @param sqlType SQL type code defined by
> java.sql.Types; for
>        * parameters of type Numeric or Decimal use the
> version of
> --- 58,63 ----
> ***************
> *** 105,160 ****
>        * @exception SQLException if a database-access
> error occurs.
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType) throws SQLException
> !         {
> !             if (parameterIndex != 1)
> !                 throw new PSQLException
> ("postgresql.call.noinout");
> !             if (!isFunction)
> !                 throw new PSQLException
> ("postgresql.call.procasfunc", originalSql);
> !
> !             // functionReturnType contains the user supplied
> value to check
> !             // testReturn contains a modified version to make
> it easier to
> !             // check the getXXX methods..
> !             functionReturnType = sqlType;
> !             testReturn = sqlType;
> !             if (functionReturnType == Types.CHAR ||
> !                 functionReturnType == Types.LONGVARCHAR)
> !                 testReturn = Types.VARCHAR;
> !             else if (functionReturnType == Types.FLOAT)
> !                 testReturn = Types.REAL; // changes to
> streamline later error checking
> !             returnTypeSet = true;
> !         }
> !
> !     /**
> !      * allow calls to execute update
> !      * @return 1 if succesful call otherwise 0
> !      */
> !     public int executeUpdate() throws SQLException
> !     {
> !         //        System.out.println ("Executing " +
> compileQuery());
> !         java.sql.ResultSet rs = super.executeQuery
> (compileQuery());
> !         if (isFunction) {
> !             if (!rs.next ())
> !                 throw new PSQLException
> ("postgresql.call.noreturnval"); // TODO-props
> !             result = rs.getObject (1);
> !             int columnType = rs.getMetaData().getColumnType
> (1);
> !             if (columnType != functionReturnType)
> !                 throw new PSQLException
> ("postgresql.call.wrongrtntype",
> !                                          new Object[]{
> !                     getSqlTypeName (columnType), getSqlTypeName
> (functionReturnType) });
> !         }
> !         rs.close ();
> !         return 1;
> !     }
> !
> !
> !     /**
> !      * allow calls to execute update
> !      * @return true if succesful
> !      */
> !     public boolean execute() throws SQLException
> !     {
> !         return (executeUpdate() == 1);
> !     }
>
>       /*
>        * You must also specify the scale for
> numeric/decimal types:
> --- 65,71 ----
>        * @exception SQLException if a database-access
> error occurs.
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType) throws SQLException
> !         {}
>
>       /*
>        * You must also specify the scale for
> numeric/decimal types:
> ***************
> *** 171,210 ****
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType,
>                                        int scale) throws SQLException
> !         {
> !             registerOutParameter (parameterIndex, sqlType);
> // ignore for now..
> !         }
> !
> !     /*
> !      * override this method to check for set @ 1 when
> declared function..
> !      *
> !      * @param paramIndex the index into the inString
> !      * @param s a string to be stored
> !      * @exception SQLException if something goes wrong
> !      */
> !     protected void set(int paramIndex, String s) throws
> SQLException
> !     {
> !         if (paramIndex == 1 && isFunction) // need to
> registerOut instead
> !             throw new PSQLException
> ("postgresql.call.funcover");
> !         super.set (paramIndex, s); // else set as usual..
> !     }
> !
> !         /*
> !      * Helper - this compiles the SQL query from the
> various parameters
> !      * This is identical to toString() except it throws
> an exception if a
> !      * parameter is unused.
> !      */
> !     protected synchronized String compileQuery()
> !     throws SQLException
> !     {
> !         if (isFunction && !returnTypeSet)
> !             throw new
> PSQLException("postgresql.call.noreturntype");
> !         if (isFunction) { // set entry 1 to dummy entry..
> !             inStrings[0] = ""; // dummy entry which ensured
> that noone overrode
> !             // and calls to setXXX (2,..) really went to
> first arg in a function call..
> !         }
> !         return super.compileQuery ();
> !     }
>
>       // Old api?
>       //public boolean isNull(int parameterIndex) throws
> SQLException {
> --- 82,88 ----
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType,
>                                        int scale) throws SQLException
> !         {}
>
>       // Old api?
>       //public boolean isNull(int parameterIndex) throws
> SQLException {
> ***************
> *** 223,229 ****
>       public boolean wasNull() throws SQLException
>       {
>           // check to see if the last access threw an
> exception
> !         return (result == null);
>       }
>
>       // Old api?
> --- 101,107 ----
>       public boolean wasNull() throws SQLException
>       {
>           // check to see if the last access threw an
> exception
> !         return false; // fake it for now
>       }
>
>       // Old api?
> ***************
> *** 241,248 ****
>        */
>       public String getString(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.VARCHAR,
> "String");
> !         return (String)result;
>       }
>       //public String getVarChar(int parameterIndex)
> throws SQLException {
>       //     return null;
> --- 119,125 ----
>        */
>       public String getString(int parameterIndex) throws
> SQLException
>       {
> !         return null;
>       }
>       //public String getVarChar(int parameterIndex)
> throws SQLException {
>       //     return null;
> ***************
> *** 261,269 ****
>        */
>       public boolean getBoolean(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.BIT, "Boolean");
> !         if (result == null) return false;
> !         return ((Boolean)result).booleanValue ();
>       }
>
>       /*
> --- 138,144 ----
>        */
>       public boolean getBoolean(int parameterIndex)
> throws SQLException
>       {
> !         return false;
>       }
>
>       /*
> ***************
> *** 275,283 ****
>        */
>       public byte getByte(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.TINYINT,
> "Byte");
> !         if (result == null) return 0;
> !         return (byte)((Integer)result).intValue ();
>       }
>
>       /*
> --- 150,156 ----
>        */
>       public byte getByte(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 289,299 ****
>        */
>       public short getShort(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.SMALLINT,
> "Short");
> !         if (result == null) return 0;
> !         return (short)((Integer)result).intValue ();
>       }
> -
>
>       /*
>        * Get the value of an INTEGER parameter as a Java
> int.
> --- 162,169 ----
>        */
>       public short getShort(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
>        * Get the value of an INTEGER parameter as a Java
> int.
> ***************
> *** 304,312 ****
>        */
>       public int getInt(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.INTEGER, "Int");
> !         if (result == null) return 0;
> !         return ((Integer)result).intValue ();
>       }
>
>       /*
> --- 174,180 ----
>        */
>       public int getInt(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 318,326 ****
>        */
>       public long getLong(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.BIGINT, "Long");
> !         if (result == null) return 0;
> !         return ((Long)result).longValue ();
>       }
>
>       /*
> --- 186,192 ----
>        */
>       public long getLong(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 332,340 ****
>        */
>       public float getFloat(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.REAL, "Float");
> !         if (result == null) return 0;
> !         return ((Float)result).floatValue ();
>       }
>
>       /*
> --- 198,204 ----
>        */
>       public float getFloat(int parameterIndex) throws
> SQLException
>       {
> !         return (float) 0.0;
>       }
>
>       /*
> ***************
> *** 346,354 ****
>        */
>       public double getDouble(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.DOUBLE,
> "Double");
> !         if (result == null) return 0;
> !         return ((Double)result).doubleValue ();
>       }
>
>       /*
> --- 210,216 ----
>        */
>       public double getDouble(int parameterIndex) throws
> SQLException
>       {
> !         return 0.0;
>       }
>
>       /*
> ***************
> *** 365,372 ****
>       public BigDecimal getBigDecimal(int parameterIndex,
> int scale)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.NUMERIC,
> "BigDecimal");
> !         return ((BigDecimal)result);
>       }
>
>       /*
> --- 227,233 ----
>       public BigDecimal getBigDecimal(int parameterIndex,
> int scale)
>       throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 379,386 ****
>        */
>       public byte[] getBytes(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.VARBINARY,
> "Bytes");
> !         return ((byte [])result);
>       }
>
>       // New API (JPM) (getLongVarBinary)
> --- 240,246 ----
>        */
>       public byte[] getBytes(int parameterIndex) throws
> SQLException
>       {
> !         return null;
>       }
>
>       // New API (JPM) (getLongVarBinary)
> ***************
> *** 397,404 ****
>        */
>       public java.sql.Date getDate(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.DATE, "Date");
> !         return (java.sql.Date)result;
>       }
>
>       /*
> --- 257,263 ----
>        */
>       public java.sql.Date getDate(int parameterIndex)
> throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 410,417 ****
>        */
>       public java.sql.Time getTime(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.TIME, "Time");
> !         return (java.sql.Time)result;
>       }
>
>       /*
> --- 269,275 ----
>        */
>       public java.sql.Time getTime(int parameterIndex)
> throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 424,431 ****
>       public java.sql.Timestamp getTimestamp(int
> parameterIndex)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.TIMESTAMP,
> "Timestamp");
> !         return (java.sql.Timestamp)result;
>       }
>
>
> //----------------------------------------------------------------------
> --- 282,288 ----
>       public java.sql.Timestamp getTimestamp(int
> parameterIndex)
>       throws SQLException
>       {
> !         return null;
>       }
>
>
> //----------------------------------------------------------------------
> ***************
> *** 460,467 ****
>       public Object getObject(int parameterIndex)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex);
> !         return result;
>       }
>
>       // ** JDBC 2 Extensions **
> --- 317,323 ----
>       public Object getObject(int parameterIndex)
>       throws SQLException
>       {
> !         return null;
>       }
>
>       // ** JDBC 2 Extensions **
> ***************
> *** 471,480 ****
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> !     public java.math.BigDecimal getBigDecimal(int
> parameterIndex) throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.NUMERIC,
> "BigDecimal");
> !         return ((BigDecimal)result);
>       }
>
>       public Blob getBlob(int i) throws SQLException
> --- 327,335 ----
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> !     public java.math.BigDecimal getBigDecimal(int i)
> throws SQLException
>       {
> !         throw org.postgresql.Driver.notImplemented();
>       }
>
>       public Blob getBlob(int i) throws SQLException
> ***************
> *** 512,587 ****
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> -     // no custom types allowed yet..
>       public void registerOutParameter(int
> parameterIndex, int sqlType, String typeName) throws
> SQLException
>       {
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> -
> -
> -     /** helperfunction for the getXXX calls to check
> isFunction and index == 1
> -      */
> -     private void checkIndex (int parameterIndex, int
> type, String getName)
> -         throws SQLException {
> -         checkIndex (parameterIndex);
> -         if (type != this.testReturn)
> -             throw new
> PSQLException("postgresql.call.wrongget",
> -                                     new Object[]{getSqlTypeName (testReturn),
> -                                                      getName,
> -                                                      getSqlTypeName (type)});
> -     }
> -     /** helperfunction for the getXXX calls to check
> isFunction and index == 1
> -      * @param parameterIndex index of getXXX (index)
> -      * check to make sure is a function and index == 1
> -      */
> -     private void checkIndex (int parameterIndex) throws
> SQLException {
> -         if (!isFunction)
> -             throw new
> PSQLException("postgresql.call.noreturntype");
> -         if (parameterIndex != 1)
> -             throw new
> PSQLException("postgresql.call.noinout");
> -     }
> -
> -     /** helper function for creating msg with type
> names
> -      * @param sqlType a java.sql.Types.XX constant
> -      * @return String which is the name of the
> constant..
> -      */
> -     private static String getSqlTypeName (int sqlType)
> {
> -         switch (sqlType)
> -             {
> -             case Types.BIT:
> -                 return "BIT";
> -             case Types.SMALLINT:
> -                 return "SMALLINT";
> -             case Types.INTEGER:
> -                 return "INTEGER";
> -             case Types.BIGINT:
> -                 return "BIGINT";
> -             case Types.NUMERIC:
> -                 return "NUMERIC";
> -             case Types.REAL:
> -                 return "REAL";
> -             case Types.DOUBLE:
> -                 return "DOUBLE";
> -             case Types.FLOAT:
> -                 return "FLOAT";
> -             case Types.CHAR:
> -                 return "CHAR";
> -             case Types.VARCHAR:
> -                 return "VARCHAR";
> -             case Types.DATE:
> -                 return "DATE";
> -             case Types.TIME:
> -                 return "TIME";
> -             case Types.TIMESTAMP:
> -                 return "TIMESTAMP";
> -             case Types.BINARY:
> -                 return "BINARY";
> -             case Types.VARBINARY:
> -                 return "VARBINARY";
> -             default:
> -                 return "UNKNOWN";
> -             }
> -     }
>   }
>
> --- 367,376 ----
> *** jdbc2/Connection.java    Sat Feb 16 00:33:29 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
> Tue Jan 15 01:55:13 2002
> ***************
> *** 135,145 ****
>
>       public java.sql.CallableStatement
> prepareCall(String sql, int resultSetType, int
> resultSetConcurrency) throws SQLException
>       {
> !         //        throw new
> PSQLException("postgresql.con.call");
> !         CallableStatement s = new
> CallableStatement(this,sql);
> !         s.setResultSetType(resultSetType);
> !         s.setResultSetConcurrency(resultSetConcurrency);
> !         return s;
>       }
>
>       /*
> --- 135,145 ----
>
>       public java.sql.CallableStatement
> prepareCall(String sql, int resultSetType, int
> resultSetConcurrency) throws SQLException
>       {
> !         throw new PSQLException("postgresql.con.call");
> !         //CallableStatement s = new
> CallableStatement(this,sql);
> !         //s.setResultSetType(resultSetType);
> !         //s.setResultSetConcurrency(resultSetConcurrency);
> !         //return s;
>       }
>
>       /*
> ***
> /home/paulb/postgresql-7.2/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
> Thu Feb 21 16:11:28 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
> Tue Jan 15 02:37:33 2002
> ***************
> *** 46,51 ****
> --- 46,54 ----
>
>       /*
>        * Constructor for the PreparedStatement class.
> +      * Split the SQL statement into segments -
> separated by the arguments.
> +      * When we rebuild the thing with the arguments, we
> can substitute the
> +      * args and join the whole thing together.
>        *
>        * @param conn the instanatiating connection
>        * @param sql the SQL statement with ? for IN
> markers
> ***************
> *** 53,88 ****
>        */
>       public PreparedStatement(Connection connection,
> String sql) throws SQLException
>       {
> -         this (connection, sql, true); // need to parse
> -     }
> -
> -     /*
> -      * Constructor for the PreparedStatement class.
> -      *
> -      * @param conn the instanatiating connection
> -      * @param sql the SQL statement with ? for IN
> markers
> -      * @param needsParsing if a descendant (aka
> CallableStmt will do it's own parse)
> -      * @exception SQLException if something bad occurs
> -      */
> -     protected PreparedStatement(Connection connection,
> String sql, boolean needsParsing) throws SQLException
> -     {
>           super(connection);
> -         this.connection = connection;
> -         this.sql = sql;
> -         if (needsParsing)
> -             parseSqlStmt ();
> -     }
>
> -     /**
> -      * Split the SQL statement into segments -
> separated by the arguments.
> -      * When we rebuild the thing with the arguments, we
> can substitute the
> -      * args and join the whole thing together.
> -      */
> -     protected void parseSqlStmt () throws SQLException
> {
>           Vector v = new Vector();
>           boolean inQuotes = false;
>           int lastParmEnd = 0, i;
>
>           for (i = 0; i < sql.length(); ++i)
>           {
>               int c = sql.charAt(i);
> --- 56,70 ----
>        */
>       public PreparedStatement(Connection connection,
> String sql) throws SQLException
>       {
>           super(connection);
>
>           Vector v = new Vector();
>           boolean inQuotes = false;
>           int lastParmEnd = 0, i;
>
> +         this.sql = sql;
> +         this.connection = connection;
> +
>           for (i = 0; i < sql.length(); ++i)
>           {
>               int c = sql.charAt(i);
> ***************
> *** 136,142 ****
>        * This is identical to toString() except it throws
> an exception if a
>        * parameter is unused.
>        */
> !     protected synchronized String compileQuery()
>       throws SQLException
>       {
>           sbuf.setLength(0);
> --- 118,124 ----
>        * This is identical to toString() except it throws
> an exception if a
>        * parameter is unused.
>        */
> !     private synchronized String compileQuery()
>       throws SQLException
>       {
>           sbuf.setLength(0);
> ***************
> *** 832,838 ****
>        * @param s a string to be stored
>        * @exception SQLException if something goes wrong
>        */
> !     protected void set(int paramIndex, String s) throws
> SQLException
>       {
>           if (paramIndex < 1 || paramIndex >
> inStrings.length)
>               throw new PSQLException("postgresql.prep.range");
> --- 814,820 ----
>        * @param s a string to be stored
>        * @exception SQLException if something goes wrong
>        */
> !     private void set(int paramIndex, String s) throws
> SQLException
>       {
>           if (paramIndex < 1 || paramIndex >
> inStrings.length)
>               throw new PSQLException("postgresql.prep.range");
>
> *** errors.properties    Thu Feb 21 14:38:35 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/errors.properties
> Wed Sep  5 23:03:37 2001
> ***************
> *** 72,85 ****
>   postgresql.unusual:Something unusual has occured to
> cause the driver to fail. Please report this
> exception: {0}
>   postgresql.unimplemented:This method is not yet
> implemented.
>   postgresql.unexpected:An unexpected result was
> returned by a query.
> -
> - # proposed changes for CallableStatements
> - postgresql.call.noreturntype:A CallableStatement
> Function was declared but no call to
> 'registerOutParameter (1, <some_type>)' was made.
> - postgresql.call.noinout:PostgreSQL only supports
> function return value [@ 1] (no OUT or INOUT
> arguments)
> - postgresql.call.procasfunc:This Statement [{0}]
> defines a procedure call (needs ?= call <stmt> to be
> considered a function.
> - postgresql.call.malformed:Malformed stmt [{0}] usage
> : {1}
> - postgresql.call.funcover:Cannot execute Query a call
> to setXXX (1, ..) was made where argument 1 is the
> return value of a function.
> - postgresql.call.wrongget:Parameter of type {0} was
> registered but call to get{1} (sqltype={2}) was made.
> - postgresql.call.noreturnval:A CallableStatement
> Function was executed with nothing returned.
> - postgresql.call.wrongrtntype:A CallableStatement
> Function was executed and the return was of type ({0})
> however type={1} was registered.
> -
> --- 72,74 ----
> *** test/JDBC2Tests.java    Wed Feb 20 16:26:46 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
> Mon Nov 19 17:33:39 2001
> ***************
> *** 227,235 ****
>           // Fastpath/LargeObject
>           suite.addTestSuite(BlobTest.class);
>
> -         //Callable Statement
> -         suite.addTestSuite(CallableStmtTest.class);
> -
>           // That's all folks
>           return suite;
>       }
> --- 227,232 ----
> ** new class
> test/jdbc2/CallableStmtTest.java
> package org.postgresql.test.jdbc2;
>
> import org.postgresql.test.JDBC2Tests;
> import junit.framework.TestCase;
> import java.io.*;
> import java.sql.*;
>
> /*
>  * CallableStatement tests.
>  * @author Paul Bethe
>  */
> public class CallableStmtTest extends TestCase
> {
>     private Connection con;
>
>     public CallableStmtTest (String name)
>     {
>         super(name);
>     }
>
>     protected void setUp() throws Exception
>     {
>         con = JDBC2Tests.openDB();
>         Statement stmt = con.createStatement ();
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getString (varchar) " +
>                       "RETURNS varchar AS ' DECLARE inString alias
> for $1; begin "+
>                       "return ''bob''; end; ' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getDouble (float) " +
>                       "RETURNS float AS ' DECLARE inString alias for
> $1; begin " +
>                       "return 42.42; end; ' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getInt (int) RETURNS int " +
>                       " AS 'DECLARE    inString alias for $1; begin " +
>                       "return 42; end;' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getNumeric (numeric) " +
>                       "RETURNS numeric AS ' DECLARE    inString alias
> for $1; " +
>                       "begin    return 42; end; ' LANGUAGE 'plpgsql';");
>         stmt.close ();
>     }
>
>     protected void tearDown() throws Exception
>     {
>         Statement stmt = con.createStatement ();
>         stmt.execute ("drop FUNCTION testspg__getString
> (varchar);");
>         stmt.execute ("drop FUNCTION testspg__getDouble
> (float);");
>         stmt.execute ("drop FUNCTION testspg__getInt
> (int);");
>         stmt.execute ("drop FUNCTION testspg__getNumeric
> (numeric);");
>         JDBC2Tests.closeDB(con);
>     }
>
>
>     final String func = "{ ? = call ";
>     final String pkgName = "testspg__";
>     //    protected void runTest () throws Throwable {
>     //testGetString ();
>     //}
>
>     public void testGetDouble () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.DOUBLE");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getDouble (?) }");
>         call.setDouble (2, (double)3.04);
>         call.registerOutParameter (1, Types.DOUBLE);
>         call.execute ();
>         double result = call.getDouble (1);
>         assertTrue ("correct return from getString ()",
> result == 42.42);
>     }
>
>     public void testGetInt () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.INTEGER");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getInt (?) }");
>         call.setInt (2, 4);
>         call.registerOutParameter (1, Types.INTEGER);
>         call.execute ();
>         int result = call.getInt (1);
>         assertTrue ("correct return from getString ()",
> result == 42);
>     }
>
>     public void testGetNumeric () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.NUMERIC");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getNumeric (?) }");
>         call.setBigDecimal (2, new java.math.BigDecimal(4));
>         call.registerOutParameter (1, Types.NUMERIC);
>         call.execute ();
>         java.math.BigDecimal result = call.getBigDecimal
> (1);
>         assertTrue ("correct return from getString ()",
>                     result.equals (new java.math.BigDecimal(42)));
>     }
>
>     public void testGetString () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.VARCHAR");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getString (?) }");
>         call.setString (2, "foo");
>         call.registerOutParameter (1, Types.VARCHAR);
>         call.execute ();
>         String result = call.getString (1);
>         assertTrue ("correct return from getString ()",
> result.equals ("bob"));
>
>     }
>
> }
>
>
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Sports - Coverage of the 2002 Olympic Games
> http://sports.yahoo.com
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: JDBC CStmt (inline this time)

From
Bruce Momjian
Date:
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.  Requires approval of
jdbc maintainers.

---------------------------------------------------------------------------


Paul Bethe wrote:
> Sorry all for the clutter - I am new to
> listserver/patch style submission I guess the correct
> way is to inline all the files..  sorry for the
> previous attachments.
>
>         Paul B
>
> *** jdbc2/CallableStatement.java    Wed Feb 20 15:29:23
> 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
> Mon Nov 19 17:33:38 2001
> ***************
> *** 7,13 ****
>
>   import java.sql.*;
>   import java.math.*;
> ! import org.postgresql.util.*;
>   /*
>    * CallableStatement is used to execute SQL stored
> procedures.
>    *
> --- 7,13 ----
>
>   import java.sql.*;
>   import java.math.*;
> !
>   /*
>    * CallableStatement is used to execute SQL stored
> procedures.
>    *
> ***************
> *** 46,91 ****
>        */
>       public CallableStatement(Connection c, String q)
> throws SQLException
>       {
> !         super(c, q, false); // don't parse yet..
> !         modifyJdbcCall ();
> !         parseSqlStmt (); // now parse the reformed stmt..
> !     }
> !
> !     /**
> !      * this method will turn a string of the form
> !      * {? = call <some_function> (?, [?,..]) }
> !      * into the PostgreSQL format which is
> !      * select <some_function> (?, [?, ...]) as result
> !      *
> !      */
> !     private void modifyJdbcCall () throws SQLException
> {
> !         originalSql = sql; // save for error msgs..
> !         int index = sql.indexOf ("="); // is implied func
> or proc?
> !         if (index != -1) isFunction = true;
> !         index = sql.indexOf ("call");
> !         if (index == -1)
> !             throw new PSQLException
> ("postgresql.call.malformed",
> !                                      new Object[]{sql, JDBC_SYNTAX});
> !         sql = sql.replace ('{', ' '); // replace these
> characters
> !         sql = sql.replace ('}', ' ');
> !         sql = sql.replace (';', ' ');
> !
> !         sql = (isFunction ? "?" : "") + sql.substring
> (index + 4);
> !         sql = "select " + sql + " as " + RESULT_COLUMN +
> ";";
> !     }
> !
> !     // internals
> !     static final String JDBC_SYNTAX = "{[? =] call
> <some_function> ([? [,?]*]) }";
> !     static final String RESULT_COLUMN = "result";
> !     String originalSql = "";
> !     boolean isFunction;
> !     // functionReturnType contains the user supplied
> value to check
> !     // testReturn contains a modified version to make
> it easier to
> !     // check the getXXX methods..
> !     int functionReturnType;
> !     int testReturn;
> !     boolean returnTypeSet;
> !     Object result;
>
>       /*
>        * Before executing a stored procedure call you
> must explicitly
> --- 46,53 ----
>        */
>       public CallableStatement(Connection c, String q)
> throws SQLException
>       {
> !         super(c, q);
> !     }
>
>       /*
>        * Before executing a stored procedure call you
> must explicitly
> ***************
> *** 96,103 ****
>        * the getXXX method whose Java type XXX
> corresponds to the
>        * parameter's registered SQL type.
>        *
> -      * ONLY 1 RETURN PARAMETER if {?= call ..} syntax
> is used
> -      *
>        * @param parameterIndex the first parameter is 1,
> the second is 2,...
>        * @param sqlType SQL type code defined by
> java.sql.Types; for
>        * parameters of type Numeric or Decimal use the
> version of
> --- 58,63 ----
> ***************
> *** 105,160 ****
>        * @exception SQLException if a database-access
> error occurs.
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType) throws SQLException
> !         {
> !             if (parameterIndex != 1)
> !                 throw new PSQLException
> ("postgresql.call.noinout");
> !             if (!isFunction)
> !                 throw new PSQLException
> ("postgresql.call.procasfunc", originalSql);
> !
> !             // functionReturnType contains the user supplied
> value to check
> !             // testReturn contains a modified version to make
> it easier to
> !             // check the getXXX methods..
> !             functionReturnType = sqlType;
> !             testReturn = sqlType;
> !             if (functionReturnType == Types.CHAR ||
> !                 functionReturnType == Types.LONGVARCHAR)
> !                 testReturn = Types.VARCHAR;
> !             else if (functionReturnType == Types.FLOAT)
> !                 testReturn = Types.REAL; // changes to
> streamline later error checking
> !             returnTypeSet = true;
> !         }
> !
> !     /**
> !      * allow calls to execute update
> !      * @return 1 if succesful call otherwise 0
> !      */
> !     public int executeUpdate() throws SQLException
> !     {
> !         //        System.out.println ("Executing " +
> compileQuery());
> !         java.sql.ResultSet rs = super.executeQuery
> (compileQuery());
> !         if (isFunction) {
> !             if (!rs.next ())
> !                 throw new PSQLException
> ("postgresql.call.noreturnval"); // TODO-props
> !             result = rs.getObject (1);
> !             int columnType = rs.getMetaData().getColumnType
> (1);
> !             if (columnType != functionReturnType)
> !                 throw new PSQLException
> ("postgresql.call.wrongrtntype",
> !                                          new Object[]{
> !                     getSqlTypeName (columnType), getSqlTypeName
> (functionReturnType) });
> !         }
> !         rs.close ();
> !         return 1;
> !     }
> !
> !
> !     /**
> !      * allow calls to execute update
> !      * @return true if succesful
> !      */
> !     public boolean execute() throws SQLException
> !     {
> !         return (executeUpdate() == 1);
> !     }
>
>       /*
>        * You must also specify the scale for
> numeric/decimal types:
> --- 65,71 ----
>        * @exception SQLException if a database-access
> error occurs.
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType) throws SQLException
> !         {}
>
>       /*
>        * You must also specify the scale for
> numeric/decimal types:
> ***************
> *** 171,210 ****
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType,
>                                        int scale) throws SQLException
> !         {
> !             registerOutParameter (parameterIndex, sqlType);
> // ignore for now..
> !         }
> !
> !     /*
> !      * override this method to check for set @ 1 when
> declared function..
> !      *
> !      * @param paramIndex the index into the inString
> !      * @param s a string to be stored
> !      * @exception SQLException if something goes wrong
> !      */
> !     protected void set(int paramIndex, String s) throws
> SQLException
> !     {
> !         if (paramIndex == 1 && isFunction) // need to
> registerOut instead
> !             throw new PSQLException
> ("postgresql.call.funcover");
> !         super.set (paramIndex, s); // else set as usual..
> !     }
> !
> !         /*
> !      * Helper - this compiles the SQL query from the
> various parameters
> !      * This is identical to toString() except it throws
> an exception if a
> !      * parameter is unused.
> !      */
> !     protected synchronized String compileQuery()
> !     throws SQLException
> !     {
> !         if (isFunction && !returnTypeSet)
> !             throw new
> PSQLException("postgresql.call.noreturntype");
> !         if (isFunction) { // set entry 1 to dummy entry..
> !             inStrings[0] = ""; // dummy entry which ensured
> that noone overrode
> !             // and calls to setXXX (2,..) really went to
> first arg in a function call..
> !         }
> !         return super.compileQuery ();
> !     }
>
>       // Old api?
>       //public boolean isNull(int parameterIndex) throws
> SQLException {
> --- 82,88 ----
>        */
>       public void registerOutParameter(int
> parameterIndex, int sqlType,
>                                        int scale) throws SQLException
> !         {}
>
>       // Old api?
>       //public boolean isNull(int parameterIndex) throws
> SQLException {
> ***************
> *** 223,229 ****
>       public boolean wasNull() throws SQLException
>       {
>           // check to see if the last access threw an
> exception
> !         return (result == null);
>       }
>
>       // Old api?
> --- 101,107 ----
>       public boolean wasNull() throws SQLException
>       {
>           // check to see if the last access threw an
> exception
> !         return false; // fake it for now
>       }
>
>       // Old api?
> ***************
> *** 241,248 ****
>        */
>       public String getString(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.VARCHAR,
> "String");
> !         return (String)result;
>       }
>       //public String getVarChar(int parameterIndex)
> throws SQLException {
>       //     return null;
> --- 119,125 ----
>        */
>       public String getString(int parameterIndex) throws
> SQLException
>       {
> !         return null;
>       }
>       //public String getVarChar(int parameterIndex)
> throws SQLException {
>       //     return null;
> ***************
> *** 261,269 ****
>        */
>       public boolean getBoolean(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.BIT, "Boolean");
> !         if (result == null) return false;
> !         return ((Boolean)result).booleanValue ();
>       }
>
>       /*
> --- 138,144 ----
>        */
>       public boolean getBoolean(int parameterIndex)
> throws SQLException
>       {
> !         return false;
>       }
>
>       /*
> ***************
> *** 275,283 ****
>        */
>       public byte getByte(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.TINYINT,
> "Byte");
> !         if (result == null) return 0;
> !         return (byte)((Integer)result).intValue ();
>       }
>
>       /*
> --- 150,156 ----
>        */
>       public byte getByte(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 289,299 ****
>        */
>       public short getShort(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.SMALLINT,
> "Short");
> !         if (result == null) return 0;
> !         return (short)((Integer)result).intValue ();
>       }
> -
>
>       /*
>        * Get the value of an INTEGER parameter as a Java
> int.
> --- 162,169 ----
>        */
>       public short getShort(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
>        * Get the value of an INTEGER parameter as a Java
> int.
> ***************
> *** 304,312 ****
>        */
>       public int getInt(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.INTEGER, "Int");
> !         if (result == null) return 0;
> !         return ((Integer)result).intValue ();
>       }
>
>       /*
> --- 174,180 ----
>        */
>       public int getInt(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 318,326 ****
>        */
>       public long getLong(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.BIGINT, "Long");
> !         if (result == null) return 0;
> !         return ((Long)result).longValue ();
>       }
>
>       /*
> --- 186,192 ----
>        */
>       public long getLong(int parameterIndex) throws
> SQLException
>       {
> !         return 0;
>       }
>
>       /*
> ***************
> *** 332,340 ****
>        */
>       public float getFloat(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.REAL, "Float");
> !         if (result == null) return 0;
> !         return ((Float)result).floatValue ();
>       }
>
>       /*
> --- 198,204 ----
>        */
>       public float getFloat(int parameterIndex) throws
> SQLException
>       {
> !         return (float) 0.0;
>       }
>
>       /*
> ***************
> *** 346,354 ****
>        */
>       public double getDouble(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.DOUBLE,
> "Double");
> !         if (result == null) return 0;
> !         return ((Double)result).doubleValue ();
>       }
>
>       /*
> --- 210,216 ----
>        */
>       public double getDouble(int parameterIndex) throws
> SQLException
>       {
> !         return 0.0;
>       }
>
>       /*
> ***************
> *** 365,372 ****
>       public BigDecimal getBigDecimal(int parameterIndex,
> int scale)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.NUMERIC,
> "BigDecimal");
> !         return ((BigDecimal)result);
>       }
>
>       /*
> --- 227,233 ----
>       public BigDecimal getBigDecimal(int parameterIndex,
> int scale)
>       throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 379,386 ****
>        */
>       public byte[] getBytes(int parameterIndex) throws
> SQLException
>       {
> !         checkIndex (parameterIndex, Types.VARBINARY,
> "Bytes");
> !         return ((byte [])result);
>       }
>
>       // New API (JPM) (getLongVarBinary)
> --- 240,246 ----
>        */
>       public byte[] getBytes(int parameterIndex) throws
> SQLException
>       {
> !         return null;
>       }
>
>       // New API (JPM) (getLongVarBinary)
> ***************
> *** 397,404 ****
>        */
>       public java.sql.Date getDate(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.DATE, "Date");
> !         return (java.sql.Date)result;
>       }
>
>       /*
> --- 257,263 ----
>        */
>       public java.sql.Date getDate(int parameterIndex)
> throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 410,417 ****
>        */
>       public java.sql.Time getTime(int parameterIndex)
> throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.TIME, "Time");
> !         return (java.sql.Time)result;
>       }
>
>       /*
> --- 269,275 ----
>        */
>       public java.sql.Time getTime(int parameterIndex)
> throws SQLException
>       {
> !         return null;
>       }
>
>       /*
> ***************
> *** 424,431 ****
>       public java.sql.Timestamp getTimestamp(int
> parameterIndex)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.TIMESTAMP,
> "Timestamp");
> !         return (java.sql.Timestamp)result;
>       }
>
>
> //----------------------------------------------------------------------
> --- 282,288 ----
>       public java.sql.Timestamp getTimestamp(int
> parameterIndex)
>       throws SQLException
>       {
> !         return null;
>       }
>
>
> //----------------------------------------------------------------------
> ***************
> *** 460,467 ****
>       public Object getObject(int parameterIndex)
>       throws SQLException
>       {
> !         checkIndex (parameterIndex);
> !         return result;
>       }
>
>       // ** JDBC 2 Extensions **
> --- 317,323 ----
>       public Object getObject(int parameterIndex)
>       throws SQLException
>       {
> !         return null;
>       }
>
>       // ** JDBC 2 Extensions **
> ***************
> *** 471,480 ****
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> !     public java.math.BigDecimal getBigDecimal(int
> parameterIndex) throws SQLException
>       {
> !         checkIndex (parameterIndex, Types.NUMERIC,
> "BigDecimal");
> !         return ((BigDecimal)result);
>       }
>
>       public Blob getBlob(int i) throws SQLException
> --- 327,335 ----
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> !     public java.math.BigDecimal getBigDecimal(int i)
> throws SQLException
>       {
> !         throw org.postgresql.Driver.notImplemented();
>       }
>
>       public Blob getBlob(int i) throws SQLException
> ***************
> *** 512,587 ****
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> -     // no custom types allowed yet..
>       public void registerOutParameter(int
> parameterIndex, int sqlType, String typeName) throws
> SQLException
>       {
>           throw org.postgresql.Driver.notImplemented();
>       }
>
> -
> -
> -     /** helperfunction for the getXXX calls to check
> isFunction and index == 1
> -      */
> -     private void checkIndex (int parameterIndex, int
> type, String getName)
> -         throws SQLException {
> -         checkIndex (parameterIndex);
> -         if (type != this.testReturn)
> -             throw new
> PSQLException("postgresql.call.wrongget",
> -                                     new Object[]{getSqlTypeName (testReturn),
> -                                                      getName,
> -                                                      getSqlTypeName (type)});
> -     }
> -     /** helperfunction for the getXXX calls to check
> isFunction and index == 1
> -      * @param parameterIndex index of getXXX (index)
> -      * check to make sure is a function and index == 1
> -      */
> -     private void checkIndex (int parameterIndex) throws
> SQLException {
> -         if (!isFunction)
> -             throw new
> PSQLException("postgresql.call.noreturntype");
> -         if (parameterIndex != 1)
> -             throw new
> PSQLException("postgresql.call.noinout");
> -     }
> -
> -     /** helper function for creating msg with type
> names
> -      * @param sqlType a java.sql.Types.XX constant
> -      * @return String which is the name of the
> constant..
> -      */
> -     private static String getSqlTypeName (int sqlType)
> {
> -         switch (sqlType)
> -             {
> -             case Types.BIT:
> -                 return "BIT";
> -             case Types.SMALLINT:
> -                 return "SMALLINT";
> -             case Types.INTEGER:
> -                 return "INTEGER";
> -             case Types.BIGINT:
> -                 return "BIGINT";
> -             case Types.NUMERIC:
> -                 return "NUMERIC";
> -             case Types.REAL:
> -                 return "REAL";
> -             case Types.DOUBLE:
> -                 return "DOUBLE";
> -             case Types.FLOAT:
> -                 return "FLOAT";
> -             case Types.CHAR:
> -                 return "CHAR";
> -             case Types.VARCHAR:
> -                 return "VARCHAR";
> -             case Types.DATE:
> -                 return "DATE";
> -             case Types.TIME:
> -                 return "TIME";
> -             case Types.TIMESTAMP:
> -                 return "TIMESTAMP";
> -             case Types.BINARY:
> -                 return "BINARY";
> -             case Types.VARBINARY:
> -                 return "VARBINARY";
> -             default:
> -                 return "UNKNOWN";
> -             }
> -     }
>   }
>
> --- 367,376 ----
> *** jdbc2/Connection.java    Sat Feb 16 00:33:29 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
> Tue Jan 15 01:55:13 2002
> ***************
> *** 135,145 ****
>
>       public java.sql.CallableStatement
> prepareCall(String sql, int resultSetType, int
> resultSetConcurrency) throws SQLException
>       {
> !         //        throw new
> PSQLException("postgresql.con.call");
> !         CallableStatement s = new
> CallableStatement(this,sql);
> !         s.setResultSetType(resultSetType);
> !         s.setResultSetConcurrency(resultSetConcurrency);
> !         return s;
>       }
>
>       /*
> --- 135,145 ----
>
>       public java.sql.CallableStatement
> prepareCall(String sql, int resultSetType, int
> resultSetConcurrency) throws SQLException
>       {
> !         throw new PSQLException("postgresql.con.call");
> !         //CallableStatement s = new
> CallableStatement(this,sql);
> !         //s.setResultSetType(resultSetType);
> !         //s.setResultSetConcurrency(resultSetConcurrency);
> !         //return s;
>       }
>
>       /*
> ***
> /home/paulb/postgresql-7.2/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
> Thu Feb 21 16:11:28 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
> Tue Jan 15 02:37:33 2002
> ***************
> *** 46,51 ****
> --- 46,54 ----
>
>       /*
>        * Constructor for the PreparedStatement class.
> +      * Split the SQL statement into segments -
> separated by the arguments.
> +      * When we rebuild the thing with the arguments, we
> can substitute the
> +      * args and join the whole thing together.
>        *
>        * @param conn the instanatiating connection
>        * @param sql the SQL statement with ? for IN
> markers
> ***************
> *** 53,88 ****
>        */
>       public PreparedStatement(Connection connection,
> String sql) throws SQLException
>       {
> -         this (connection, sql, true); // need to parse
> -     }
> -
> -     /*
> -      * Constructor for the PreparedStatement class.
> -      *
> -      * @param conn the instanatiating connection
> -      * @param sql the SQL statement with ? for IN
> markers
> -      * @param needsParsing if a descendant (aka
> CallableStmt will do it's own parse)
> -      * @exception SQLException if something bad occurs
> -      */
> -     protected PreparedStatement(Connection connection,
> String sql, boolean needsParsing) throws SQLException
> -     {
>           super(connection);
> -         this.connection = connection;
> -         this.sql = sql;
> -         if (needsParsing)
> -             parseSqlStmt ();
> -     }
>
> -     /**
> -      * Split the SQL statement into segments -
> separated by the arguments.
> -      * When we rebuild the thing with the arguments, we
> can substitute the
> -      * args and join the whole thing together.
> -      */
> -     protected void parseSqlStmt () throws SQLException
> {
>           Vector v = new Vector();
>           boolean inQuotes = false;
>           int lastParmEnd = 0, i;
>
>           for (i = 0; i < sql.length(); ++i)
>           {
>               int c = sql.charAt(i);
> --- 56,70 ----
>        */
>       public PreparedStatement(Connection connection,
> String sql) throws SQLException
>       {
>           super(connection);
>
>           Vector v = new Vector();
>           boolean inQuotes = false;
>           int lastParmEnd = 0, i;
>
> +         this.sql = sql;
> +         this.connection = connection;
> +
>           for (i = 0; i < sql.length(); ++i)
>           {
>               int c = sql.charAt(i);
> ***************
> *** 136,142 ****
>        * This is identical to toString() except it throws
> an exception if a
>        * parameter is unused.
>        */
> !     protected synchronized String compileQuery()
>       throws SQLException
>       {
>           sbuf.setLength(0);
> --- 118,124 ----
>        * This is identical to toString() except it throws
> an exception if a
>        * parameter is unused.
>        */
> !     private synchronized String compileQuery()
>       throws SQLException
>       {
>           sbuf.setLength(0);
> ***************
> *** 832,838 ****
>        * @param s a string to be stored
>        * @exception SQLException if something goes wrong
>        */
> !     protected void set(int paramIndex, String s) throws
> SQLException
>       {
>           if (paramIndex < 1 || paramIndex >
> inStrings.length)
>               throw new PSQLException("postgresql.prep.range");
> --- 814,820 ----
>        * @param s a string to be stored
>        * @exception SQLException if something goes wrong
>        */
> !     private void set(int paramIndex, String s) throws
> SQLException
>       {
>           if (paramIndex < 1 || paramIndex >
> inStrings.length)
>               throw new PSQLException("postgresql.prep.range");
>
> *** errors.properties    Thu Feb 21 14:38:35 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/errors.properties
> Wed Sep  5 23:03:37 2001
> ***************
> *** 72,85 ****
>   postgresql.unusual:Something unusual has occured to
> cause the driver to fail. Please report this
> exception: {0}
>   postgresql.unimplemented:This method is not yet
> implemented.
>   postgresql.unexpected:An unexpected result was
> returned by a query.
> -
> - # proposed changes for CallableStatements
> - postgresql.call.noreturntype:A CallableStatement
> Function was declared but no call to
> 'registerOutParameter (1, <some_type>)' was made.
> - postgresql.call.noinout:PostgreSQL only supports
> function return value [@ 1] (no OUT or INOUT
> arguments)
> - postgresql.call.procasfunc:This Statement [{0}]
> defines a procedure call (needs ?= call <stmt> to be
> considered a function.
> - postgresql.call.malformed:Malformed stmt [{0}] usage
> : {1}
> - postgresql.call.funcover:Cannot execute Query a call
> to setXXX (1, ..) was made where argument 1 is the
> return value of a function.
> - postgresql.call.wrongget:Parameter of type {0} was
> registered but call to get{1} (sqltype={2}) was made.
> - postgresql.call.noreturnval:A CallableStatement
> Function was executed with nothing returned.
> - postgresql.call.wrongrtntype:A CallableStatement
> Function was executed and the return was of type ({0})
> however type={1} was registered.
> -
> --- 72,74 ----
> *** test/JDBC2Tests.java    Wed Feb 20 16:26:46 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
> Mon Nov 19 17:33:39 2001
> ***************
> *** 227,235 ****
>           // Fastpath/LargeObject
>           suite.addTestSuite(BlobTest.class);
>
> -         //Callable Statement
> -         suite.addTestSuite(CallableStmtTest.class);
> -
>           // That's all folks
>           return suite;
>       }
> --- 227,232 ----
> ** new class
> test/jdbc2/CallableStmtTest.java
> package org.postgresql.test.jdbc2;
>
> import org.postgresql.test.JDBC2Tests;
> import junit.framework.TestCase;
> import java.io.*;
> import java.sql.*;
>
> /*
>  * CallableStatement tests.
>  * @author Paul Bethe
>  */
> public class CallableStmtTest extends TestCase
> {
>     private Connection con;
>
>     public CallableStmtTest (String name)
>     {
>         super(name);
>     }
>
>     protected void setUp() throws Exception
>     {
>         con = JDBC2Tests.openDB();
>         Statement stmt = con.createStatement ();
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getString (varchar) " +
>                       "RETURNS varchar AS ' DECLARE inString alias
> for $1; begin "+
>                       "return ''bob''; end; ' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getDouble (float) " +
>                       "RETURNS float AS ' DECLARE inString alias for
> $1; begin " +
>                       "return 42.42; end; ' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getInt (int) RETURNS int " +
>                       " AS 'DECLARE    inString alias for $1; begin " +
>                       "return 42; end;' LANGUAGE 'plpgsql';");
>         stmt.execute ("CREATE OR REPLACE FUNCTION
> testspg__getNumeric (numeric) " +
>                       "RETURNS numeric AS ' DECLARE    inString alias
> for $1; " +
>                       "begin    return 42; end; ' LANGUAGE 'plpgsql';");
>         stmt.close ();
>     }
>
>     protected void tearDown() throws Exception
>     {
>         Statement stmt = con.createStatement ();
>         stmt.execute ("drop FUNCTION testspg__getString
> (varchar);");
>         stmt.execute ("drop FUNCTION testspg__getDouble
> (float);");
>         stmt.execute ("drop FUNCTION testspg__getInt
> (int);");
>         stmt.execute ("drop FUNCTION testspg__getNumeric
> (numeric);");
>         JDBC2Tests.closeDB(con);
>     }
>
>
>     final String func = "{ ? = call ";
>     final String pkgName = "testspg__";
>     //    protected void runTest () throws Throwable {
>     //testGetString ();
>     //}
>
>     public void testGetDouble () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.DOUBLE");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getDouble (?) }");
>         call.setDouble (2, (double)3.04);
>         call.registerOutParameter (1, Types.DOUBLE);
>         call.execute ();
>         double result = call.getDouble (1);
>         assertTrue ("correct return from getString ()",
> result == 42.42);
>     }
>
>     public void testGetInt () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.INTEGER");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getInt (?) }");
>         call.setInt (2, 4);
>         call.registerOutParameter (1, Types.INTEGER);
>         call.execute ();
>         int result = call.getInt (1);
>         assertTrue ("correct return from getString ()",
> result == 42);
>     }
>
>     public void testGetNumeric () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.NUMERIC");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getNumeric (?) }");
>         call.setBigDecimal (2, new java.math.BigDecimal(4));
>         call.registerOutParameter (1, Types.NUMERIC);
>         call.execute ();
>         java.math.BigDecimal result = call.getBigDecimal
> (1);
>         assertTrue ("correct return from getString ()",
>                     result.equals (new java.math.BigDecimal(42)));
>     }
>
>     public void testGetString () throws Throwable {
>         // System.out.println ("Testing CallableStmt
> Types.VARCHAR");
>         CallableStatement call = con.prepareCall (func +
> pkgName + "getString (?) }");
>         call.setString (2, "foo");
>         call.registerOutParameter (1, Types.VARCHAR);
>         call.execute ();
>         String result = call.getString (1);
>         assertTrue ("correct return from getString ()",
> result.equals ("bob"));
>
>     }
>
> }
>
>
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Sports - Coverage of the 2002 Olympic Games
> http://sports.yahoo.com
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: JDBC CStmt (inline this time)

From
Bruce Momjian
Date:
Paul, I have talked to the JDBC folks and they asked if you would
recreate a patch against the current PostgreSQL CVS for them to apply.
They are having trouble applying it.

I know you submitted it long ago (Feb 20), and that it is a pain to redo
it, but we would appreciate it.

---------------------------------------------------------------------------

Paul Bethe wrote:
> Sorry all for the clutter - I am new to
> listserver/patch style submission I guess the correct
> way is to inline all the files..  sorry for the
> previous attachments.
>
>         Paul B
>
> *** jdbc2/CallableStatement.java    Wed Feb 20 15:29:23
> 2002
> ---
> /home/paulb/Development/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
> Mon Nov 19 17:33:38 2001
> ***************
> *** 7,13 ****
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026