*** ./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; }