syntax. Fix the RESULT_OID case, which never worked. Add documentation.
The PL/pgSQL language is case insensitive. All keywords and
- identifiers can be used in mixed upper- and lowercase.
+ identifiers can be used in mixed upper- and lower-case.
PL/pgSQL is a block oriented language. A block is defined as
must also have a default value specified.
- The default value is evaluated every time the function is called. So
+ The default value is evaluated every time the block is entered. So
assigning 'now' to a variable of type
timestamp causes the variable to have the
time of the actual function call, not when the function was
corresponding identifier $n will be a rowtype, but it
must be aliased using the ALIAS command described below. Only the user
attributes of a table row are accessible in the row, no Oid or other
- system attributes (hence the row could be from a view and view rows
+ system attributes (because the row could be from a view and view rows
don't have useful system attributes).
Using the table.field%TYPE
causes PL/pgSQL to look up the attributes definitions at the
first call to the function during the lifetime of a backend.
- Have a table with a char(20) attribute and some PL/pgSQL functions
+ Suppose we have a table with a char(20) attribute and some PL/pgSQL functions
that deal with its content in local variables. Now someone
decides that char(20) isn't enough, dumps the table, drops it,
recreates it now with the attribute in question defined as
+
+ Obtaining other results status
+
+GET DIAGNOSTICS variable = item [ , ... ]
+
+ This command allows retrieval of system status indicators. Each
+ item is a keyword identifying a state
+ value to be assigned to the specified variable (which should be of
+ the right datatype to receive it). The currently available status
+ items are ROW_COUNT>, the number of rows processed by
+ the last SQL query sent down to the SQL engine; and
+ RESULT_OID>, the Oid of the last row inserted by the
+ most recent SQL query. Note that RESULT_OID> is only
+ useful after an INSERT query.
+
+
+
+
Returning from the function
* spi.c
* Server Programming Interface
*
- * $Id: spi.c,v 1.51 2001/01/04 02:36:52 tgl Exp $
+ * $Id: spi.c,v 1.52 2001/02/19 19:49:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "executor/spi_priv.h"
#include "access/printtup.h"
+uint32 SPI_processed = 0;
+Oid SPI_lastoid = InvalidOid;
+SPITupleTable *SPI_tuptable = NULL;
+int SPI_result;
+
static _SPI_connection *_SPI_stack = NULL;
static _SPI_connection *_SPI_current = NULL;
static int _SPI_connected = -1;
static int _SPI_curid = -1;
-DLLIMPORT uint32 SPI_processed = 0;
-DLLIMPORT SPITupleTable *SPI_tuptable = NULL;
-DLLIMPORT int SPI_result;
-
static int _SPI_execute(char *src, int tcount, _SPI_plan *plan);
static int _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount);
_SPI_current = _SPI_stack = NULL;
_SPI_connected = _SPI_curid = -1;
SPI_processed = 0;
+ SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
}
CommandCounterIncrement();
SPI_processed = 0;
+ SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
_SPI_current->tuptable = NULL;
_SPI_current->qtlist = NULL;
CommandCounterIncrement();
SPI_processed = 0;
+ SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
_SPI_current->tuptable = NULL;
_SPI_current->qtlist = NULL;
bool isRetrieveIntoRelation = false;
char *intoName = NULL;
int res;
+ Oid save_lastoid;
switch (operation)
{
ExecutorRun(queryDesc, state, EXEC_FOR, (long) tcount);
_SPI_current->processed = state->es_processed;
+ save_lastoid = state->es_lastoid;
+
if (operation == CMD_SELECT && queryDesc->dest == SPI)
{
if (_SPI_checktuples())
if (dest == SPI)
{
SPI_processed = _SPI_current->processed;
+ SPI_lastoid = save_lastoid;
SPI_tuptable = _SPI_current->tuptable;
}
queryDesc->dest = dest;
#define SPI_OK_CURSOR 10
extern DLLIMPORT uint32 SPI_processed;
+extern DLLIMPORT Oid SPI_lastoid;
extern DLLIMPORT SPITupleTable *SPI_tuptable;
extern DLLIMPORT int SPI_result;
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.15 2001/02/10 22:53:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.16 2001/02/19 19:49:53 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
{
int nalloc;
int nused;
- int *dtnums;
+ int *nums;
+ } intlist;
+ struct
+ {
+ int nalloc;
+ int nused;
+ PLpgSQL_diag_item *dtitems;
} dtlist;
struct
{
%type stmt_fors, stmt_select, stmt_perform
%type stmt_dynexecute, stmt_dynfors, stmt_getdiag
-%type <dtlist> raise_params
+%type <intlist> raise_params
%type raise_level, raise_param
%type raise_msg
-%type getdiag_items, getdiag_targets
+%type getdiag_list
%type getdiag_item, getdiag_target
%type lno
%token K_NOTICE
%token K_NULL
%token K_PERFORM
-%token K_PROCESSED
+%token K_ROW_COUNT
%token K_RAISE
%token K_RECORD
%token K_RENAME
-%token K_RESULT
+%token K_RESULT_OID
%token K_RETURN
%token K_REVERSE
%token K_SELECT
}
;
-stmt_getdiag : K_GET K_DIAGNOSTICS lno K_SELECT getdiag_items K_INTO getdiag_targets ';'
+stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
{
PLpgSQL_stmt_getdiag *new;
new->cmd_type = PLPGSQL_STMT_GETDIAG;
new->lineno = $3;
- new->nitems = $5.nused;
- new->items = malloc(sizeof(int) * $5.nused);
- new->ntargets = $7.nused;
- new->targets = malloc(sizeof(int) * $7.nused);
- memcpy(new->items, $5.dtnums, sizeof(int) * $5.nused);
- memcpy(new->targets, $7.dtnums, sizeof(int) * $7.nused);
-
- if (new->nitems != new->ntargets)
- {
- plpgsql_error_lineno = new->lineno;
- plpgsql_comperrinfo();
- elog(ERROR, "number of diagnostic items does not match target list");
- };
+ new->ndtitems = $4.nused;
+ new->dtitems = malloc(sizeof(PLpgSQL_diag_item) * $4.nused);
+ memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused);
$$ = (PLpgSQL_stmt *)new;
}
;
-getdiag_items : getdiag_items ',' getdiag_item
+getdiag_list : getdiag_list ',' getdiag_target K_ASSIGN getdiag_item
{
if ($1.nused == $1.nalloc)
{
$1.nalloc *= 2;
- $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
+ $1.dtitems = repalloc($1.dtitems, sizeof(PLpgSQL_diag_item) * $1.nalloc);
}
- $1.dtnums[$1.nused++] = $3;
+ $1.dtitems[$1.nused].target = $3;
+ $1.dtitems[$1.nused].item = $5;
+ $1.nused++;
$$.nalloc = $1.nalloc;
$$.nused = $1.nused;
- $$.dtnums = $1.dtnums;
+ $$.dtitems = $1.dtitems;
}
- | getdiag_item
+ | getdiag_target K_ASSIGN getdiag_item
{
$$.nalloc = 1;
$$.nused = 1;
- $$.dtnums = palloc(sizeof(int) * $$.nalloc);
- $$.dtnums[0] = $1;
- }
- ;
-
-getdiag_item : K_PROCESSED
- {
- $$ = PLPGSQL_GETDIAG_PROCESSED;
- }
- | K_RESULT
- {
- $$ = PLPGSQL_GETDIAG_RESULT;
+ $$.dtitems = palloc(sizeof(PLpgSQL_diag_item) * $$.nalloc);
+ $$.dtitems[0].target = $1;
+ $$.dtitems[0].item = $3;
}
;
-getdiag_targets : getdiag_targets ',' getdiag_target
+getdiag_item : K_ROW_COUNT
{
- if ($1.nused == $1.nalloc)
- {
- $1.nalloc *= 2;
- $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
- }
- $1.dtnums[$1.nused++] = $3;
-
- $$.nalloc = $1.nalloc;
- $$.nused = $1.nused;
- $$.dtnums = $1.dtnums;
+ $$ = PLPGSQL_GETDIAG_ROW_COUNT;
}
- | getdiag_target
+ | K_RESULT_OID
{
- $$.nalloc = 1;
- $$.nused = 1;
- $$.dtnums = palloc(sizeof(int) * $$.nalloc);
- $$.dtnums[0] = $1;
+ $$ = PLPGSQL_GETDIAG_RESULT_OID;
}
;
-
-getdiag_target : T_VARIABLE
+getdiag_target : T_VARIABLE
{
if (yylval.var->isconst)
{
new->message = $4;
new->nparams = $5.nused;
new->params = malloc(sizeof(int) * $5.nused);
- memcpy(new->params, $5.dtnums, sizeof(int) * $5.nused);
+ memcpy(new->params, $5.nums, sizeof(int) * $5.nused);
$$ = (PLpgSQL_stmt *)new;
}
if ($1.nused == $1.nalloc)
{
$1.nalloc *= 2;
- $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
+ $1.nums = repalloc($1.nums, sizeof(int) * $1.nalloc);
}
- $1.dtnums[$1.nused++] = $2;
+ $1.nums[$1.nused++] = $2;
$$.nalloc = $1.nalloc;
$$.nused = $1.nused;
- $$.dtnums = $1.dtnums;
+ $$.nums = $1.nums;
}
| raise_param
{
$$.nalloc = 1;
$$.nused = 1;
- $$.dtnums = palloc(sizeof(int) * $$.nalloc);
- $$.dtnums[0] = $1;
+ $$.nums = palloc(sizeof(int) * $$.nalloc);
+ $$.nums[0] = $1;
}
;
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.37 2001/02/09 00:14:26 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.38 2001/02/19 19:49:53 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
static int exec_stmt_assign(PLpgSQL_execstate * estate,
PLpgSQL_stmt_assign * stmt);
static int exec_stmt_getdiag(PLpgSQL_execstate * estate,
- PLpgSQL_stmt_getdiag * stmt);
+ PLpgSQL_stmt_getdiag * stmt);
static int exec_stmt_if(PLpgSQL_execstate * estate,
PLpgSQL_stmt_if * stmt);
static int exec_stmt_loop(PLpgSQL_execstate * estate,
case PLPGSQL_STMT_ASSIGN:
stmttype = "assignment";
break;
- case PLPGSQL_STMT_GETDIAG:
- stmttype = "get diagnostics";
- break;
+ case PLPGSQL_STMT_GETDIAG:
+ stmttype = "get diagnostics";
+ break;
case PLPGSQL_STMT_IF:
stmttype = "if";
break;
PLpgSQL_datum *var;
bool isnull = false;
- for ( i=0 ; i < stmt->nitems ; i++)
+ for ( i=0 ; i < stmt->ndtitems ; i++)
{
- if ((stmt->targets[i] <= 0))
- break;
+ PLpgSQL_diag_item *dtitem = & stmt->dtitems[i];
+
+ if (dtitem->target <= 0)
+ continue;
- var = (estate->datums[stmt->targets[i]]);
+ var = (estate->datums[dtitem->target]);
if (var == NULL)
- break;
+ continue;
- switch (stmt->items[i])
+ switch (dtitem->item)
{
- case PLPGSQL_GETDIAG_PROCESSED:
+ case PLPGSQL_GETDIAG_ROW_COUNT:
- exec_assign_value(estate, var, (Datum)SPI_processed, INT4OID, &isnull);
- break;
+ exec_assign_value(estate, var, UInt32GetDatum(SPI_processed),
+ INT4OID, &isnull);
+ break;
- case PLPGSQL_GETDIAG_RESULT:
+ case PLPGSQL_GETDIAG_RESULT_OID:
- exec_assign_value(estate, var, (Datum)SPI_result, INT4OID, &isnull);
- break;
+ exec_assign_value(estate, var, ObjectIdGetDatum(SPI_lastoid),
+ OIDOID, &isnull);
+ break;
default:
- elog(ERROR, "unknown attribute request %d in get_diagnostic", stmt->items[i]);
- };
- };
+ elog(ERROR, "unknown attribute request %d in get_diagnostic",
+ dtitem->item);
+ }
+ }
- return PLPGSQL_RC_OK;
+ return PLPGSQL_RC_OK;
}
/* ----------
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.9 2000/12/03 20:45:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.10 2001/02/19 19:49:53 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
int i;
dump_ind();
- printf("GET DIAGNOSTICS SELECT ");
- for (i = 0; i < stmt->nitems; i++)
+ printf("GET DIAGNOSTICS ");
+ for (i = 0; i < stmt->ndtitems; i++)
{
+ PLpgSQL_diag_item *dtitem = & stmt->dtitems[i];
+
if (i != 0)
printf(", ");
- switch (stmt->items[i])
+ printf("{var %d} = ", dtitem->target);
+
+ switch (dtitem->item)
{
- case PLPGSQL_GETDIAG_PROCESSED:
- printf("PROCESSED");
+ case PLPGSQL_GETDIAG_ROW_COUNT:
+ printf("ROW_COUNT");
break;
- case PLPGSQL_GETDIAG_RESULT:
- printf("RESULT");
+ case PLPGSQL_GETDIAG_RESULT_OID:
+ printf("RESULT_OID");
break;
default:
break;
}
}
- printf(" INTO ");
- for (i = 0; i < stmt->ntargets; i++)
- {
- if (i != 0)
- printf(", ");
-
- printf("{var %d}", stmt->targets[i]);
- }
-
printf("\n");
}
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.11 2000/09/05 09:02:18 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.12 2001/02/19 19:49:53 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
*/
enum
{
- PLPGSQL_GETDIAG_PROCESSED,
- PLPGSQL_GETDIAG_RESULT
+ PLPGSQL_GETDIAG_ROW_COUNT,
+ PLPGSQL_GETDIAG_RESULT_OID
};
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
+
+typedef struct
+{ /* Get Diagnostics item */
+ int item; /* id for diagnostic value desired */
+ int target; /* where to assign it */
+} PLpgSQL_diag_item;
+
typedef struct
-{ /* Get Disgnostics statement */
+{ /* Get Diagnostics statement */
int cmd_type;
int lineno;
- int nitems;
- int *items;
- int ntargets;
- int *targets;
+ int ndtitems;
+ PLpgSQL_diag_item *dtitems;
} PLpgSQL_stmt_getdiag;
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.8 2000/09/15 11:59:40 ishii Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.9 2001/02/19 19:49:53 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
notice { return K_NOTICE; }
null { return K_NULL; }
perform { return K_PERFORM; }
-processed { return K_PROCESSED; }
raise { return K_RAISE; }
record { return K_RECORD; }
rename { return K_RENAME; }
-result { return K_RESULT; }
+result_oid { return K_RESULT_OID; }
return { return K_RETURN; }
reverse { return K_REVERSE; }
+row_count { return K_ROW_COUNT; }
select { return K_SELECT; }
then { return K_THEN; }
to { return K_TO; }