1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Change plpgsql's GET DIAGNOSTICS statement to use SQL99-compatible

syntax.  Fix the RESULT_OID case, which never worked.  Add documentation.
This commit is contained in:
Tom Lane
2001-02-19 19:49:53 +00:00
parent 66858ebc67
commit 414f94f262
8 changed files with 130 additions and 120 deletions

View File

@ -3,22 +3,23 @@
* 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);
@ -155,6 +156,7 @@ AtEOXact_SPI(void)
_SPI_current = _SPI_stack = NULL;
_SPI_connected = _SPI_curid = -1;
SPI_processed = 0;
SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
}
@ -623,6 +625,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
CommandCounterIncrement();
SPI_processed = 0;
SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
_SPI_current->tuptable = NULL;
_SPI_current->qtlist = NULL;
@ -723,6 +726,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
CommandCounterIncrement();
SPI_processed = 0;
SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
_SPI_current->tuptable = NULL;
_SPI_current->qtlist = NULL;
@ -786,6 +790,7 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
bool isRetrieveIntoRelation = false;
char *intoName = NULL;
int res;
Oid save_lastoid;
switch (operation)
{
@ -840,6 +845,8 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
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())
@ -859,6 +866,7 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
if (dest == SPI)
{
SPI_processed = _SPI_current->processed;
SPI_lastoid = save_lastoid;
SPI_tuptable = _SPI_current->tuptable;
}
queryDesc->dest = dest;

View File

@ -71,6 +71,7 @@ typedef struct
#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;

View File

@ -4,7 +4,7 @@
* 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.
*
@ -63,7 +63,13 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
{
int nalloc;
int nused;
int *dtnums;
int *nums;
} intlist;
struct
{
int nalloc;
int nused;
PLpgSQL_diag_item *dtitems;
} dtlist;
struct
{
@ -119,11 +125,11 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
%type <stmt> stmt_fors, stmt_select, stmt_perform
%type <stmt> stmt_dynexecute, stmt_dynfors, stmt_getdiag
%type <dtlist> raise_params
%type <intlist> raise_params
%type <ival> raise_level, raise_param
%type <str> raise_msg
%type <dtlist> getdiag_items, getdiag_targets
%type <dtlist> getdiag_list
%type <ival> getdiag_item, getdiag_target
%type <ival> lno
@ -156,11 +162,11 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
%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
@ -607,7 +613,7 @@ stmt_assign : assign_var lno K_ASSIGN expr_until_semi
}
;
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;
@ -616,80 +622,50 @@ stmt_getdiag : K_GET K_DIAGNOSTICS lno K_SELECT getdiag_items K_INTO getdiag_tar
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;
$$.dtitems = palloc(sizeof(PLpgSQL_diag_item) * $$.nalloc);
$$.dtitems[0].target = $1;
$$.dtitems[0].item = $3;
}
;
getdiag_item : K_PROCESSED
getdiag_item : K_ROW_COUNT
{
$$ = PLPGSQL_GETDIAG_PROCESSED;
$$ = PLPGSQL_GETDIAG_ROW_COUNT;
}
| K_RESULT
| K_RESULT_OID
{
$$ = PLPGSQL_GETDIAG_RESULT;
$$ = PLPGSQL_GETDIAG_RESULT_OID;
}
;
getdiag_targets : getdiag_targets ',' getdiag_target
{
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;
}
| getdiag_target
{
$$.nalloc = 1;
$$.nused = 1;
$$.dtnums = palloc(sizeof(int) * $$.nalloc);
$$.dtnums[0] = $1;
}
;
getdiag_target : T_VARIABLE
getdiag_target : T_VARIABLE
{
if (yylval.var->isconst)
{
@ -1070,7 +1046,7 @@ stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
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;
}
@ -1116,20 +1092,20 @@ raise_params : raise_params raise_param
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;
}
;

View File

@ -3,7 +3,7 @@
* 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.
*
@ -82,7 +82,7 @@ static int exec_stmt(PLpgSQL_execstate * estate,
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,
@ -507,9 +507,9 @@ plpgsql_exec_trigger(PLpgSQL_function * func,
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;
@ -1071,35 +1071,40 @@ exec_stmt_getdiag(PLpgSQL_execstate * estate, PLpgSQL_stmt_getdiag * stmt)
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;
}
/* ----------

View File

@ -3,7 +3,7 @@
* 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.
*
@ -708,20 +708,24 @@ dump_getdiag(PLpgSQL_stmt_getdiag * stmt)
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:
@ -729,15 +733,6 @@ dump_getdiag(PLpgSQL_stmt_getdiag * stmt)
break;
}
}
printf(" INTO ");
for (i = 0; i < stmt->ntargets; i++)
{
if (i != 0)
printf(", ");
printf("{var %d}", stmt->targets[i]);
}
printf("\n");
}

View File

@ -3,7 +3,7 @@
* 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.
*
@ -115,8 +115,8 @@ enum
*/
enum
{
PLPGSQL_GETDIAG_PROCESSED,
PLPGSQL_GETDIAG_RESULT
PLPGSQL_GETDIAG_ROW_COUNT,
PLPGSQL_GETDIAG_RESULT_OID
};
@ -277,14 +277,19 @@ typedef struct
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
typedef struct
{ /* Get Disgnostics statement */
{ /* Get Diagnostics item */
int item; /* id for diagnostic value desired */
int target; /* where to assign it */
} PLpgSQL_diag_item;
typedef struct
{ /* 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;

View File

@ -4,7 +4,7 @@
* 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.
*
@ -114,13 +114,13 @@ not { return K_NOT; }
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; }