Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 94136d5

Browse files
committed
Add new SPI_OK_REWRITTEN return code to SPI_execute and friends, for the
case that the command is rewritten into another type of command. The old behavior to return the command tag of the last executed command was pretty surprising. In PL/pgSQL, for example, it meant that if a command was rewritten to a utility statement, FOUND wasn't set at all.
1 parent 0154345 commit 94136d5

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

doc/src/sgml/spi.sgml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.63 2009/01/07 13:44:36 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.64 2009/01/21 11:02:40 heikki Exp $ -->
22

33
<chapter id="spi">
44
<title>Server Programming Interface</title>
@@ -527,6 +527,16 @@ typedef struct
527527
</para>
528528
</listitem>
529529
</varlistentry>
530+
531+
<varlistentry>
532+
<term><symbol>SPI_OK_REWRITTEN</symbol></term>
533+
<listitem>
534+
<para>
535+
if the command was rewritten into another kind of command (e.g.,
536+
<command>UPDATE</command> became an <command>INSERT</command>) by a <link linkend="rules">rule</link>.
537+
</para>
538+
</listitem>
539+
</varlistentry>
530540
</variablelist>
531541
</para>
532542

src/backend/executor/spi.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.206 2009/01/07 20:38:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.207 2009/01/21 11:02:40 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1490,6 +1490,8 @@ SPI_result_code_string(int code)
14901490
return "SPI_OK_DELETE_RETURNING";
14911491
case SPI_OK_UPDATE_RETURNING:
14921492
return "SPI_OK_UPDATE_RETURNING";
1493+
case SPI_OK_REWRITTEN:
1494+
return "SPI_OK_REWRITTEN";
14931495
}
14941496
/* Unrecognized code ... return something useful ... */
14951497
sprintf(buf, "Unrecognized SPI code %d", code);
@@ -1910,11 +1912,12 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
19101912
_SPI_current->tuptable = NULL;
19111913

19121914
/*
1913-
* If none of the queries had canSetTag, we return the last query's result
1914-
* code, but not its auxiliary results (for backwards compatibility).
1915+
* If none of the queries had canSetTag, return SPI_OK_REWRITTEN. Prior
1916+
* to 8.4, we used return the last query's result code, but not its
1917+
* auxiliary results, but that's confusing.
19151918
*/
19161919
if (my_res == 0)
1917-
my_res = res;
1920+
my_res = SPI_OK_REWRITTEN;
19181921

19191922
return my_res;
19201923
}

src/include/executor/spi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.70 2009/01/07 20:38:56 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.71 2009/01/21 11:02:40 heikki Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -56,6 +56,7 @@ typedef struct _SPI_plan *SPIPlanPtr;
5656
#define SPI_OK_INSERT_RETURNING 11
5757
#define SPI_OK_DELETE_RETURNING 12
5858
#define SPI_OK_UPDATE_RETURNING 13
59+
#define SPI_OK_REWRITTEN 14
5960

6061
extern PGDLLIMPORT uint32 SPI_processed;
6162
extern PGDLLIMPORT Oid SPI_lastoid;

src/pl/plpgsql/src/pl_exec.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.229 2009/01/14 09:53:51 heikki Exp $
11+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.230 2009/01/21 11:02:40 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2782,19 +2782,13 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
27822782

27832783
/*
27842784
* Check for error, and set FOUND if appropriate (for historical reasons
2785-
* we set FOUND only for certain query types).
2786-
*
2787-
* Note: the command type indicated by return code might not match
2788-
* mod_stmt, if there is an INSTEAD OF rule rewriting an UPDATE into an
2789-
* INSERT, for example. In that case, the INSERT doesn't have canSetTag
2790-
* set, mod_stmt is false, and SPI_execute_plan sets SPI_processed to
2791-
* zero. We'll set FOUND to false here in that case. If the statement is
2792-
* rewritten into a utility statement, however, FOUND is left unchanged.
2793-
* Arguably that's a bug, but changing it now could break applications.
2785+
* we set FOUND only for certain query types). Also Assert that we
2786+
* identified the statement type the same as SPI did.
27942787
*/
27952788
switch (rc)
27962789
{
27972790
case SPI_OK_SELECT:
2791+
Assert(!stmt->mod_stmt);
27982792
exec_set_found(estate, (SPI_processed != 0));
27992793
break;
28002794

@@ -2804,11 +2798,23 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
28042798
case SPI_OK_INSERT_RETURNING:
28052799
case SPI_OK_UPDATE_RETURNING:
28062800
case SPI_OK_DELETE_RETURNING:
2801+
Assert(stmt->mod_stmt);
28072802
exec_set_found(estate, (SPI_processed != 0));
28082803
break;
28092804

28102805
case SPI_OK_SELINTO:
28112806
case SPI_OK_UTILITY:
2807+
Assert(!stmt->mod_stmt);
2808+
break;
2809+
2810+
case SPI_OK_REWRITTEN:
2811+
Assert(!stmt->mod_stmt);
2812+
/*
2813+
* The command was rewritten into another kind of command. It's
2814+
* not clear what FOUND would mean in that case (and SPI doesn't
2815+
* return the row count either), so just set it to false.
2816+
*/
2817+
exec_set_found(estate, false);
28122818
break;
28132819

28142820
default:

0 commit comments

Comments
 (0)