diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index b867df5581f2f0e8a21831bae1a0eaf7abd87d97..b1a0fe28ca5512220d3f12a0a1ea2fcf07654cb6 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.298 2008/09/01 20:42:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.299 2008/10/10 13:48:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -147,7 +147,8 @@ check_xact_readonly(Node *parsetree)
 
 	/*
 	 * Note: Commands that need to do more complicated checking are handled
-	 * elsewhere.
+	 * elsewhere, in particular COPY and plannable statements do their
+	 * own checking.
 	 */
 
 	switch (nodeTag(parsetree))
@@ -2015,10 +2016,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_ALL;
 			break;
 
-		case T_CreateDomainStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_CreateSchemaStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2054,6 +2051,33 @@ GetCommandLogLevel(Node *parsetree)
 				lev = LOGSTMT_ALL;
 			break;
 
+		case T_PrepareStmt:
+			{
+				PrepareStmt *stmt = (PrepareStmt *) parsetree;
+
+				/* Look through a PREPARE to the contained stmt */
+				lev = GetCommandLogLevel(stmt->query);
+			}
+			break;
+
+		case T_ExecuteStmt:
+			{
+				ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
+				PreparedStatement *ps;
+
+				/* Look through an EXECUTE to the referenced stmt */
+				ps = FetchPreparedStatement(stmt->name, false);
+				if (ps)
+					lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
+				else
+					lev = LOGSTMT_ALL;
+			}
+			break;
+
+		case T_DeallocateStmt:
+			lev = LOGSTMT_ALL;
+			break;
+
 		case T_RenameStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2074,10 +2098,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_AlterFunctionStmt:
-			lev = LOGSTMT_DDL;
-			break;
-
 		case T_GrantStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2106,6 +2126,10 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
+		case T_AlterFunctionStmt:
+			lev = LOGSTMT_DDL;
+			break;
+
 		case T_IndexStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2186,6 +2210,10 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_ALL;
 			break;
 
+		case T_DiscardStmt:
+			lev = LOGSTMT_ALL;
+			break;
+
 		case T_CreateTrigStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2202,6 +2230,10 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
+		case T_CreateDomainStmt:
+			lev = LOGSTMT_DDL;
+			break;
+
 		case T_CreateRoleStmt:
 			lev = LOGSTMT_DDL;
 			break;
@@ -2282,33 +2314,6 @@ GetCommandLogLevel(Node *parsetree)
 			lev = LOGSTMT_DDL;
 			break;
 
-		case T_PrepareStmt:
-			{
-				PrepareStmt *stmt = (PrepareStmt *) parsetree;
-
-				/* Look through a PREPARE to the contained stmt */
-				lev = GetCommandLogLevel(stmt->query);
-			}
-			break;
-
-		case T_ExecuteStmt:
-			{
-				ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
-				PreparedStatement *ps;
-
-				/* Look through an EXECUTE to the referenced stmt */
-				ps = FetchPreparedStatement(stmt->name, false);
-				if (ps)
-					lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
-				else
-					lev = LOGSTMT_ALL;
-			}
-			break;
-
-		case T_DeallocateStmt:
-			lev = LOGSTMT_ALL;
-			break;
-
 			/* already-planned queries */
 		case T_PlannedStmt:
 			{