mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
Back-patch fix for command completion report handling. This is
primarily needed so that INSERTing a row still reports the row's OID even when there are ON INSERT rules firing additional queries.
This commit is contained in:
parent
5fb5066cb6
commit
75c07d5b4d
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.153 2002/02/14 15:24:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.153.2.1 2002/02/26 23:48:37 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PerformAddAttribute() code, like most of the relation
|
||||
@ -88,16 +88,25 @@ PortalCleanup(Portal portal)
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
* PerformPortalFetch
|
||||
* --------------------------------
|
||||
|
||||
/*
|
||||
* PerformPortalFetch
|
||||
*
|
||||
* name: name of portal
|
||||
* forward: forward or backward fetch?
|
||||
* count: # of tuples to fetch (0 implies all)
|
||||
* dest: where to send results
|
||||
* completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
|
||||
* in which to store a command completion status string.
|
||||
*
|
||||
* completionTag may be NULL if caller doesn't want a status string.
|
||||
*/
|
||||
void
|
||||
PerformPortalFetch(char *name,
|
||||
bool forward,
|
||||
int count,
|
||||
char *tag,
|
||||
CommandDest dest)
|
||||
CommandDest dest,
|
||||
char *completionTag)
|
||||
{
|
||||
Portal portal;
|
||||
QueryDesc *queryDesc;
|
||||
@ -106,6 +115,10 @@ PerformPortalFetch(char *name,
|
||||
CommandId savedId;
|
||||
bool temp_desc = false;
|
||||
|
||||
/* initialize completion status in case of early exit */
|
||||
if (completionTag)
|
||||
strcpy(completionTag, (dest == None) ? "MOVE 0" : "FETCH 0");
|
||||
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
@ -166,7 +179,7 @@ PerformPortalFetch(char *name,
|
||||
* relations */
|
||||
false, /* this is a portal fetch, not a "retrieve
|
||||
* portal" */
|
||||
tag,
|
||||
NULL, /* not used */
|
||||
queryDesc->dest);
|
||||
|
||||
/*
|
||||
@ -192,16 +205,15 @@ PerformPortalFetch(char *name,
|
||||
{
|
||||
ExecutorRun(queryDesc, estate, EXEC_FOR, (long) count);
|
||||
|
||||
/*
|
||||
* I use CMD_UPDATE, because no CMD_MOVE or the like exists,
|
||||
* and I would like to provide the same kind of info as
|
||||
* CMD_UPDATE
|
||||
*/
|
||||
UpdateCommandInfo(CMD_UPDATE, 0, estate->es_processed);
|
||||
if (estate->es_processed > 0)
|
||||
portal->atStart = false; /* OK to back up now */
|
||||
if (count <= 0 || (int) estate->es_processed < count)
|
||||
portal->atEnd = true; /* we retrieved 'em all */
|
||||
|
||||
if (completionTag)
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s %u",
|
||||
(dest == None) ? "MOVE" : "FETCH",
|
||||
estate->es_processed);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -210,16 +222,15 @@ PerformPortalFetch(char *name,
|
||||
{
|
||||
ExecutorRun(queryDesc, estate, EXEC_BACK, (long) count);
|
||||
|
||||
/*
|
||||
* I use CMD_UPDATE, because no CMD_MOVE or the like exists,
|
||||
* and I would like to provide the same kind of info as
|
||||
* CMD_UPDATE
|
||||
*/
|
||||
UpdateCommandInfo(CMD_UPDATE, 0, estate->es_processed);
|
||||
if (estate->es_processed > 0)
|
||||
portal->atEnd = false; /* OK to go forward now */
|
||||
if (count <= 0 || (int) estate->es_processed < count)
|
||||
portal->atStart = true; /* we retrieved 'em all */
|
||||
|
||||
if (completionTag)
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s %u",
|
||||
(dest == None) ? "MOVE" : "FETCH",
|
||||
estate->es_processed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,11 +246,6 @@ PerformPortalFetch(char *name,
|
||||
pfree(queryDesc);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
/*
|
||||
* Note: the "end-of-command" tag is returned by higher-level utility
|
||||
* code
|
||||
*/
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.67 2001/10/25 05:49:25 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.67.2.1 2002/02/26 23:48:38 tgl Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -120,7 +120,7 @@ ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDest dest)
|
||||
plan->instrument = InstrAlloc();
|
||||
|
||||
gettimeofday(&starttime, NULL);
|
||||
ProcessQuery(query, plan, None);
|
||||
ProcessQuery(query, plan, None, NULL);
|
||||
CommandCounterIncrement();
|
||||
gettimeofday(&endtime, NULL);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.47 2001/10/28 06:25:43 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.47.2.1 2002/02/26 23:48:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -275,7 +275,7 @@ postquel_getnext(execution_state *es)
|
||||
/*
|
||||
* Process a utility command. (create, destroy...) DZ - 30-8-1996
|
||||
*/
|
||||
ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
|
||||
ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest, NULL);
|
||||
if (!LAST_POSTQUEL_COMMAND(es))
|
||||
CommandCounterIncrement();
|
||||
return (TupleTableSlot *) NULL;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.65 2002/02/14 15:24:08 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.65.2.1 2002/02/26 23:48:40 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1011,7 +1011,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
|
||||
res = SPI_OK_UTILITY;
|
||||
if (plan == NULL)
|
||||
{
|
||||
ProcessUtility(queryTree->utilityStmt, None);
|
||||
ProcessUtility(queryTree->utilityStmt, None, NULL);
|
||||
if (!islastquery)
|
||||
CommandCounterIncrement();
|
||||
else
|
||||
@ -1085,7 +1085,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
|
||||
|
||||
if (queryTree->commandType == CMD_UTILITY)
|
||||
{
|
||||
ProcessUtility(queryTree->utilityStmt, None);
|
||||
ProcessUtility(queryTree->utilityStmt, None, NULL);
|
||||
if (!islastquery)
|
||||
CommandCounterIncrement();
|
||||
else
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.160 2001/11/05 05:00:14 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.160.2.1 2002/02/26 23:48:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1755,6 +1755,7 @@ _copyQuery(Query *from)
|
||||
newnode->isTemp = from->isTemp;
|
||||
newnode->hasAggs = from->hasAggs;
|
||||
newnode->hasSubLinks = from->hasSubLinks;
|
||||
newnode->originalQuery = from->originalQuery;
|
||||
|
||||
Node_Copy(from, newnode, rtable);
|
||||
Node_Copy(from, newnode, jointree);
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.108 2001/11/05 05:00:14 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.108.2.1 2002/02/26 23:48:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -593,6 +593,7 @@ _equalQuery(Query *a, Query *b)
|
||||
return false;
|
||||
if (a->hasSubLinks != b->hasSubLinks)
|
||||
return false;
|
||||
/* we deliberately ignore originalQuery */
|
||||
if (!equal(a->rtable, b->rtable))
|
||||
return false;
|
||||
if (!equal(a->jointree, b->jointree))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.113 2001/10/25 05:49:31 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.113.2.1 2002/02/26 23:48:42 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Most of the read functions for plan nodes are tested. (In fact, they
|
||||
@ -168,6 +168,9 @@ _readQuery(void)
|
||||
token = pg_strtok(&length); /* get hasSubLinks */
|
||||
local_node->hasSubLinks = strtobool(token);
|
||||
|
||||
/* we always want originalQuery to be false in a read-in query */
|
||||
local_node->originalQuery = false;
|
||||
|
||||
token = pg_strtok(&length); /* skip :rtable */
|
||||
local_node->rtable = nodeRead(true);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.213 2002/01/03 23:21:31 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.213.2.1 2002/02/26 23:48:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -121,6 +121,7 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
|
||||
List *result = NIL;
|
||||
ParseState *pstate = make_parsestate(parentParseState);
|
||||
Query *query;
|
||||
List *listscan;
|
||||
|
||||
extras_before = extras_after = NIL;
|
||||
|
||||
@ -145,6 +146,18 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
|
||||
extras_after = lnext(extras_after);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that only the original query is marked original.
|
||||
* We have to do this explicitly since recursive calls of parse_analyze
|
||||
* will have set originalQuery in some of the added-on queries.
|
||||
*/
|
||||
foreach(listscan, result)
|
||||
{
|
||||
Query *q = lfirst(listscan);
|
||||
|
||||
q->originalQuery = (q == query);
|
||||
}
|
||||
|
||||
pfree(pstate);
|
||||
|
||||
return result;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.46 2001/10/28 06:25:51 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.46.2.1 2002/02/26 23:48:45 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -41,8 +41,6 @@
|
||||
#include "libpq/pqformat.h"
|
||||
|
||||
|
||||
static char CommandInfo[32] = {0};
|
||||
|
||||
/* ----------------
|
||||
* dummy DestReceiver functions
|
||||
* ----------------
|
||||
@ -102,7 +100,6 @@ BeginCommand(char *pname,
|
||||
* if this is a "retrieve into portal" query, done because
|
||||
* nothing needs to be sent to the fe.
|
||||
*/
|
||||
CommandInfo[0] = '\0';
|
||||
if (isIntoPortal)
|
||||
break;
|
||||
|
||||
@ -198,30 +195,22 @@ DestToFunction(CommandDest dest)
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* EndCommand - tell destination that no more tuples will arrive
|
||||
* EndCommand - tell destination that query is complete
|
||||
* ----------------
|
||||
*/
|
||||
void
|
||||
EndCommand(char *commandTag, CommandDest dest)
|
||||
EndCommand(const char *commandTag, CommandDest dest)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
switch (dest)
|
||||
{
|
||||
case Remote:
|
||||
case RemoteInternal:
|
||||
|
||||
/*
|
||||
* tell the fe that the query is over
|
||||
*/
|
||||
sprintf(buf, "%s%s", commandTag, CommandInfo);
|
||||
pq_puttextmessage('C', buf);
|
||||
CommandInfo[0] = '\0';
|
||||
pq_puttextmessage('C', commandTag);
|
||||
break;
|
||||
|
||||
case Debug:
|
||||
case None:
|
||||
default:
|
||||
case Debug:
|
||||
case SPI:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -317,23 +306,3 @@ ReadyForQuery(CommandDest dest)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case CMD_INSERT:
|
||||
if (tuples > 1)
|
||||
lastoid = InvalidOid;
|
||||
sprintf(CommandInfo, " %u %u", lastoid, tuples);
|
||||
break;
|
||||
case CMD_DELETE:
|
||||
case CMD_UPDATE:
|
||||
sprintf(CommandInfo, " %u", tuples);
|
||||
break;
|
||||
default:
|
||||
CommandInfo[0] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.245 2002/01/10 01:11:45 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.245.2.1 2002/02/26 23:48:45 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -64,6 +64,7 @@
|
||||
|
||||
#include "pgstat.h"
|
||||
|
||||
|
||||
/* ----------------
|
||||
* global variables
|
||||
* ----------------
|
||||
@ -87,6 +88,13 @@ bool InError = false;
|
||||
|
||||
static bool EchoQuery = false; /* default don't echo */
|
||||
|
||||
/*
|
||||
* Flag to mark SIGHUP. Whenever the main loop comes around it
|
||||
* will reread the configuration file. (Better than doing the
|
||||
* reading in the signal handler, ey?)
|
||||
*/
|
||||
static volatile bool got_SIGHUP = false;
|
||||
|
||||
/* ----------------
|
||||
* people who want to use EOF should #define DONTUSENEWLINE in
|
||||
* tcop/tcopdebug.h
|
||||
@ -118,13 +126,7 @@ static void start_xact_command(void);
|
||||
static void finish_xact_command(void);
|
||||
static void SigHupHandler(SIGNAL_ARGS);
|
||||
static void FloatExceptionHandler(SIGNAL_ARGS);
|
||||
|
||||
/*
|
||||
* Flag to mark SIGHUP. Whenever the main loop comes around it
|
||||
* will reread the configuration file. (Better than doing the
|
||||
* reading in the signal handler, ey?)
|
||||
*/
|
||||
static volatile bool got_SIGHUP = false;
|
||||
static const char *CreateCommandTag(Node *parsetree);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@ -635,6 +637,8 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
{
|
||||
Node *parsetree = (Node *) lfirst(parsetree_item);
|
||||
bool isTransactionStmt;
|
||||
const char *commandTag;
|
||||
char completionTag[COMPLETION_TAG_BUFSIZE];
|
||||
List *querytree_list,
|
||||
*querytree_item;
|
||||
|
||||
@ -670,16 +674,17 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
|
||||
if (!allowit)
|
||||
{
|
||||
/*
|
||||
* the EndCommand() stuff is to tell the frontend that the
|
||||
* command ended. -cim 6/1/90
|
||||
*/
|
||||
char *tag = "*ABORT STATE*";
|
||||
|
||||
elog(NOTICE, "current transaction is aborted, "
|
||||
"queries ignored until end of transaction block");
|
||||
|
||||
EndCommand(tag, dest);
|
||||
/*
|
||||
* We need to emit a command-complete report to the client,
|
||||
* even though we didn't process the query.
|
||||
* - cim 6/1/90
|
||||
*/
|
||||
commandTag = "*ABORT STATE*";
|
||||
|
||||
EndCommand(commandTag, dest);
|
||||
|
||||
/*
|
||||
* We continue in the loop, on the off chance that there
|
||||
@ -702,7 +707,18 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
|
||||
/*
|
||||
* OK to analyze and rewrite this query.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* First we set the command-completion tag to the main query
|
||||
* (as opposed to each of the others that may be generated by
|
||||
* analyze and rewrite). Also set ps_status to the main query tag.
|
||||
*/
|
||||
commandTag = CreateCommandTag(parsetree);
|
||||
|
||||
set_ps_display(commandTag);
|
||||
|
||||
/*
|
||||
* Switch to appropriate context for constructing querytrees (again,
|
||||
* these must outlive the execution context).
|
||||
*/
|
||||
@ -746,7 +762,19 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
else if (DebugLvl > 1)
|
||||
elog(DEBUG, "ProcessUtility");
|
||||
|
||||
ProcessUtility(querytree->utilityStmt, dest);
|
||||
if (querytree->originalQuery)
|
||||
{
|
||||
/* utility statement can override default tag string */
|
||||
ProcessUtility(querytree->utilityStmt, dest,
|
||||
completionTag);
|
||||
if (completionTag[0])
|
||||
commandTag = completionTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* utility added by rewrite cannot override tag */
|
||||
ProcessUtility(querytree->utilityStmt, dest, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -778,7 +806,18 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
{
|
||||
if (DebugLvl > 1)
|
||||
elog(DEBUG, "ProcessQuery");
|
||||
ProcessQuery(querytree, plan, dest);
|
||||
|
||||
if (querytree->originalQuery)
|
||||
{
|
||||
/* original stmt can override default tag string */
|
||||
ProcessQuery(querytree, plan, dest, completionTag);
|
||||
commandTag = completionTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* stmt added by rewrite cannot override tag */
|
||||
ProcessQuery(querytree, plan, dest, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (Show_executor_stats)
|
||||
@ -818,6 +857,29 @@ pg_exec_query_string(char *query_string, /* string to execute */
|
||||
|
||||
} /* end loop over queries generated from a
|
||||
* parsetree */
|
||||
|
||||
/*
|
||||
* It is possible that the original query was removed due to
|
||||
* a DO INSTEAD rewrite rule. In that case we will still have
|
||||
* the default completion tag, which is fine for most purposes,
|
||||
* but it may confuse clients if it's INSERT/UPDATE/DELETE.
|
||||
* Clients expect those tags to have counts after them (cf.
|
||||
* ProcessQuery).
|
||||
*/
|
||||
if (strcmp(commandTag, "INSERT") == 0)
|
||||
commandTag = "INSERT 0 0";
|
||||
else if (strcmp(commandTag, "UPDATE") == 0)
|
||||
commandTag = "UPDATE 0";
|
||||
else if (strcmp(commandTag, "DELETE") == 0)
|
||||
commandTag = "DELETE 0";
|
||||
|
||||
/*
|
||||
* Tell client that we're done with this query. Note we emit
|
||||
* exactly one EndCommand report for each raw parsetree, thus
|
||||
* one for each SQL command the client sent, regardless of
|
||||
* rewriting.
|
||||
*/
|
||||
EndCommand(commandTag, dest);
|
||||
} /* end loop over parsetrees */
|
||||
|
||||
/*
|
||||
@ -1626,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
puts("\nPOSTGRES backend interactive interface ");
|
||||
puts("$Revision: 1.245 $ $Date: 2002/01/10 01:11:45 $\n");
|
||||
puts("$Revision: 1.245.2.1 $ $Date: 2002/02/26 23:48:45 $\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2037,3 +2099,268 @@ assertTest(int val)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* CreateCommandTag
|
||||
*
|
||||
* utility to get a string representation of the
|
||||
* command operation.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static const char *
|
||||
CreateCommandTag(Node *parsetree)
|
||||
{
|
||||
const char *tag;
|
||||
|
||||
switch (nodeTag(parsetree))
|
||||
{
|
||||
case T_InsertStmt:
|
||||
tag = "INSERT";
|
||||
break;
|
||||
|
||||
case T_DeleteStmt:
|
||||
tag = "DELETE";
|
||||
break;
|
||||
|
||||
case T_UpdateStmt:
|
||||
tag = "UPDATE";
|
||||
break;
|
||||
|
||||
case T_SelectStmt:
|
||||
tag = "SELECT";
|
||||
break;
|
||||
|
||||
case T_TransactionStmt:
|
||||
{
|
||||
TransactionStmt *stmt = (TransactionStmt *) parsetree;
|
||||
|
||||
switch (stmt->command)
|
||||
{
|
||||
case BEGIN_TRANS:
|
||||
tag = "BEGIN";
|
||||
break;
|
||||
|
||||
case COMMIT:
|
||||
tag = "COMMIT";
|
||||
break;
|
||||
|
||||
case ROLLBACK:
|
||||
tag = "ROLLBACK";
|
||||
break;
|
||||
|
||||
default:
|
||||
tag = "???";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case T_ClosePortalStmt:
|
||||
tag = "CLOSE";
|
||||
break;
|
||||
|
||||
case T_FetchStmt:
|
||||
{
|
||||
FetchStmt *stmt = (FetchStmt *) parsetree;
|
||||
tag = (stmt->ismove) ? "MOVE" : "FETCH";
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateStmt:
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_DropStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_TruncateStmt:
|
||||
tag = "TRUNCATE";
|
||||
break;
|
||||
|
||||
case T_CommentStmt:
|
||||
tag = "COMMENT";
|
||||
break;
|
||||
|
||||
case T_CopyStmt:
|
||||
tag = "COPY";
|
||||
break;
|
||||
|
||||
case T_RenameStmt:
|
||||
tag = "ALTER";
|
||||
break;
|
||||
|
||||
case T_AlterTableStmt:
|
||||
tag = "ALTER";
|
||||
break;
|
||||
|
||||
case T_GrantStmt:
|
||||
{
|
||||
GrantStmt *stmt = (GrantStmt *) parsetree;
|
||||
tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
|
||||
}
|
||||
break;
|
||||
|
||||
case T_DefineStmt:
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_ViewStmt: /* CREATE VIEW */
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_ProcedureStmt: /* CREATE FUNCTION */
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_IndexStmt: /* CREATE INDEX */
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_RuleStmt: /* CREATE RULE */
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_CreateSeqStmt:
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_RemoveAggrStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_RemoveFuncStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_RemoveOperStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_VersionStmt:
|
||||
tag = "CREATE VERSION";
|
||||
break;
|
||||
|
||||
case T_CreatedbStmt:
|
||||
tag = "CREATE DATABASE";
|
||||
break;
|
||||
|
||||
case T_DropdbStmt:
|
||||
tag = "DROP DATABASE";
|
||||
break;
|
||||
|
||||
case T_NotifyStmt:
|
||||
tag = "NOTIFY";
|
||||
break;
|
||||
|
||||
case T_ListenStmt:
|
||||
tag = "LISTEN";
|
||||
break;
|
||||
|
||||
case T_UnlistenStmt:
|
||||
tag = "UNLISTEN";
|
||||
break;
|
||||
|
||||
case T_LoadStmt:
|
||||
tag = "LOAD";
|
||||
break;
|
||||
|
||||
case T_ClusterStmt:
|
||||
tag = "CLUSTER";
|
||||
break;
|
||||
|
||||
case T_VacuumStmt:
|
||||
if (((VacuumStmt *) parsetree)->vacuum)
|
||||
tag = "VACUUM";
|
||||
else
|
||||
tag = "ANALYZE";
|
||||
break;
|
||||
|
||||
case T_ExplainStmt:
|
||||
tag = "EXPLAIN";
|
||||
break;
|
||||
|
||||
#ifdef NOT_USED
|
||||
case T_RecipeStmt:
|
||||
tag = "EXECUTE RECIPE";
|
||||
break;
|
||||
#endif
|
||||
|
||||
case T_VariableSetStmt:
|
||||
tag = "SET VARIABLE";
|
||||
break;
|
||||
|
||||
case T_VariableShowStmt:
|
||||
tag = "SHOW VARIABLE";
|
||||
break;
|
||||
|
||||
case T_VariableResetStmt:
|
||||
tag = "RESET VARIABLE";
|
||||
break;
|
||||
|
||||
case T_CreateTrigStmt:
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_DropTrigStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_CreatePLangStmt:
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_DropPLangStmt:
|
||||
tag = "DROP";
|
||||
break;
|
||||
|
||||
case T_CreateUserStmt:
|
||||
tag = "CREATE USER";
|
||||
break;
|
||||
|
||||
case T_AlterUserStmt:
|
||||
tag = "ALTER USER";
|
||||
break;
|
||||
|
||||
case T_DropUserStmt:
|
||||
tag = "DROP USER";
|
||||
break;
|
||||
|
||||
case T_LockStmt:
|
||||
tag = "LOCK TABLE";
|
||||
break;
|
||||
|
||||
case T_ConstraintsSetStmt:
|
||||
tag = "SET CONSTRAINTS";
|
||||
break;
|
||||
|
||||
case T_CreateGroupStmt:
|
||||
tag = "CREATE GROUP";
|
||||
break;
|
||||
|
||||
case T_AlterGroupStmt:
|
||||
tag = "ALTER GROUP";
|
||||
break;
|
||||
|
||||
case T_DropGroupStmt:
|
||||
tag = "DROP GROUP";
|
||||
break;
|
||||
|
||||
case T_CheckPointStmt:
|
||||
tag = "CHECKPOINT";
|
||||
break;
|
||||
|
||||
case T_ReindexStmt:
|
||||
tag = "REINDEX";
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(DEBUG, "CreateCommandTag: unknown parse node type %d",
|
||||
nodeTag(parsetree));
|
||||
tag = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.46 2001/10/25 05:49:43 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.46.2.1 2002/02/26 23:48:45 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -23,9 +23,6 @@
|
||||
#include "utils/ps_status.h"
|
||||
|
||||
|
||||
static char *CreateOperationTag(int operationType);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* CreateQueryDesc
|
||||
* ----------------------------------------------------------------
|
||||
@ -89,42 +86,6 @@ CreateExecutorState(void)
|
||||
return state;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* CreateOperationTag
|
||||
*
|
||||
* utility to get a string representation of the
|
||||
* query operation.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static char *
|
||||
CreateOperationTag(int operationType)
|
||||
{
|
||||
char *tag;
|
||||
|
||||
switch (operationType)
|
||||
{
|
||||
case CMD_SELECT:
|
||||
tag = "SELECT";
|
||||
break;
|
||||
case CMD_INSERT:
|
||||
tag = "INSERT";
|
||||
break;
|
||||
case CMD_DELETE:
|
||||
tag = "DELETE";
|
||||
break;
|
||||
case CMD_UPDATE:
|
||||
tag = "UPDATE";
|
||||
break;
|
||||
default:
|
||||
elog(DEBUG, "CreateOperationTag: unknown operation type %d",
|
||||
operationType);
|
||||
tag = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* PreparePortal
|
||||
* ----------------
|
||||
@ -158,19 +119,25 @@ PreparePortal(char *portalName)
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ProcessQuery
|
||||
/*
|
||||
* ProcessQuery
|
||||
* Execute a query
|
||||
*
|
||||
* Execute a plan, the non-parallel version
|
||||
* ----------------------------------------------------------------
|
||||
* parsetree: the query tree
|
||||
* plan: the plan tree for the query
|
||||
* dest: where to send results
|
||||
* completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
|
||||
* in which to store a command completion status string.
|
||||
*
|
||||
* completionTag may be NULL if caller doesn't want a status string.
|
||||
*/
|
||||
void
|
||||
ProcessQuery(Query *parsetree,
|
||||
Plan *plan,
|
||||
CommandDest dest)
|
||||
CommandDest dest,
|
||||
char *completionTag)
|
||||
{
|
||||
int operation = parsetree->commandType;
|
||||
char *tag;
|
||||
bool isRetrieveIntoPortal;
|
||||
bool isRetrieveIntoRelation;
|
||||
char *intoName = NULL;
|
||||
@ -180,8 +147,6 @@ ProcessQuery(Query *parsetree,
|
||||
EState *state;
|
||||
TupleDesc attinfo;
|
||||
|
||||
set_ps_display(tag = CreateOperationTag(operation));
|
||||
|
||||
/*
|
||||
* initialize portal/into relation status
|
||||
*/
|
||||
@ -238,8 +203,7 @@ ProcessQuery(Query *parsetree,
|
||||
* When performing a retrieve into, we override the normal
|
||||
* communication destination during the processing of the the query.
|
||||
* This only affects the tuple-output function - the correct
|
||||
* destination will still see BeginCommand() and EndCommand()
|
||||
* messages.
|
||||
* destination will still see the BeginCommand() call.
|
||||
*/
|
||||
if (isRetrieveIntoRelation)
|
||||
queryDesc->dest = None;
|
||||
@ -263,7 +227,7 @@ ProcessQuery(Query *parsetree,
|
||||
attinfo,
|
||||
isRetrieveIntoRelation,
|
||||
isRetrieveIntoPortal,
|
||||
tag,
|
||||
NULL, /* not used */
|
||||
dest);
|
||||
|
||||
/*
|
||||
@ -281,7 +245,9 @@ ProcessQuery(Query *parsetree,
|
||||
/* Now we can return to caller's memory context. */
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
|
||||
EndCommand(tag, dest);
|
||||
/* Set completion tag. SQL calls this operation DECLARE CURSOR */
|
||||
if (completionTag)
|
||||
strcpy(completionTag, "DECLARE");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -292,16 +258,42 @@ ProcessQuery(Query *parsetree,
|
||||
*/
|
||||
ExecutorRun(queryDesc, state, EXEC_RUN, 0L);
|
||||
|
||||
/* save infos for EndCommand */
|
||||
UpdateCommandInfo(operation, state->es_lastoid, state->es_processed);
|
||||
/*
|
||||
* Build command completion status string, if caller wants one.
|
||||
*/
|
||||
if (completionTag)
|
||||
{
|
||||
Oid lastOid;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case CMD_SELECT:
|
||||
strcpy(completionTag, "SELECT");
|
||||
break;
|
||||
case CMD_INSERT:
|
||||
if (state->es_processed == 1)
|
||||
lastOid = state->es_lastoid;
|
||||
else
|
||||
lastOid = InvalidOid;
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"INSERT %u %u", lastOid, state->es_processed);
|
||||
break;
|
||||
case CMD_UPDATE:
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"UPDATE %u", state->es_processed);
|
||||
break;
|
||||
case CMD_DELETE:
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"DELETE %u", state->es_processed);
|
||||
break;
|
||||
default:
|
||||
strcpy(completionTag, "???");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, we close down all the scans and free allocated resources.
|
||||
*/
|
||||
ExecutorEnd(queryDesc, state);
|
||||
|
||||
/*
|
||||
* Notify the destination of end of processing.
|
||||
*/
|
||||
EndCommand(tag, dest);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.125 2002/02/07 00:27:30 inoue Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.125.2.1 2002/02/26 23:48:46 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -44,7 +44,6 @@
|
||||
#include "rewrite/rewriteRemove.h"
|
||||
#include "tcop/utility.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/temprel.h"
|
||||
#include "access/xlog.h"
|
||||
@ -130,18 +129,31 @@ CheckDropPermissions(char *name, char rightkind)
|
||||
}
|
||||
|
||||
|
||||
/* ----------------
|
||||
/*
|
||||
* ProcessUtility
|
||||
* general utility function invoker
|
||||
* ----------------
|
||||
*
|
||||
* parsetree: the parse tree for the utility statement
|
||||
* dest: where to send results
|
||||
* completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
|
||||
* in which to store a command completion status string.
|
||||
*
|
||||
* completionTag is only set nonempty if we want to return a nondefault
|
||||
* status (currently, only used for MOVE/FETCH).
|
||||
*
|
||||
* completionTag may be NULL if caller doesn't want a status string.
|
||||
*/
|
||||
void
|
||||
ProcessUtility(Node *parsetree,
|
||||
CommandDest dest)
|
||||
CommandDest dest,
|
||||
char *completionTag)
|
||||
{
|
||||
char *commandTag = NULL;
|
||||
char *relname;
|
||||
char *relationName;
|
||||
|
||||
if (completionTag)
|
||||
completionTag[0] = '\0';
|
||||
|
||||
switch (nodeTag(parsetree))
|
||||
{
|
||||
/*
|
||||
@ -155,17 +167,14 @@ ProcessUtility(Node *parsetree,
|
||||
switch (stmt->command)
|
||||
{
|
||||
case BEGIN_TRANS:
|
||||
set_ps_display(commandTag = "BEGIN");
|
||||
BeginTransactionBlock();
|
||||
break;
|
||||
|
||||
case COMMIT:
|
||||
set_ps_display(commandTag = "COMMIT");
|
||||
EndTransactionBlock();
|
||||
break;
|
||||
|
||||
case ROLLBACK:
|
||||
set_ps_display(commandTag = "ROLLBACK");
|
||||
UserAbortTransactionBlock();
|
||||
break;
|
||||
}
|
||||
@ -180,8 +189,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CLOSE");
|
||||
|
||||
PerformPortalClose(stmt->portalname, dest);
|
||||
}
|
||||
break;
|
||||
@ -193,8 +200,6 @@ ProcessUtility(Node *parsetree,
|
||||
bool forward;
|
||||
int count;
|
||||
|
||||
set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
|
||||
|
||||
SetQuerySnapshot();
|
||||
|
||||
forward = (bool) (stmt->direction == FORWARD);
|
||||
@ -204,8 +209,9 @@ ProcessUtility(Node *parsetree,
|
||||
*/
|
||||
|
||||
count = stmt->howMany;
|
||||
PerformPortalFetch(portalName, forward, count, commandTag,
|
||||
(stmt->ismove) ? None : dest); /* /dev/null for MOVE */
|
||||
PerformPortalFetch(portalName, forward, count,
|
||||
(stmt->ismove) ? None : dest,
|
||||
completionTag);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -215,8 +221,6 @@ ProcessUtility(Node *parsetree,
|
||||
*
|
||||
*/
|
||||
case T_CreateStmt:
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
|
||||
|
||||
/*
|
||||
@ -234,8 +238,6 @@ ProcessUtility(Node *parsetree,
|
||||
List *args = stmt->names;
|
||||
List *arg;
|
||||
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
foreach(arg, args)
|
||||
{
|
||||
relname = strVal(lfirst(arg));
|
||||
@ -296,8 +298,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
Relation rel;
|
||||
|
||||
set_ps_display(commandTag = "TRUNCATE");
|
||||
|
||||
relname = ((TruncateStmt *) parsetree)->relName;
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
|
||||
@ -325,8 +325,6 @@ ProcessUtility(Node *parsetree,
|
||||
|
||||
statement = ((CommentStmt *) parsetree);
|
||||
|
||||
set_ps_display(commandTag = "COMMENT");
|
||||
|
||||
CommentObject(statement->objtype, statement->objname,
|
||||
statement->objproperty, statement->objlist,
|
||||
statement->comment);
|
||||
@ -337,8 +335,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
CopyStmt *stmt = (CopyStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "COPY");
|
||||
|
||||
if (stmt->direction != FROM)
|
||||
SetQuerySnapshot();
|
||||
|
||||
@ -365,8 +361,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
RenameStmt *stmt = (RenameStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "ALTER");
|
||||
|
||||
relname = stmt->relname;
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
@ -413,8 +407,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "ALTER");
|
||||
|
||||
/*
|
||||
* Some or all of these functions are recursive to cover
|
||||
* inherited things, so permission checks are done there.
|
||||
@ -475,9 +467,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
GrantStmt *stmt = (GrantStmt *) parsetree;
|
||||
|
||||
commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
|
||||
set_ps_display(commandTag);
|
||||
|
||||
ExecuteGrantStmt(stmt);
|
||||
}
|
||||
break;
|
||||
@ -491,8 +480,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
DefineStmt *stmt = (DefineStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
switch (stmt->defType)
|
||||
{
|
||||
case OPERATOR:
|
||||
@ -514,15 +501,11 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ViewStmt *stmt = (ViewStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
DefineView(stmt->viewname, stmt->query); /* retrieve parsetree */
|
||||
}
|
||||
break;
|
||||
|
||||
case T_ProcedureStmt: /* CREATE FUNCTION */
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
CreateFunction((ProcedureStmt *) parsetree);
|
||||
break;
|
||||
|
||||
@ -530,8 +513,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
IndexStmt *stmt = (IndexStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
relname = stmt->relname;
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "CREATE INDEX: relation \"%s\" is a system catalog",
|
||||
@ -559,15 +540,12 @@ ProcessUtility(Node *parsetree,
|
||||
aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE);
|
||||
if (aclcheck_result != ACLCHECK_OK)
|
||||
elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
DefineQueryRewrite(stmt);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateSeqStmt:
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
DefineSequence((CreateSeqStmt *) parsetree);
|
||||
break;
|
||||
|
||||
@ -576,8 +554,6 @@ ProcessUtility(Node *parsetree,
|
||||
RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
|
||||
char *typename = (char *) NULL;
|
||||
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
if (stmt->aggtype != NULL)
|
||||
typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
|
||||
|
||||
@ -589,8 +565,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
RemoveFunction(stmt->funcname, stmt->args);
|
||||
}
|
||||
break;
|
||||
@ -603,8 +577,6 @@ ProcessUtility(Node *parsetree,
|
||||
char *typename1 = (char *) NULL;
|
||||
char *typename2 = (char *) NULL;
|
||||
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
if (typenode1 != NULL)
|
||||
typename1 = TypeNameToInternalName(typenode1);
|
||||
if (typenode2 != NULL)
|
||||
@ -622,8 +594,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CREATE DATABASE");
|
||||
|
||||
createdb(stmt->dbname, stmt->dbpath,
|
||||
stmt->dbtemplate, stmt->encoding);
|
||||
}
|
||||
@ -633,8 +603,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
DropdbStmt *stmt = (DropdbStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "DROP DATABASE");
|
||||
|
||||
dropdb(stmt->dbname);
|
||||
}
|
||||
break;
|
||||
@ -644,8 +612,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
NotifyStmt *stmt = (NotifyStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "NOTIFY");
|
||||
|
||||
Async_Notify(stmt->relname);
|
||||
}
|
||||
break;
|
||||
@ -654,8 +620,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ListenStmt *stmt = (ListenStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "LISTEN");
|
||||
|
||||
Async_Listen(stmt->relname, MyProcPid);
|
||||
}
|
||||
break;
|
||||
@ -664,8 +628,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "UNLISTEN");
|
||||
|
||||
Async_Unlisten(stmt->relname, MyProcPid);
|
||||
}
|
||||
break;
|
||||
@ -678,8 +640,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
LoadStmt *stmt = (LoadStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "LOAD");
|
||||
|
||||
closeAllVfds(); /* probably not necessary... */
|
||||
load_file(stmt->filename);
|
||||
}
|
||||
@ -689,8 +649,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ClusterStmt *stmt = (ClusterStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "CLUSTER");
|
||||
|
||||
relname = stmt->relname;
|
||||
if (IsSystemRelationName(relname))
|
||||
elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
|
||||
@ -703,12 +661,6 @@ ProcessUtility(Node *parsetree,
|
||||
break;
|
||||
|
||||
case T_VacuumStmt:
|
||||
if (((VacuumStmt *) parsetree)->vacuum)
|
||||
commandTag = "VACUUM";
|
||||
else
|
||||
commandTag = "ANALYZE";
|
||||
set_ps_display(commandTag);
|
||||
|
||||
vacuum((VacuumStmt *) parsetree);
|
||||
break;
|
||||
|
||||
@ -716,8 +668,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ExplainStmt *stmt = (ExplainStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "EXPLAIN");
|
||||
|
||||
ExplainQuery(stmt->query, stmt->verbose, stmt->analyze, dest);
|
||||
}
|
||||
break;
|
||||
@ -731,8 +681,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
RecipeStmt *stmt = (RecipeStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "EXECUTE RECIPE");
|
||||
|
||||
beginRecipe(stmt);
|
||||
}
|
||||
break;
|
||||
@ -746,7 +694,6 @@ ProcessUtility(Node *parsetree,
|
||||
VariableSetStmt *n = (VariableSetStmt *) parsetree;
|
||||
|
||||
SetPGVariable(n->name, n->args);
|
||||
set_ps_display(commandTag = "SET VARIABLE");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -755,7 +702,6 @@ ProcessUtility(Node *parsetree,
|
||||
VariableShowStmt *n = (VariableShowStmt *) parsetree;
|
||||
|
||||
GetPGVariable(n->name);
|
||||
set_ps_display(commandTag = "SHOW VARIABLE");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -764,7 +710,6 @@ ProcessUtility(Node *parsetree,
|
||||
VariableResetStmt *n = (VariableResetStmt *) parsetree;
|
||||
|
||||
ResetPGVariable(n->name);
|
||||
set_ps_display(commandTag = "RESET VARIABLE");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -772,14 +717,10 @@ ProcessUtility(Node *parsetree,
|
||||
* ******************************** TRIGGER statements *******************************
|
||||
*/
|
||||
case T_CreateTrigStmt:
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
CreateTrigger((CreateTrigStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_DropTrigStmt:
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
DropTrigger((DropTrigStmt *) parsetree);
|
||||
break;
|
||||
|
||||
@ -787,14 +728,10 @@ ProcessUtility(Node *parsetree,
|
||||
* ************* PROCEDURAL LANGUAGE statements *****************
|
||||
*/
|
||||
case T_CreatePLangStmt:
|
||||
set_ps_display(commandTag = "CREATE");
|
||||
|
||||
CreateProceduralLanguage((CreatePLangStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_DropPLangStmt:
|
||||
set_ps_display(commandTag = "DROP");
|
||||
|
||||
DropProceduralLanguage((DropPLangStmt *) parsetree);
|
||||
break;
|
||||
|
||||
@ -803,57 +740,39 @@ ProcessUtility(Node *parsetree,
|
||||
*
|
||||
*/
|
||||
case T_CreateUserStmt:
|
||||
set_ps_display(commandTag = "CREATE USER");
|
||||
|
||||
CreateUser((CreateUserStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_AlterUserStmt:
|
||||
set_ps_display(commandTag = "ALTER USER");
|
||||
|
||||
AlterUser((AlterUserStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_DropUserStmt:
|
||||
set_ps_display(commandTag = "DROP USER");
|
||||
|
||||
DropUser((DropUserStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_LockStmt:
|
||||
set_ps_display(commandTag = "LOCK TABLE");
|
||||
|
||||
LockTableCommand((LockStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_ConstraintsSetStmt:
|
||||
set_ps_display(commandTag = "SET CONSTRAINTS");
|
||||
|
||||
DeferredTriggerSetState((ConstraintsSetStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_CreateGroupStmt:
|
||||
set_ps_display(commandTag = "CREATE GROUP");
|
||||
|
||||
CreateGroup((CreateGroupStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_AlterGroupStmt:
|
||||
set_ps_display(commandTag = "ALTER GROUP");
|
||||
|
||||
AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
|
||||
break;
|
||||
|
||||
case T_DropGroupStmt:
|
||||
set_ps_display(commandTag = "DROP GROUP");
|
||||
|
||||
DropGroup((DropGroupStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_CheckPointStmt:
|
||||
{
|
||||
set_ps_display(commandTag = "CHECKPOINT");
|
||||
|
||||
if (!superuser())
|
||||
elog(ERROR, "permission denied");
|
||||
CreateCheckPoint(false);
|
||||
@ -864,8 +783,6 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
ReindexStmt *stmt = (ReindexStmt *) parsetree;
|
||||
|
||||
set_ps_display(commandTag = "REINDEX");
|
||||
|
||||
switch (stmt->reindexType)
|
||||
{
|
||||
case INDEX:
|
||||
@ -911,9 +828,4 @@ ProcessUtility(Node *parsetree,
|
||||
nodeTag(parsetree));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* tell fe/be or whatever that we're done.
|
||||
*/
|
||||
EndCommand(commandTag, dest);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: command.h,v 1.31 2001/11/05 17:46:33 momjian Exp $
|
||||
* $Id: command.h,v 1.31.2.1 2002/02/26 23:48:46 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,7 +27,7 @@
|
||||
* "ERROR" if portal not found.
|
||||
*/
|
||||
extern void PerformPortalFetch(char *name, bool forward, int count,
|
||||
char *tag, CommandDest dest);
|
||||
CommandDest dest, char *completionTag);
|
||||
|
||||
/*
|
||||
* PerformPortalClose
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.151 2001/11/05 17:46:34 momjian Exp $
|
||||
* $Id: parsenodes.h,v 1.151.2.1 2002/02/26 23:48:46 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -48,6 +48,8 @@ typedef struct Query
|
||||
bool hasAggs; /* has aggregates in tlist or havingQual */
|
||||
bool hasSubLinks; /* has subquery SubLink */
|
||||
|
||||
bool originalQuery; /* marks original query through rewriting */
|
||||
|
||||
List *rtable; /* list of range table entries */
|
||||
FromExpr *jointree; /* table join tree (FROM and WHERE
|
||||
* clauses) */
|
||||
|
@ -39,7 +39,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: dest.h,v 1.28 2001/11/05 17:46:36 momjian Exp $
|
||||
* $Id: dest.h,v 1.28.2.1 2002/02/26 23:48:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -48,6 +48,11 @@
|
||||
|
||||
#include "access/htup.h"
|
||||
|
||||
|
||||
/* buffer size to use for command completion tags */
|
||||
#define COMPLETION_TAG_BUFSIZE 64
|
||||
|
||||
|
||||
/* ----------------
|
||||
* CommandDest is a simplistic means of identifying the desired
|
||||
* destination. Someday this will probably need to be improved.
|
||||
@ -88,7 +93,7 @@ extern void BeginCommand(char *pname, int operation, TupleDesc attinfo,
|
||||
bool isIntoRel, bool isIntoPortal, char *tag,
|
||||
CommandDest dest);
|
||||
extern DestReceiver *DestToFunction(CommandDest dest);
|
||||
extern void EndCommand(char *commandTag, CommandDest dest);
|
||||
extern void EndCommand(const char *commandTag, CommandDest dest);
|
||||
|
||||
/* Additional functions that go with destination management, more or less. */
|
||||
|
||||
@ -96,6 +101,5 @@ extern void SendCopyBegin(void);
|
||||
extern void ReceiveCopyBegin(void);
|
||||
extern void NullCommand(CommandDest dest);
|
||||
extern void ReadyForQuery(CommandDest dest);
|
||||
extern void UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples);
|
||||
|
||||
#endif /* DEST_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pquery.h,v 1.19 2001/11/05 17:46:36 momjian Exp $
|
||||
* $Id: pquery.h,v 1.19.2.1 2002/02/26 23:48:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -18,7 +18,8 @@
|
||||
#include "utils/portal.h"
|
||||
|
||||
|
||||
extern void ProcessQuery(Query *parsetree, Plan *plan, CommandDest dest);
|
||||
extern void ProcessQuery(Query *parsetree, Plan *plan, CommandDest dest,
|
||||
char *completionTag);
|
||||
|
||||
extern EState *CreateExecutorState(void);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: utility.h,v 1.13 2001/11/05 17:46:36 momjian Exp $
|
||||
* $Id: utility.h,v 1.13.2.1 2002/02/26 23:48:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#include "executor/execdesc.h"
|
||||
|
||||
extern void ProcessUtility(Node *parsetree, CommandDest dest);
|
||||
extern void ProcessUtility(Node *parsetree, CommandDest dest,
|
||||
char *completionTag);
|
||||
|
||||
#endif /* UTILITY_H */
|
||||
|
Loading…
Reference in New Issue
Block a user