mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Number of tuples inserted/affected by INSERT/UPDATE/DELETE...
This commit is contained in:
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.19 1997/08/22 14:28:20 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.20 1997/08/27 09:02:24 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -65,7 +65,7 @@ static TupleTableSlot *ExecutePlan(EState *estate, Plan *plan,
|
|||||||
int numberTuples, ScanDirection direction,
|
int numberTuples, ScanDirection direction,
|
||||||
void (*printfunc)());
|
void (*printfunc)());
|
||||||
static void ExecRetrieve(TupleTableSlot *slot, void (*printfunc)(),
|
static void ExecRetrieve(TupleTableSlot *slot, void (*printfunc)(),
|
||||||
Relation intoRelationDesc);
|
EState *estate);
|
||||||
static void ExecAppend(TupleTableSlot *slot,ItemPointer tupleid,
|
static void ExecAppend(TupleTableSlot *slot,ItemPointer tupleid,
|
||||||
EState *estate);
|
EState *estate);
|
||||||
static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
|
static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
|
||||||
@ -171,6 +171,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
|
|||||||
plan = queryDesc->plantree;
|
plan = queryDesc->plantree;
|
||||||
dest = queryDesc->dest;
|
dest = queryDesc->dest;
|
||||||
destination = (void (*)()) DestToFunction(dest);
|
destination = (void (*)()) DestToFunction(dest);
|
||||||
|
estate->es_processed = 0;
|
||||||
|
estate->es_lastoid = InvalidOid;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
@ -665,7 +667,6 @@ ExecutePlan(EState *estate,
|
|||||||
ScanDirection direction,
|
ScanDirection direction,
|
||||||
void (*printfunc)())
|
void (*printfunc)())
|
||||||
{
|
{
|
||||||
Relation intoRelationDesc;
|
|
||||||
JunkFilter *junkfilter;
|
JunkFilter *junkfilter;
|
||||||
|
|
||||||
TupleTableSlot *slot;
|
TupleTableSlot *slot;
|
||||||
@ -674,12 +675,6 @@ ExecutePlan(EState *estate,
|
|||||||
int current_tuple_count;
|
int current_tuple_count;
|
||||||
TupleTableSlot *result;
|
TupleTableSlot *result;
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* get information
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
intoRelationDesc = estate->es_into_relation_descriptor;
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initialize local variables
|
* initialize local variables
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -782,7 +777,7 @@ ExecutePlan(EState *estate,
|
|||||||
case CMD_SELECT:
|
case CMD_SELECT:
|
||||||
ExecRetrieve(slot, /* slot containing tuple */
|
ExecRetrieve(slot, /* slot containing tuple */
|
||||||
printfunc, /* print function */
|
printfunc, /* print function */
|
||||||
intoRelationDesc); /* "into" relation */
|
estate); /* */
|
||||||
result = slot;
|
result = slot;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -853,7 +848,7 @@ ExecutePlan(EState *estate,
|
|||||||
static void
|
static void
|
||||||
ExecRetrieve(TupleTableSlot *slot,
|
ExecRetrieve(TupleTableSlot *slot,
|
||||||
void (*printfunc)(),
|
void (*printfunc)(),
|
||||||
Relation intoRelationDesc)
|
EState *estate)
|
||||||
{
|
{
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
TupleDesc attrtype;
|
TupleDesc attrtype;
|
||||||
@ -869,8 +864,9 @@ ExecRetrieve(TupleTableSlot *slot,
|
|||||||
* insert the tuple into the "into relation"
|
* insert the tuple into the "into relation"
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
if (intoRelationDesc != NULL) {
|
if ( estate->es_into_relation_descriptor != NULL )
|
||||||
heap_insert (intoRelationDesc, tuple);
|
{
|
||||||
|
heap_insert (estate->es_into_relation_descriptor, tuple);
|
||||||
IncrAppended();
|
IncrAppended();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,6 +876,7 @@ ExecRetrieve(TupleTableSlot *slot,
|
|||||||
*/
|
*/
|
||||||
(*printfunc)(tuple, attrtype);
|
(*printfunc)(tuple, attrtype);
|
||||||
IncrRetrieved();
|
IncrRetrieved();
|
||||||
|
(estate->es_processed)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
@ -947,7 +944,6 @@ ExecAppend(TupleTableSlot *slot,
|
|||||||
newId = heap_insert(resultRelationDesc, /* relation desc */
|
newId = heap_insert(resultRelationDesc, /* relation desc */
|
||||||
tuple); /* heap tuple */
|
tuple); /* heap tuple */
|
||||||
IncrAppended();
|
IncrAppended();
|
||||||
UpdateAppendOid(newId);
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* process indices
|
* process indices
|
||||||
@ -961,6 +957,8 @@ ExecAppend(TupleTableSlot *slot,
|
|||||||
if (numIndices > 0) {
|
if (numIndices > 0) {
|
||||||
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, false);
|
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, false);
|
||||||
}
|
}
|
||||||
|
(estate->es_processed)++;
|
||||||
|
estate->es_lastoid = newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
@ -989,10 +987,12 @@ ExecDelete(TupleTableSlot *slot,
|
|||||||
* delete the tuple
|
* delete the tuple
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
heap_delete(resultRelationDesc, /* relation desc */
|
if ( heap_delete(resultRelationDesc, /* relation desc */
|
||||||
tupleid); /* item pointer to tuple */
|
tupleid) ) /* item pointer to tuple */
|
||||||
|
return;
|
||||||
|
|
||||||
IncrDeleted();
|
IncrDeleted();
|
||||||
|
(estate->es_processed)++;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* Note: Normally one would think that we have to
|
* Note: Normally one would think that we have to
|
||||||
@ -1094,6 +1094,7 @@ ExecReplace(TupleTableSlot *slot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IncrReplaced();
|
IncrReplaced();
|
||||||
|
(estate->es_processed)++;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* Note: instead of having to update the old index tuples
|
* Note: instead of having to update the old index tuples
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.7 1997/08/19 21:34:02 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.8 1997/08/27 09:03:14 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -43,8 +43,7 @@
|
|||||||
|
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
|
|
||||||
static Oid GetAppendOid(void);
|
static char CommandInfo[32] = {0};
|
||||||
static void ResetAppendOid(void);
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* output functions
|
* output functions
|
||||||
@ -87,8 +86,6 @@ void (*DestToFunction(CommandDest dest))(HeapTuple, TupleDesc)
|
|||||||
return donothing;
|
return donothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_INSERT_TAG(tag) (*tag == 'I' && *(tag+1) == 'N')
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* EndCommand - tell destination that no more tuples will arrive
|
* EndCommand - tell destination that no more tuples will arrive
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -106,14 +103,8 @@ EndCommand(char *commandTag, CommandDest dest)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
pq_putnchar("C", 1);
|
pq_putnchar("C", 1);
|
||||||
/* pq_putint(0, 4); */
|
sprintf(buf, "%s%s", commandTag, CommandInfo);
|
||||||
if (IS_INSERT_TAG(commandTag))
|
|
||||||
{
|
|
||||||
sprintf(buf, "%s %d", commandTag, GetAppendOid());
|
|
||||||
pq_putstr(buf);
|
pq_putstr(buf);
|
||||||
}
|
|
||||||
else
|
|
||||||
pq_putstr(commandTag);
|
|
||||||
pq_flush();
|
pq_flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -239,7 +230,7 @@ BeginCommand(char *pname,
|
|||||||
* because nothing needs to be sent to the fe.
|
* because nothing needs to be sent to the fe.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
ResetAppendOid();
|
CommandInfo[0] = 0;
|
||||||
if (isIntoPortal)
|
if (isIntoPortal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -318,41 +309,22 @@ BeginCommand(char *pname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Oid AppendOid;
|
|
||||||
|
|
||||||
static void
|
|
||||||
ResetAppendOid(void)
|
|
||||||
{
|
|
||||||
AppendOid = InvalidOid;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MULTI_TUPLE_APPEND -1
|
|
||||||
|
|
||||||
void
|
void
|
||||||
UpdateAppendOid(Oid newoid)
|
UpdateCommandInfo (int operation, Oid lastoid, uint32 tuples)
|
||||||
{
|
{
|
||||||
/*
|
switch (operation)
|
||||||
* First update after AppendOid was reset (at command beginning).
|
{
|
||||||
*/
|
case CMD_INSERT :
|
||||||
if (AppendOid == InvalidOid)
|
if ( tuples > 1 )
|
||||||
AppendOid = newoid;
|
lastoid = InvalidOid;
|
||||||
/*
|
sprintf (CommandInfo, " %u %u", lastoid, tuples);
|
||||||
* Already detected a multiple tuple append, return a void oid ;)
|
break;
|
||||||
*/
|
case CMD_DELETE :
|
||||||
else if (AppendOid == MULTI_TUPLE_APPEND)
|
case CMD_UPDATE :
|
||||||
|
sprintf (CommandInfo, " %u", tuples);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
CommandInfo[0] = 0;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
/*
|
|
||||||
* Oid has been assigned once before, tag this as a multiple tuple
|
|
||||||
* append.
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
AppendOid = MULTI_TUPLE_APPEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Oid
|
|
||||||
GetAppendOid(void)
|
|
||||||
{
|
|
||||||
if (AppendOid == MULTI_TUPLE_APPEND)
|
|
||||||
return InvalidOid;
|
|
||||||
return AppendOid;
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.6 1997/08/19 21:34:07 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.7 1997/08/27 09:03:15 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -322,6 +322,9 @@ ProcessQueryDesc(QueryDesc *queryDesc)
|
|||||||
*/
|
*/
|
||||||
ExecutorRun(queryDesc, state, EXEC_RUN, 0);
|
ExecutorRun(queryDesc, state, EXEC_RUN, 0);
|
||||||
|
|
||||||
|
/* save infos for EndCommand */
|
||||||
|
UpdateCommandInfo (operation, state->es_lastoid, state->es_processed);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* now, we close down all the scans and free allocated resources...
|
* now, we close down all the scans and free allocated resources...
|
||||||
* with ExecutorEnd()
|
* with ExecutorEnd()
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: execnodes.h,v 1.7 1997/08/06 03:42:02 momjian Exp $
|
* $Id: execnodes.h,v 1.8 1997/08/27 09:04:52 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -197,6 +197,8 @@ typedef struct EState {
|
|||||||
TupleTable es_tupleTable;
|
TupleTable es_tupleTable;
|
||||||
JunkFilter *es_junkFilter;
|
JunkFilter *es_junkFilter;
|
||||||
int *es_refcount;
|
int *es_refcount;
|
||||||
|
uint32 es_processed; /* # of tuples processed */
|
||||||
|
Oid es_lastoid; /* last oid processed (by INSERT) */
|
||||||
} EState;
|
} EState;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: dest.h,v 1.6 1997/08/19 21:40:06 momjian Exp $
|
* $Id: dest.h,v 1.7 1997/08/27 09:05:09 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -69,6 +69,6 @@ extern void NullCommand(CommandDest dest);
|
|||||||
extern void BeginCommand(char *pname, int operation, TupleDesc attinfo,
|
extern void BeginCommand(char *pname, int operation, TupleDesc attinfo,
|
||||||
bool isIntoRel, bool isIntoPortal, char *tag,
|
bool isIntoRel, bool isIntoPortal, char *tag,
|
||||||
CommandDest dest);
|
CommandDest dest);
|
||||||
extern void UpdateAppendOid(Oid newoid);
|
extern void UpdateCommandInfo (int operation, Oid lastoid, uint32 tuples);
|
||||||
|
|
||||||
#endif /* DEST_H */
|
#endif /* DEST_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.33 1997/07/12 20:31:47 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.34 1997/08/27 09:05:23 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1532,18 +1532,70 @@ char* PQcmdStatus(PGresult *res) {
|
|||||||
if the last command was an INSERT, return the oid string
|
if the last command was an INSERT, return the oid string
|
||||||
if not, return ""
|
if not, return ""
|
||||||
*/
|
*/
|
||||||
const char* PQoidStatus(PGresult *res) {
|
static char oidStatus[32] = {0};
|
||||||
if (!res) {
|
const char* PQoidStatus (PGresult *res)
|
||||||
|
{
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
fprintf (stderr, "PQoidStatus () -- pointer to PQresult is null");
|
fprintf (stderr, "PQoidStatus () -- pointer to PQresult is null");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oidStatus[0] = 0;
|
||||||
|
if ( !res->cmdStatus )
|
||||||
|
return oidStatus;
|
||||||
|
|
||||||
|
if ( strncmp (res->cmdStatus, "INSERT", 6) == 0 )
|
||||||
|
{
|
||||||
|
char *p = res->cmdStatus + 7;
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
for (e = p; *e != ' ' && *e; ) e++;
|
||||||
|
sprintf (oidStatus, "%.*s", e - p, p);
|
||||||
|
}
|
||||||
|
return oidStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
PQcmdTuples -
|
||||||
|
if the last command was an INSERT/UPDATE/DELETE, return number
|
||||||
|
of inserted/affected tuples, if not, return ""
|
||||||
|
*/
|
||||||
|
const char* PQcmdTuples (PGresult *res)
|
||||||
|
{
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "PQcmdTuples () -- pointer to PQresult is null");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !res->cmdStatus )
|
if ( !res->cmdStatus )
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (strncmp(res->cmdStatus, "INSERT",6) == 0) {
|
if ( strncmp (res->cmdStatus, "INSERT", 6) == 0 ||
|
||||||
return res->cmdStatus+7;
|
strncmp (res->cmdStatus, "DELETE", 6) == 0 ||
|
||||||
} else
|
strncmp (res->cmdStatus, "UPDATE", 6) == 0 )
|
||||||
|
{
|
||||||
|
char *p = res->cmdStatus + 6;
|
||||||
|
|
||||||
|
if ( *p == 0 )
|
||||||
|
{
|
||||||
|
fprintf (stderr, "PQcmdTuples (%s) -- short input from server",
|
||||||
|
res->cmdStatus);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
if ( *(res->cmdStatus) != 'I' ) /* UPDATE/DELETE */
|
||||||
|
return (p);
|
||||||
|
while ( *p != ' ' && *p ) p++; /* INSERT: skip oid */
|
||||||
|
if ( *p == 0 )
|
||||||
|
{
|
||||||
|
fprintf (stderr, "PQcmdTuples (INSERT) -- there's no # of tuples");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: libpq-fe.h,v 1.19 1997/05/09 03:28:54 scrappy Exp $
|
* $Id: libpq-fe.h,v 1.20 1997/08/27 09:05:24 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -225,6 +225,7 @@ extern Oid PQftype(PGresult *res, int field_num);
|
|||||||
extern short PQfsize(PGresult *res, int field_num);
|
extern short PQfsize(PGresult *res, int field_num);
|
||||||
extern char* PQcmdStatus(PGresult *res);
|
extern char* PQcmdStatus(PGresult *res);
|
||||||
extern const char* PQoidStatus(PGresult *res);
|
extern const char* PQoidStatus(PGresult *res);
|
||||||
|
extern const char* PQcmdTuples(PGresult *res);
|
||||||
extern char* PQgetvalue(PGresult *res, int tup_num, int field_num);
|
extern char* PQgetvalue(PGresult *res, int tup_num, int field_num);
|
||||||
extern int PQgetlength(PGresult *res, int tup_num, int field_num);
|
extern int PQgetlength(PGresult *res, int tup_num, int field_num);
|
||||||
extern int PQgetisnull(PGresult *res, int tup_num, int field_num);
|
extern int PQgetisnull(PGresult *res, int tup_num, int field_num);
|
||||||
|
Reference in New Issue
Block a user