diff options
author | Bruce Momjian <bruce@momjian.us> | 2004-04-07 05:05:50 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2004-04-07 05:05:50 +0000 |
commit | 6a25c6e1d1036db1162f3137bfc8213ecd7446a4 (patch) | |
tree | aa10ef836d9d8596bf52cf7d214eae512d464556 /src/backend/tcop/postgres.c | |
parent | e5170860eeaf28802375d0e1d51689b491958571 (diff) | |
download | postgresql-6a25c6e1d1036db1162f3137bfc8213ecd7446a4.tar.gz postgresql-6a25c6e1d1036db1162f3137bfc8213ecd7446a4.zip |
> >>1. change the type of "log_statement" option from boolean to string,
> >>with allowed values of "all, mod, ddl, none" with default "none".
OK, here is a patch that implements #1. Here is sample output:
test=> set client_min_messages = 'log';
SET
test=> set log_statement = 'mod';
SET
test=> select 1;
?column?
----------
1
(1 row)
test=> update test set x=1;
LOG: statement: update test set x=1;
ERROR: relation "test" does not exist
test=> update test set x=1;
LOG: statement: update test set x=1;
ERROR: relation "test" does not exist
test=> copy test from '/tmp/x';
LOG: statement: copy test from '/tmp/x';
ERROR: relation "test" does not exist
test=> copy test to '/tmp/x';
ERROR: relation "test" does not exist
test=> prepare xx as select 1;
PREPARE
test=> prepare xx as update x set y=1;
LOG: statement: prepare xx as update x set y=1;
ERROR: relation "x" does not exist
test=> explain analyze select 1;;
QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.006..0.007 rows=1 loops=1)
Total runtime: 0.046 ms
(2 rows)
test=> explain analyze update test set x=1;
LOG: statement: explain analyze update test set x=1;
ERROR: relation "test" does not exist
test=> explain update test set x=1;
ERROR: relation "test" does not exist
It checks PREPARE and EXECUTE ANALYZE too. The log_statement values are
'none', 'mod', 'ddl', and 'all'. For 'all', it prints before the query
is parsed, and for ddl/mod, it does it right after parsing using the
node tag (or command tag for CREATE/ALTER/DROP), so any non-parse errors
will print after the log line.
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index ff0ac6aa64a..6cece54b30b 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.397 2004/03/24 22:40:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.398 2004/04/07 05:05:49 momjian Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -87,6 +87,8 @@ bool InError = false; /* flag for logging end of session */ bool Log_disconnections = false; +LogStmtLevel log_statement = LOGSTMT_NONE; + /* * Flags for expensive function optimization -- JMH 3/9/92 */ @@ -471,9 +473,10 @@ pg_parse_and_rewrite(const char *query_string, /* string to execute */ List * pg_parse_query(const char *query_string) { - List *raw_parsetree_list; + List *raw_parsetree_list, + *parsetree_item; - if (log_statement) + if (log_statement == LOGSTMT_ALL) ereport(LOG, (errmsg("statement: %s", query_string))); @@ -482,6 +485,51 @@ pg_parse_query(const char *query_string) raw_parsetree_list = raw_parser(query_string); + /* do log_statement tests for mod and ddl */ + if (log_statement == LOGSTMT_MOD || + log_statement == LOGSTMT_DDL) + { + foreach(parsetree_item, raw_parsetree_list) + { + Node *parsetree = (Node *) lfirst(parsetree_item); + const char *commandTag; + + if (IsA(parsetree, ExplainStmt) && + ((ExplainStmt *)parsetree)->analyze) + parsetree = (Node *)(((ExplainStmt *)parsetree)->query); + + if (IsA(parsetree, PrepareStmt)) + parsetree = (Node *)(((PrepareStmt *)parsetree)->query); + + if (IsA(parsetree, SelectStmt)) + continue; /* optimization for frequent command */ + + if (log_statement == LOGSTMT_MOD && + (IsA(parsetree, InsertStmt) || + IsA(parsetree, UpdateStmt) || + IsA(parsetree, DeleteStmt) || + IsA(parsetree, TruncateStmt) || + (IsA(parsetree, CopyStmt) && + ((CopyStmt *)parsetree)->is_from))) /* COPY FROM */ + { + ereport(LOG, + (errmsg("statement: %s", query_string))); + break; + } + commandTag = CreateCommandTag(parsetree); + if (strncmp(commandTag, "CREATE ", strlen("CREATE ")) == 0 || + strncmp(commandTag, "ALTER ", strlen("ALTER ")) == 0 || + strncmp(commandTag, "DROP ", strlen("DROP ")) == 0 || + IsA(parsetree, GrantStmt) || /* GRANT or REVOKE */ + IsA(parsetree, CommentStmt)) + { + ereport(LOG, + (errmsg("statement: %s", query_string))); + break; + } + } + } + if (log_parser_stats) ShowUsage("PARSER STATISTICS"); @@ -2488,7 +2536,7 @@ PostgresMain(int argc, char *argv[], const char *username) SetConfigOption("log_disconnections", "true", debug_context, gucsource); } if (debug_flag >= 2) - SetConfigOption("log_statement", "true", debug_context, gucsource); + SetConfigOption("log_statement", "all", debug_context, gucsource); if (debug_flag >= 3) SetConfigOption("debug_print_parse", "true", debug_context, gucsource); if (debug_flag >= 4) |