From 906651f663669036a0a9680ff4105c5828c9190c Mon Sep 17 00:00:00 2001
From: "Marc G. Fournier" <scrappy@hub.org>
Date: Mon, 16 Sep 1996 05:36:38 +0000
Subject: [PATCH] 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>
---
 src/backend/executor/functions.c | 29 ++++++++++++++++++++++++++++-
 src/backend/tcop/postgres.c      | 27 +++++++++++++++++++++++++--
 2 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 2f6e29d8277..47baa11850a 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
  *
  *
  * 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,
 static TupleDesc
 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);
 }
 
@@ -168,6 +176,17 @@ postquel_getnext(execution_state *es)
 {
     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;
     
     return ExecutorRun(es->qd, es->estate, feature, 0);
@@ -176,6 +195,14 @@ postquel_getnext(execution_state *es)
 static void
 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);
 }
 
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0abb084a591..43fb9003c7f 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -7,7 +7,7 @@
  *
  *
  * 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
  *    this is the "main" module of the postgres backend and
@@ -547,6 +547,16 @@ pg_plan(char *query_string,	/* string to execute */
 	    }
 #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)
@@ -601,6 +611,14 @@ pg_eval_dest(char *query_string, /* string to execute */
     for (i=0;i<querytree_list->len;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) {
 	    /* ----------------
 	     *   process utility functions (create, destroy, etc..)
@@ -617,8 +635,13 @@ pg_eval_dest(char *query_string, /* string to execute */
 	    ProcessUtility(querytree->utilityStmt, dest);
 	    
 	} else {
+#ifndef FUNC_UTIL_PATCH
+	    /*
+	     * Moved before the if.  DZ - 30-8-1996
+	     */
 	    plan = (Plan *) lfirst(plan_list);
 	    plan_list = lnext(plan_list);
+#endif
 	    
 #ifdef INDEXSCAN_PATCH
 	    /*
@@ -1246,7 +1269,7 @@ PostgresMain(int argc, char *argv[])
      */
     if (IsUnderPostmaster == false) {
 	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 $");
     }
     
     /* ----------------
-- 
GitLab