提交 906651f6 编写于 作者: M Marc G. Fournier

There is a bug in the function executor. The backend crashes while trying to

execute an sql function containing an utility command (create, notify, ...).
The bug is part in the planner, which returns a number of plans different
than the number of commands if there are utility commands in the query, and
in part in the function executor which assumes that all commands are normal
query commands and causes a SIGSEGV trying to execute commands without plan.

Submitted by: Massimo Dal Zotto <dz@cs.unitn.it>
上级 47549313
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.1.1.1 1996/07/09 06:21:25 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.2 1996/09/16 05:36:15 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -160,6 +160,14 @@ init_execution_state(FunctionCachePtr fcache, ...@@ -160,6 +160,14 @@ init_execution_state(FunctionCachePtr fcache,
static TupleDesc static TupleDesc
postquel_start(execution_state *es) postquel_start(execution_state *es)
{ {
#ifdef FUNC_UTIL_PATCH
/*
* Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
*/
if (es->qd->operation == CMD_UTILITY) {
return (TupleDesc) NULL;
}
#endif
return ExecutorStart(es->qd, es->estate); return ExecutorStart(es->qd, es->estate);
} }
...@@ -168,6 +176,17 @@ postquel_getnext(execution_state *es) ...@@ -168,6 +176,17 @@ postquel_getnext(execution_state *es)
{ {
int feature; int feature;
#ifdef FUNC_UTIL_PATCH
if (es->qd->operation == CMD_UTILITY) {
/*
* Process an utility command. (create, destroy...) DZ - 30-8-1996
*/
ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
if (!LAST_POSTQUEL_COMMAND(es)) CommandCounterIncrement();
return (TupleTableSlot*) NULL;
}
#endif
feature = (LAST_POSTQUEL_COMMAND(es)) ? EXEC_RETONE : EXEC_RUN; feature = (LAST_POSTQUEL_COMMAND(es)) ? EXEC_RETONE : EXEC_RUN;
return ExecutorRun(es->qd, es->estate, feature, 0); return ExecutorRun(es->qd, es->estate, feature, 0);
...@@ -176,6 +195,14 @@ postquel_getnext(execution_state *es) ...@@ -176,6 +195,14 @@ postquel_getnext(execution_state *es)
static void static void
postquel_end(execution_state *es) postquel_end(execution_state *es)
{ {
#ifdef FUNC_UTIL_PATCH
/*
* Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
*/
if (es->qd->operation == CMD_UTILITY) {
return;
}
#endif
ExecutorEnd(es->qd, es->estate); ExecutorEnd(es->qd, es->estate);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.7 1996/09/10 06:48:52 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.8 1996/09/16 05:36:38 scrappy Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -547,6 +547,16 @@ pg_plan(char *query_string, /* string to execute */ ...@@ -547,6 +547,16 @@ pg_plan(char *query_string, /* string to execute */
} }
#endif #endif
} }
#ifdef FUNC_UTIL_PATCH
/*
* If the command is an utility append a null plan. This is
* needed to keep the plan_list aligned with the querytree_list
* or the function executor will crash. DZ - 30-8-1996
*/
else {
plan_list = lappend(plan_list, NULL);
}
#endif
} }
if (queryListP) if (queryListP)
...@@ -601,6 +611,14 @@ pg_eval_dest(char *query_string, /* string to execute */ ...@@ -601,6 +611,14 @@ pg_eval_dest(char *query_string, /* string to execute */
for (i=0;i<querytree_list->len;i++) { for (i=0;i<querytree_list->len;i++) {
querytree = querytree_list->qtrees[i]; querytree = querytree_list->qtrees[i];
#ifdef FUNC_UTIL_PATCH
/*
* Advance on the plan_list in every case. Now the plan_list
* has the same length of the querytree_list. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list);
#endif
if (querytree->commandType == CMD_UTILITY) { if (querytree->commandType == CMD_UTILITY) {
/* ---------------- /* ----------------
* process utility functions (create, destroy, etc..) * process utility functions (create, destroy, etc..)
...@@ -617,8 +635,13 @@ pg_eval_dest(char *query_string, /* string to execute */ ...@@ -617,8 +635,13 @@ pg_eval_dest(char *query_string, /* string to execute */
ProcessUtility(querytree->utilityStmt, dest); ProcessUtility(querytree->utilityStmt, dest);
} else { } else {
#ifndef FUNC_UTIL_PATCH
/*
* Moved before the if. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list); plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list); plan_list = lnext(plan_list);
#endif
#ifdef INDEXSCAN_PATCH #ifdef INDEXSCAN_PATCH
/* /*
...@@ -1246,7 +1269,7 @@ PostgresMain(int argc, char *argv[]) ...@@ -1246,7 +1269,7 @@ PostgresMain(int argc, char *argv[])
*/ */
if (IsUnderPostmaster == false) { if (IsUnderPostmaster == false) {
puts("\nPOSTGRES backend interactive interface"); puts("\nPOSTGRES backend interactive interface");
puts("$Revision: 1.7 $ $Date: 1996/09/10 06:48:52 $"); puts("$Revision: 1.8 $ $Date: 1996/09/16 05:36:38 $");
} }
/* ---------------- /* ----------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册