*** ./src/bin/psql/common.c.orig	2004-09-19 23:08:34.000000000 +0200
--- ./src/bin/psql/common.c	2004-09-19 23:10:23.000000000 +0200
***************
*** 946,962 ****
  	return OK;
  }
  
  /*
!  * check whether a query string begins with BEGIN/COMMIT/ROLLBACK/START XACT
   */
! static bool
! is_transact_command(const char *query)
  {
- 	int			wordlen;
- 
- 	/*
- 	 * First we must advance over any whitespace and comments.
- 	 */
  	while (*query)
  	{
  		if (isspace((unsigned char) *query))
--- 946,959 ----
  	return OK;
  }
  
+ 
  /*
!  * Advance the given char* over noise (white space, comments).
!  * This is used for is_transact_command. 
   */
! static char *
! command_remove_noise(const char *query)
  {
  	while (*query)
  	{
  		if (isspace((unsigned char) *query))
***************
*** 985,990 ****
--- 982,1006 ----
  			break;				/* found first token */
  	}
  
+ 	return query;
+ }
+ 
+ 
+ /*
+  * check whether a query is either a transaction modifying statement
+  * (BEGIN,COMMIT,ROLLBACK,ABORT,END,START) or a statement that must
+  * not be executed within a transaction
+  */
+ static bool
+ is_transact_command(const char *query)
+ {
+ 	int			wordlen;
+ 
+ 	/*
+ 	 * First we must advance over any whitespace and comments.
+ 	 */
+ 	query = command_remove_noise(query);
+ 
  	/*
  	 * Check word length ("beginx" is not "begin").
  	 */
***************
*** 992,997 ****
--- 1008,1016 ----
  	while (isalpha((unsigned char) query[wordlen]))
  		wordlen++;
  
+ 	/*
+ 	 * Trx modifying commands.
+ 	 */
  	if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
  		return true;
  	if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
***************
*** 1005,1010 ****
--- 1024,1058 ----
  	if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
  		return true;
  
+ 	/*
+ 	 * Commands not allowed within transactions.
+ 	 */
+ 	if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
+ 		return true;
+ 	if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
+ 		return true;
+ 
+ 	/*
+ 	 * Commands that can only be detected at the second word.
+ 	 */
+ 	if ((wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0) ||
+ 		(wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
+ 		(wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
+ 	{
+ 		query += wordlen;
+ 
+ 		query = command_remove_noise(query);
+ 
+ 		wordlen = 0;
+ 		while (isalpha((unsigned char) query[wordlen]))
+ 			wordlen++;
+ 
+ 		if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
+ 			return true;
+ 		if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
+ 			return true;
+ 	}
+ 
  	return false;
  }
  
