Re: SPI bug. - Mailing list pgsql-hackers
From | Neil Conway |
---|---|
Subject | Re: SPI bug. |
Date | |
Msg-id | 4274C372.7080707@samurai.com Whole thread Raw |
In response to | Re: SPI bug. (Neil Conway <neilc@samurai.com>) |
Responses |
Re: SPI bug.
|
List | pgsql-hackers |
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;
pgsql-hackers by date: