Neil Conway wrote:
I think changing SPI_cursor_fetch() and SPI_cursor_move() to take a "long" for the "count" parameter is the right fix for HEAD.

Attached is a patch that implements this. A bunch of functions had to be updated: SPI_execute(), SPI_execute_snapshot(), SPI_exec(), SPI_execp(), SPI_execute_plan(), SPI_cursor_fetch(), and SPI_cursor_move().


I also updated PL/Python, which was invoking SPI_execute() with an `int' parameter. PL/Tcl could be updated as well, but it seems the base Tcl package doesn't provide a Tcl_GetLong() function. PL/Perl could also be updated (plperl_spi_exec()), but I don't know XS, so I will leave that to someone else.

Barring any objections, I'll apply this to HEAD tomorrow.

-Neil
Index: doc/src/sgml/spi.sgml
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/doc/src/sgml/spi.sgml,v
retrieving revision 1.40
diff -c -r1.40 spi.sgml
*** doc/src/sgml/spi.sgml	29 Mar 2005 02:53:53 -0000	1.40
--- doc/src/sgml/spi.sgml	1 May 2005 06:29:47 -0000
***************
*** 292,298 ****
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_execute(const char * <parameter>command</parameter>, bool <parameter>read_only</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 292,298 ----
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_execute(const char * <parameter>command</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 423,429 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
--- 423,429 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
***************
*** 598,604 ****
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_exec(const char * <parameter>command</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 598,604 ----
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 627,633 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
--- 627,633 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
***************
*** 963,969 ****
   <refsynopsisdiv>
  <synopsis>
  int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
!                      bool <parameter>read_only</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 963,969 ----
   <refsynopsisdiv>
  <synopsis>
  int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
!                      bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 1030,1036 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
--- 1030,1036 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
***************
*** 1104,1110 ****
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 1104,1110 ----
  
   <refsynopsisdiv>
  <synopsis>
! int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 1162,1168 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
--- 1162,1168 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to process or return
***************
*** 1375,1381 ****
  
   <refsynopsisdiv>
  <synopsis>
! void SPI_cursor_fetch(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 1375,1381 ----
  
   <refsynopsisdiv>
  <synopsis>
! void SPI_cursor_fetch(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 1411,1417 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to fetch
--- 1411,1417 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to fetch
***************
*** 1448,1454 ****
  
   <refsynopsisdiv>
  <synopsis>
! void SPI_cursor_move(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, int <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
--- 1448,1454 ----
  
   <refsynopsisdiv>
  <synopsis>
! void SPI_cursor_move(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 1485,1491 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>int <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to move
--- 1485,1491 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>long <parameter>count</parameter></literal></term>
      <listitem>
       <para>
        maximum number of rows to move
Index: src/backend/executor/spi.c
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/backend/executor/spi.c,v
retrieving revision 1.137
diff -c -r1.137 spi.c
*** src/backend/executor/spi.c	29 Mar 2005 02:53:53 -0000	1.137
--- src/backend/executor/spi.c	1 May 2005 06:27:14 -0000
***************
*** 39,51 ****
  static int _SPI_execute_plan(_SPI_plan *plan,
  							 Datum *Values, const char *Nulls,
  							 Snapshot snapshot, Snapshot crosscheck_snapshot,
! 							 bool read_only, int tcount);
  
! static int _SPI_pquery(QueryDesc *queryDesc, int tcount);
  
  static void _SPI_error_callback(void *arg);
  
! static void _SPI_cursor_operation(Portal portal, bool forward, int count,
  					  DestReceiver *dest);
  
  static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location);
--- 39,51 ----
  static int _SPI_execute_plan(_SPI_plan *plan,
  							 Datum *Values, const char *Nulls,
  							 Snapshot snapshot, Snapshot crosscheck_snapshot,
! 							 bool read_only, long tcount);
  
! static int _SPI_pquery(QueryDesc *queryDesc, long tcount);
  
  static void _SPI_error_callback(void *arg);
  
! static void _SPI_cursor_operation(Portal portal, bool forward, long count,
  					  DestReceiver *dest);
  
  static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location);
***************
*** 278,286 ****
  	_SPI_curid = _SPI_connected - 1;
  }
  
! /* Parse, plan, and execute a querystring */
  int
! SPI_execute(const char *src, bool read_only, int tcount)
  {
  	_SPI_plan	plan;
  	int			res;
--- 278,286 ----
  	_SPI_curid = _SPI_connected - 1;
  }
  
! /* Parse, plan, and execute a query string */
  int
! SPI_execute(const char *src, bool read_only, long tcount)
  {
  	_SPI_plan	plan;
  	int			res;
***************
*** 309,315 ****
  
  /* Obsolete version of SPI_execute */
  int
! SPI_exec(const char *src, int tcount)
  {
  	return SPI_execute(src, false, tcount);
  }
--- 309,315 ----
  
  /* Obsolete version of SPI_execute */
  int
! SPI_exec(const char *src, long tcount)
  {
  	return SPI_execute(src, false, tcount);
  }
***************
*** 317,323 ****
  /* Execute a previously prepared plan */
  int
  SPI_execute_plan(void *plan, Datum *Values, const char *Nulls,
! 				 bool read_only, int tcount)
  {
  	int			res;
  
--- 317,323 ----
  /* Execute a previously prepared plan */
  int
  SPI_execute_plan(void *plan, Datum *Values, const char *Nulls,
! 				 bool read_only, long tcount)
  {
  	int			res;
  
***************
*** 342,348 ****
  
  /* Obsolete version of SPI_execute_plan */
  int
! SPI_execp(void *plan, Datum *Values, const char *Nulls, int tcount)
  {
  	return SPI_execute_plan(plan, Values, Nulls, false, tcount);
  }
--- 342,348 ----
  
  /* Obsolete version of SPI_execute_plan */
  int
! SPI_execp(void *plan, Datum *Values, const char *Nulls, long tcount)
  {
  	return SPI_execute_plan(plan, Values, Nulls, false, tcount);
  }
***************
*** 360,366 ****
  SPI_execute_snapshot(void *plan,
  					 Datum *Values, const char *Nulls,
  					 Snapshot snapshot, Snapshot crosscheck_snapshot,
! 					 bool read_only, int tcount)
  {
  	int			res;
  
--- 360,366 ----
  SPI_execute_snapshot(void *plan,
  					 Datum *Values, const char *Nulls,
  					 Snapshot snapshot, Snapshot crosscheck_snapshot,
! 					 bool read_only, long tcount)
  {
  	int			res;
  
***************
*** 989,995 ****
   *	Fetch rows in a cursor
   */
  void
! SPI_cursor_fetch(Portal portal, bool forward, int count)
  {
  	_SPI_cursor_operation(portal, forward, count,
  						  CreateDestReceiver(SPI, NULL));
--- 989,995 ----
   *	Fetch rows in a cursor
   */
  void
! SPI_cursor_fetch(Portal portal, bool forward, long count)
  {
  	_SPI_cursor_operation(portal, forward, count,
  						  CreateDestReceiver(SPI, NULL));
***************
*** 1003,1009 ****
   *	Move in a cursor
   */
  void
! SPI_cursor_move(Portal portal, bool forward, int count)
  {
  	_SPI_cursor_operation(portal, forward, count, None_Receiver);
  }
--- 1003,1009 ----
   *	Move in a cursor
   */
  void
! SPI_cursor_move(Portal portal, bool forward, long count)
  {
  	_SPI_cursor_operation(portal, forward, count, None_Receiver);
  }
***************
*** 1319,1325 ****
  static int
  _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
  				  Snapshot snapshot, Snapshot crosscheck_snapshot,
! 				  bool read_only, int tcount)
  {
  	volatile int res = 0;
  	Snapshot	saveActiveSnapshot;
--- 1319,1325 ----
  static int
  _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
  				  Snapshot snapshot, Snapshot crosscheck_snapshot,
! 				  bool read_only, long tcount)
  {
  	volatile int res = 0;
  	Snapshot	saveActiveSnapshot;
***************
*** 1503,1509 ****
  }
  
  static int
! _SPI_pquery(QueryDesc *queryDesc, int tcount)
  {
  	int			operation = queryDesc->operation;
  	int			res;
--- 1503,1509 ----
  }
  
  static int
! _SPI_pquery(QueryDesc *queryDesc, long tcount)
  {
  	int			operation = queryDesc->operation;
  	int			res;
***************
*** 1541,1547 ****
  
  	ExecutorStart(queryDesc, false);
  
! 	ExecutorRun(queryDesc, ForwardScanDirection, (long) tcount);
  
  	_SPI_current->processed = queryDesc->estate->es_processed;
  	save_lastoid = queryDesc->estate->es_lastoid;
--- 1541,1547 ----
  
  	ExecutorStart(queryDesc, false);
  
! 	ExecutorRun(queryDesc, ForwardScanDirection, tcount);
  
  	_SPI_current->processed = queryDesc->estate->es_processed;
  	save_lastoid = queryDesc->estate->es_lastoid;
***************
*** 1609,1615 ****
   *	Do a FETCH or MOVE in a cursor
   */
  static void
! _SPI_cursor_operation(Portal portal, bool forward, int count,
  					  DestReceiver *dest)
  {
  	long		nfetched;
--- 1609,1615 ----
   *	Do a FETCH or MOVE in a cursor
   */
  static void
! _SPI_cursor_operation(Portal portal, bool forward, long count,
  					  DestReceiver *dest)
  {
  	long		nfetched;
***************
*** 1631,1637 ****
  	/* Run the cursor */
  	nfetched = PortalRunFetch(portal,
  							  forward ? FETCH_FORWARD : FETCH_BACKWARD,
! 							  (long) count,
  							  dest);
  
  	/*
--- 1631,1637 ----
  	/* Run the cursor */
  	nfetched = PortalRunFetch(portal,
  							  forward ? FETCH_FORWARD : FETCH_BACKWARD,
! 							  count,
  							  dest);
  
  	/*
Index: src/include/executor/spi.h
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/include/executor/spi.h,v
retrieving revision 1.51
diff -c -r1.51 spi.h
*** src/include/executor/spi.h	29 Mar 2005 02:53:53 -0000	1.51
--- src/include/executor/spi.h	1 May 2005 06:26:30 -0000
***************
*** 82,98 ****
  extern void SPI_push(void);
  extern void SPI_pop(void);
  extern void SPI_restore_connection(void);
! extern int	SPI_execute(const char *src, bool read_only, int tcount);
  extern int	SPI_execute_plan(void *plan, Datum *Values, const char *Nulls,
! 							 bool read_only, int tcount);
! extern int	SPI_exec(const char *src, int tcount);
  extern int	SPI_execp(void *plan, Datum *Values, const char *Nulls,
! 					  int tcount);
  extern int	SPI_execute_snapshot(void *plan,
  								 Datum *Values, const char *Nulls,
  								 Snapshot snapshot,
  								 Snapshot crosscheck_snapshot,
! 								 bool read_only, int tcount);
  extern void *SPI_prepare(const char *src, int nargs, Oid *argtypes);
  extern void *SPI_saveplan(void *plan);
  extern int	SPI_freeplan(void *plan);
--- 82,98 ----
  extern void SPI_push(void);
  extern void SPI_pop(void);
  extern void SPI_restore_connection(void);
! extern int	SPI_execute(const char *src, bool read_only, long tcount);
  extern int	SPI_execute_plan(void *plan, Datum *Values, const char *Nulls,
! 							 bool read_only, long tcount);
! extern int	SPI_exec(const char *src, long tcount);
  extern int	SPI_execp(void *plan, Datum *Values, const char *Nulls,
! 					  long tcount);
  extern int	SPI_execute_snapshot(void *plan,
  								 Datum *Values, const char *Nulls,
  								 Snapshot snapshot,
  								 Snapshot crosscheck_snapshot,
! 								 bool read_only, long tcount);
  extern void *SPI_prepare(const char *src, int nargs, Oid *argtypes);
  extern void *SPI_saveplan(void *plan);
  extern int	SPI_freeplan(void *plan);
***************
*** 123,130 ****
  extern Portal SPI_cursor_open(const char *name, void *plan,
  				Datum *Values, const char *Nulls, bool read_only);
  extern Portal SPI_cursor_find(const char *name);
! extern void SPI_cursor_fetch(Portal portal, bool forward, int count);
! extern void SPI_cursor_move(Portal portal, bool forward, int count);
  extern void SPI_cursor_close(Portal portal);
  
  extern void AtEOXact_SPI(bool isCommit);
--- 123,130 ----
  extern Portal SPI_cursor_open(const char *name, void *plan,
  				Datum *Values, const char *Nulls, bool read_only);
  extern Portal SPI_cursor_find(const char *name);
! extern void SPI_cursor_fetch(Portal portal, bool forward, long count);
! extern void SPI_cursor_move(Portal portal, bool forward, long count);
  extern void SPI_cursor_close(Portal portal);
  
  extern void AtEOXact_SPI(bool isCommit);
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.135
diff -c -r1.135 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	7 Apr 2005 14:53:04 -0000	1.135
--- src/pl/plpgsql/src/pl_exec.c	1 May 2005 06:36:37 -0000
***************
*** 158,164 ****
  			   bool *isNull,
  			   Oid *rettype);
  static int exec_run_select(PLpgSQL_execstate *estate,
! 				PLpgSQL_expr *expr, int maxtuples, Portal *portalP);
  static void exec_move_row(PLpgSQL_execstate *estate,
  			  PLpgSQL_rec *rec,
  			  PLpgSQL_row *row,
--- 158,164 ----
  			   bool *isNull,
  			   Oid *rettype);
  static int exec_run_select(PLpgSQL_execstate *estate,
! 				PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
  static void exec_move_row(PLpgSQL_execstate *estate,
  			  PLpgSQL_rec *rec,
  			  PLpgSQL_row *row,
***************
*** 3482,3488 ****
   */
  static int
  exec_run_select(PLpgSQL_execstate *estate,
! 				PLpgSQL_expr *expr, int maxtuples, Portal *portalP)
  {
  	int			i;
  	Datum	   *values;
--- 3482,3488 ----
   */
  static int
  exec_run_select(PLpgSQL_execstate *estate,
! 				PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
  {
  	int			i;
  	Datum	   *values;
Index: src/pl/plpython/plpython.c
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/pl/plpython/plpython.c,v
retrieving revision 1.60
diff -c -r1.60 plpython.c
*** src/pl/plpython/plpython.c	29 Mar 2005 00:17:24 -0000	1.60
--- src/pl/plpython/plpython.c	1 May 2005 06:42:09 -0000
***************
*** 1546,1553 ****
  
  static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
  static PyObject *PLy_spi_execute(PyObject *, PyObject *);
! static PyObject *PLy_spi_execute_query(char *query, int limit);
! static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int);
  static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
  
  
--- 1546,1553 ----
  
  static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
  static PyObject *PLy_spi_execute(PyObject *, PyObject *);
! static PyObject *PLy_spi_execute_query(char *query, long limit);
! static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, long);
  static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
  
  
***************
*** 1965,1971 ****
  	char	   *query;
  	PyObject   *plan;
  	PyObject   *list = NULL;
! 	int			limit = 0;
  
  	/* Can't execute more if we have an unhandled error */
  	if (PLy_error_in_progress)
--- 1965,1971 ----
  	char	   *query;
  	PyObject   *plan;
  	PyObject   *list = NULL;
! 	long		limit = 0;
  
  	/* Can't execute more if we have an unhandled error */
  	if (PLy_error_in_progress)
***************
*** 1974,1985 ****
  		return NULL;
  	}
  
! 	if (PyArg_ParseTuple(args, "s|i", &query, &limit))
  		return PLy_spi_execute_query(query, limit);
  
  	PyErr_Clear();
  
! 	if ((PyArg_ParseTuple(args, "O|Oi", &plan, &list, &limit)) &&
  		(is_PLyPlanObject(plan)))
  		return PLy_spi_execute_plan(plan, list, limit);
  
--- 1974,1985 ----
  		return NULL;
  	}
  
! 	if (PyArg_ParseTuple(args, "s|l", &query, &limit))
  		return PLy_spi_execute_query(query, limit);
  
  	PyErr_Clear();
  
! 	if ((PyArg_ParseTuple(args, "O|Ol", &plan, &list, &limit)) &&
  		(is_PLyPlanObject(plan)))
  		return PLy_spi_execute_plan(plan, list, limit);
  
***************
*** 1988,1994 ****
  }
  
  static PyObject *
! PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit)
  {
  	volatile int nargs;
  	int			i,
--- 1988,1994 ----
  }
  
  static PyObject *
! PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
  {
  	volatile int nargs;
  	int			i,
***************
*** 2123,2129 ****
  }
  
  static PyObject *
! PLy_spi_execute_query(char *query, int limit)
  {
  	int			rv;
  	MemoryContext oldcontext;
--- 2123,2129 ----
  }
  
  static PyObject *
! PLy_spi_execute_query(char *query, long limit)
  {
  	int			rv;
  	MemoryContext oldcontext;
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Reply via email to