aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Lind <barry@xythos.com>2003-05-03 20:40:45 +0000
committerBarry Lind <barry@xythos.com>2003-05-03 20:40:45 +0000
commit5295fffc26d9bb02fc3b51cbb4f7de744ee50046 (patch)
tree73ca858d05b3272bdd243aaadc927dafdf8d2467
parent721996d88906393b5f9fb4191e8c54726fa478fc (diff)
downloadpostgresql-5295fffc26d9bb02fc3b51cbb4f7de744ee50046.tar.gz
postgresql-5295fffc26d9bb02fc3b51cbb4f7de744ee50046.zip
Patch to fix up LONGVARBINARY support submitted by Amit Gollapudi
(agollapudi@demandsolutions.com). Also applied the RefCursor support patch by Nic Ferrier. This patch allows you too return a get a result set from a function that returns a refcursor. For example: call.registerOutParameter(1, Types.OTHER); call.execute(); ResultSet rs = (ResultSet) call.getObject(1); Modified Files: jdbc/org/postgresql/core/BaseStatement.java jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java jdbc/org/postgresql/jdbc1/Jdbc1Statement.java jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java jdbc/org/postgresql/jdbc2/Jdbc2Statement.java jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java jdbc/org/postgresql/jdbc3/Jdbc3Statement.java Added Files: jdbc/org/postgresql/PGRefCursorResultSet.java jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java jdbc/org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java jdbc/org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java jdbc/org/postgresql/test/jdbc2/RefCursorTest.java
-rw-r--r--src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java25
-rw-r--r--src/interfaces/jdbc/org/postgresql/core/BaseStatement.java7
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java9
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java4
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java44
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java8
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java9
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java6
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java7
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java43
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java8
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java5
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java10
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java47
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java7
-rw-r--r--src/interfaces/jdbc/org/postgresql/test/jdbc2/RefCursorTest.java100
18 files changed, 340 insertions, 11 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java
new file mode 100644
index 00000000000..2594c7e1d0d
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+ *
+ * PGRefCursorResultSet.java
+ * Describes a PLPGSQL refcursor type.
+ *
+ * Copyright (c) 2003, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGRefCursorResultSet.java,v 1.1 2003/05/03 20:40:45 barry Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+package org.postgresql;
+
+
+/** A ref cursor based result set.
+ */
+public interface PGRefCursorResultSet
+{
+
+ /** return the name of the cursor.
+ */
+ public String getRefCursor ();
+
+}
diff --git a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java b/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java
index c7432d2016f..dc5ffbdf787 100644
--- a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java
@@ -6,19 +6,20 @@
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.1 2003/03/07 18:39:41 barry Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.2 2003/05/03 20:40:45 barry Exp $
*
*-------------------------------------------------------------------------
*/
package org.postgresql.core;
-
+import org.postgresql.PGRefCursorResultSet;
import java.sql.*;
import java.util.Vector;
public interface BaseStatement extends org.postgresql.PGStatement
{
- public BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
+ public BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
+ public PGRefCursorResultSet createRefCursorResultSet(String cursorName) throws SQLException;
public BaseConnection getPGConnection();
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
index 99e42b5c92c..ee1db017cf9 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
@@ -9,7 +9,7 @@
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.11 2003/03/08 06:06:55 barry Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.12 2003/05/03 20:40:45 barry Exp $
*
*-------------------------------------------------------------------------
*/
@@ -575,11 +575,18 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
return getBytes(columnIndex);
default:
String type = field.getPGType();
+
// if the backend doesn't know the type then coerce to String
if (type.equals("unknown"))
{
return getString(columnIndex);
}
+ // Specialized support for ref cursors is neater.
+ else if (type.equals("refcursor"))
+ {
+ String cursorName = getString(columnIndex);
+ return statement.createRefCursorResultSet(cursorName);
+ }
else
{
return connection.getObject(field.getPGType(), getString(columnIndex));
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
index 8f39d2bb24c..c473dd240bd 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
@@ -13,7 +13,7 @@ import org.postgresql.core.QueryExecutor;
import org.postgresql.largeobject.*;
import org.postgresql.util.*;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.20 2003/04/17 04:37:07 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.21 2003/05/03 20:40:45 barry Exp $
* This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@@ -871,6 +871,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
break;
case Types.BINARY:
case Types.VARBINARY:
+ case Types.LONGVARBINARY:
l_pgType = PG_BYTEA;
break;
case Types.OTHER:
@@ -1490,6 +1491,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
break;
case Types.BINARY:
case Types.VARBINARY:
+ case Types.LONGVARBINARY:
setObject(parameterIndex, x);
break;
case Types.OTHER:
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java
index bb30580c3c5..697a1869ab7 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java
@@ -3,6 +3,7 @@ package org.postgresql.jdbc1;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
@@ -18,5 +19,10 @@ public class Jdbc1CallableStatement extends AbstractJdbc1Statement implements ja
{
return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc1RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
index 87e64d69064..a80928ebddf 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
@@ -2,6 +2,7 @@ package org.postgresql.jdbc1;
import java.sql.*;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
@@ -17,4 +18,9 @@ public class Jdbc1PreparedStatement extends AbstractJdbc1Statement implements Pr
{
return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc1RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java
new file mode 100644
index 00000000000..7b83bf67427
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java
@@ -0,0 +1,44 @@
+package org.postgresql.jdbc1;
+
+import java.sql.SQLException;
+import org.postgresql.core.QueryExecutor;
+import org.postgresql.core.BaseStatement;
+import org.postgresql.PGRefCursorResultSet;
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc1RefCursorResultSet extends Jdbc1ResultSet
+ implements PGRefCursorResultSet
+{
+
+ // The name of the cursor being used.
+ String refCursorHandle;
+
+ // Indicates when the result set has activaly bound to the cursor.
+ boolean isInitialized = false;
+
+
+ Jdbc1RefCursorResultSet(BaseStatement statement, String refCursorName)
+ {
+ super(statement, null, null, null, -1, 0L, false);
+ this.refCursorHandle = refCursorName;
+ }
+
+ public String getRefCursor ()
+ {
+ return refCursorHandle;
+ }
+
+ public boolean next () throws SQLException
+ {
+ if (isInitialized)
+ return super.next();
+ // Initialize this res set with the rows from the cursor.
+ String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+ QueryExecutor.execute(toExec, new String[0], this);
+ isInitialized = true;
+ return super.next();
+ }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
index 67cb91b32e6..38edfd87e0d 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
@@ -3,10 +3,11 @@ package org.postgresql.jdbc1;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.5 2003/03/07 18:39:44 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.6 2003/05/03 20:40:45 barry Exp $
* This class implements the java.sql.Statement interface for JDBC1.
* However most of the implementation is really done in
* org.postgresql.jdbc1.AbstractJdbc1Statement
@@ -23,4 +24,9 @@ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement
{
return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc1RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
index 46ebdb47cec..21514235027 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
@@ -9,7 +9,7 @@
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.18 2003/03/25 02:24:07 davec Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.19 2003/05/03 20:40:45 barry Exp $
*
*-------------------------------------------------------------------------
*/
@@ -148,11 +148,18 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
default:
String type = field.getPGType();
+
// if the backend doesn't know the type then coerce to String
if (type.equals("unknown"))
{
return getString(columnIndex);
}
+ // Specialized support for ref cursors is neater.
+ else if (type.equals("refcursor"))
+ {
+ String cursorName = getString(columnIndex);
+ return statement.createRefCursorResultSet(cursorName);
+ }
else
{
return connection.getObject(field.getPGType(), getString(columnIndex));
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
index 5b8e76e122d..e10223e975c 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java
@@ -3,6 +3,7 @@ package org.postgresql.jdbc2;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
@@ -18,5 +19,10 @@ public class Jdbc2CallableStatement extends org.postgresql.jdbc2.AbstractJdbc2St
{
return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc2RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
index 4eeded05fdc..83023f05f44 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
@@ -3,6 +3,7 @@ package org.postgresql.jdbc2;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
@@ -18,5 +19,11 @@ public class Jdbc2PreparedStatement extends org.postgresql.jdbc2.AbstractJdbc2St
{
return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc2RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java
new file mode 100644
index 00000000000..08ec33d752f
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java
@@ -0,0 +1,43 @@
+package org.postgresql.jdbc2;
+
+
+import org.postgresql.core.QueryExecutor;
+import org.postgresql.core.BaseStatement;
+import org.postgresql.PGRefCursorResultSet;
+
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc2RefCursorResultSet extends Jdbc2ResultSet
+ implements PGRefCursorResultSet
+{
+
+ String refCursorHandle;
+
+ // Indicates when the result set has activaly bound to the cursor.
+ boolean isInitialized = false;
+
+ Jdbc2RefCursorResultSet(BaseStatement statement, String refCursorName) throws java.sql.SQLException
+ {
+ super(statement, null, null, null, -1, 0L, false);
+ this.refCursorHandle = refCursorName;
+ }
+
+ public String getRefCursor ()
+ {
+ return refCursorHandle;
+ }
+
+ public boolean next () throws java.sql.SQLException
+ {
+ if (isInitialized)
+ return super.next();
+ // Initialize this res set with the rows from the cursor.
+ String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+ QueryExecutor.execute(toExec, new String[0], this);
+ isInitialized = true;
+ return super.next();
+ }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
index a1328dd3fba..eb78a889b36 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
@@ -3,10 +3,11 @@ package org.postgresql.jdbc2;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.5 2003/03/07 18:39:45 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.6 2003/05/03 20:40:45 barry Exp $
* This class implements the java.sql.Statement interface for JDBC2.
* However most of the implementation is really done in
* org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents
@@ -23,4 +24,9 @@ public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement
{
return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc2RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java
index 2b71e192cfe..0008f0e98ca 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java
@@ -3,6 +3,7 @@ package org.postgresql.jdbc3;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
@@ -19,5 +20,9 @@ public class Jdbc3CallableStatement extends org.postgresql.jdbc3.AbstractJdbc3St
return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc3RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java
index 229a4353cd4..e9e25f76b02 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java
@@ -2,7 +2,9 @@ package org.postgresql.jdbc3;
import java.sql.*;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
+import org.postgresql.core.BaseStatement;
import org.postgresql.core.Field;
public class Jdbc3PreparedStatement extends org.postgresql.jdbc3.AbstractJdbc3Statement implements java.sql.PreparedStatement
@@ -15,8 +17,12 @@ public class Jdbc3PreparedStatement extends org.postgresql.jdbc3.AbstractJdbc3St
public BaseResultSet createResultSet (Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
{
- return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ return new Jdbc3ResultSet((BaseStatement)this, fields, tuples, status, updateCount, insertOID, binaryCursor);
+ }
+
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc3RefCursorResultSet(this, cursorName);
}
-
}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java
new file mode 100644
index 00000000000..fe18672a7b3
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java
@@ -0,0 +1,47 @@
+package org.postgresql.jdbc3;
+
+import org.postgresql.core.QueryExecutor;
+import org.postgresql.core.Field;
+import org.postgresql.core.BaseStatement;
+import java.util.Vector;
+import org.postgresql.PGConnection;
+import org.postgresql.PGRefCursorResultSet;
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc3RefCursorResultSet extends Jdbc3ResultSet implements PGRefCursorResultSet
+{
+
+ String refCursorHandle;
+
+ // Indicates when the result set has activaly bound to the cursor.
+ boolean isInitialized = false;
+
+ Jdbc3RefCursorResultSet(java.sql.Statement statement, String refCursorName) throws java.sql.SQLException
+ {
+ // This casting is a GCJ requirement.
+ super((BaseStatement)statement,
+ (Field[])null,
+ (Vector)null,
+ (String)null, -1, 0L, false);
+ this.refCursorHandle = refCursorName;
+ }
+
+ public String getRefCursor ()
+ {
+ return refCursorHandle;
+ }
+
+ public boolean next () throws java.sql.SQLException
+ {
+ if (isInitialized)
+ return super.next();
+ // Initialize this res set with the rows from the cursor.
+ String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+ QueryExecutor.execute(toExec, new String[0], this);
+ isInitialized = true;
+ return super.next();
+ }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java
index aa8cf00ca63..eedea2f5f05 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java
@@ -3,10 +3,11 @@ package org.postgresql.jdbc3;
import java.sql.*;
import java.util.Vector;
+import org.postgresql.PGRefCursorResultSet;
import org.postgresql.core.BaseResultSet;
import org.postgresql.core.Field;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.4 2003/03/07 18:39:45 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.5 2003/05/03 20:40:45 barry Exp $
* This class implements the java.sql.Statement interface for JDBC3.
* However most of the implementation is really done in
* org.postgresql.jdbc3.AbstractJdbc3Statement or one of it's parents
@@ -24,4 +25,8 @@ public class Jdbc3Statement extends org.postgresql.jdbc3.AbstractJdbc3Statement
return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor);
}
+ public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException
+ {
+ return new Jdbc3RefCursorResultSet(this, cursorName);
+ }
}
diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/RefCursorTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/RefCursorTest.java
new file mode 100644
index 00000000000..a3ce71cb155
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/RefCursorTest.java
@@ -0,0 +1,100 @@
+package org.postgresql.test.jdbc2;
+
+import org.postgresql.test.TestUtil;
+import junit.framework.TestCase;
+import java.io.*;
+import java.sql.*;
+
+/*
+ * RefCursor ResultSet tests.
+ * This test case is basically the same as the ResultSet test case.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class RefCursorTest extends TestCase
+{
+ private Connection con;
+
+ public RefCursorTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ // this is the same as the ResultSet setup.
+ con = TestUtil.openDB();
+ Statement stmt = con.createStatement();
+
+ TestUtil.createTable(con, "testrs", "id integer");
+
+ stmt.executeUpdate("INSERT INTO testrs VALUES (1)");
+ stmt.executeUpdate("INSERT INTO testrs VALUES (2)");
+ stmt.executeUpdate("INSERT INTO testrs VALUES (3)");
+ stmt.executeUpdate("INSERT INTO testrs VALUES (4)");
+ stmt.executeUpdate("INSERT INTO testrs VALUES (6)");
+ stmt.executeUpdate("INSERT INTO testrs VALUES (9)");
+
+
+ // Create the functions.
+ stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getRefcursor () RETURNS refcursor AS '"
+ + "declare v_resset; begin open v_resset for select id from testrs order by id; "
+ + "return v_resset; end;' LANGUAGE 'plpgsql';");
+ stmt.execute ("CREATE OR REPLACE FUNCTION testspg__getEmptyRefcursor () RETURNS refcursor AS '"
+ + "declare v_resset; begin open v_resset for select id from testrs where id < 1 order by id; "
+ + "return v_resset; end;' LANGUAGE 'plpgsql';");
+ stmt.close();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ Statement stmt = con.createStatement ();
+ stmt.execute ("drop FUNCTION testspg__getRefcursor ();");
+ stmt.execute ("drop FUNCTION testspg__getEmptyRefcursor ();");
+ TestUtil.dropTable(con, "testrs");
+ TestUtil.closeDB(con);
+ }
+
+ public void testResult() throws Exception
+ {
+ CallableStatement call = con.prepareCall("{ ? = call testspg__getRefcursor () }");
+ call.registerOutParameter(1, Types.OTHER);
+ call.execute();
+ ResultSet rs = (ResultSet) call.getObject(1);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 1);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 2);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 3);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 4);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 6);
+
+ assertTrue(rs.next());
+ assertTrue(rs.getInt(1) == 9);
+
+ assertTrue(!rs.next());
+
+ call.close();
+ }
+
+
+ public void testEmptyResult() throws Exception
+ {
+ CallableStatement call = con.prepareCall("{ ? = call testspg__getRefcursor () }");
+ call.registerOutParameter(1, Types.OTHER);
+ call.execute();
+
+ ResultSet rs = (ResultSet) call.getObject(1);
+ assertTrue(!rs.next());
+
+ call.close();
+ }
+}