Skip to content

Commit 6a25c6e

Browse files
committed
> >>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.
1 parent e517086 commit 6a25c6e

File tree

6 files changed

+161
-50
lines changed

6 files changed

+161
-50
lines changed

doc/src/sgml/runtime.sgml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.257 2004/04/05 03:02:03 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.258 2004/04/07 05:05:49 momjian Exp $
33
-->
44

55
<Chapter Id="runtime">
@@ -2121,12 +2121,21 @@ SET ENABLE_SEQSCAN TO OFF;
21212121
</varlistentry>
21222122

21232123
<varlistentry id="guc-log-statement" xreflabel="log_statement">
2124-
<term><varname>log_statement</varname> (<type>boolean</type>)</term>
2125-
<listitem>
2126-
<para>
2127-
Causes each SQL statement to be logged. The default is
2128-
off. Only superusers can disable this option if it has been
2129-
enabled by an administrator.
2124+
<term><varname>log_statement</varname> (<type>string</type>)</term>
2125+
<listitem>
2126+
<para>
2127+
Controls which SQL statement are logged. Valid values are
2128+
<literal>all</>, <literal>ddl</>, <literal>mod</>, and
2129+
<literal>none</>. <literal>ddl</> logs all data definition
2130+
commands like <literal>CREATE</>, <literal>ALTER</>, and
2131+
<literal>DROP</> commands. <literal>mod</> logs all
2132+
<literal>ddl</> statements, plus <literal>INSERT</>,
2133+
<literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
2134+
and <literal>COPY FROM</>. <literal>PREPARE</> and
2135+
<literal>EXPLAIN ANALYZE</> statements are also considered for
2136+
appropriate commands. The default is <literal>none</>. Only
2137+
superusers can reduce the detail of this option if it has been
2138+
set by an administrator.
21302139
</para>
21312140

21322141
<note>

src/backend/tcop/postgres.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.397 2004/03/24 22:40:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.398 2004/04/07 05:05:49 momjian Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -87,6 +87,8 @@ bool InError = false;
8787
/* flag for logging end of session */
8888
bool Log_disconnections = false;
8989

90+
LogStmtLevel log_statement = LOGSTMT_NONE;
91+
9092
/*
9193
* Flags for expensive function optimization -- JMH 3/9/92
9294
*/
@@ -471,9 +473,10 @@ pg_parse_and_rewrite(const char *query_string, /* string to execute */
471473
List *
472474
pg_parse_query(const char *query_string)
473475
{
474-
List *raw_parsetree_list;
476+
List *raw_parsetree_list,
477+
*parsetree_item;
475478

476-
if (log_statement)
479+
if (log_statement == LOGSTMT_ALL)
477480
ereport(LOG,
478481
(errmsg("statement: %s", query_string)));
479482

@@ -482,6 +485,51 @@ pg_parse_query(const char *query_string)
482485

483486
raw_parsetree_list = raw_parser(query_string);
484487

488+
/* do log_statement tests for mod and ddl */
489+
if (log_statement == LOGSTMT_MOD ||
490+
log_statement == LOGSTMT_DDL)
491+
{
492+
foreach(parsetree_item, raw_parsetree_list)
493+
{
494+
Node *parsetree = (Node *) lfirst(parsetree_item);
495+
const char *commandTag;
496+
497+
if (IsA(parsetree, ExplainStmt) &&
498+
((ExplainStmt *)parsetree)->analyze)
499+
parsetree = (Node *)(((ExplainStmt *)parsetree)->query);
500+
501+
if (IsA(parsetree, PrepareStmt))
502+
parsetree = (Node *)(((PrepareStmt *)parsetree)->query);
503+
504+
if (IsA(parsetree, SelectStmt))
505+
continue; /* optimization for frequent command */
506+
507+
if (log_statement == LOGSTMT_MOD &&
508+
(IsA(parsetree, InsertStmt) ||
509+
IsA(parsetree, UpdateStmt) ||
510+
IsA(parsetree, DeleteStmt) ||
511+
IsA(parsetree, TruncateStmt) ||
512+
(IsA(parsetree, CopyStmt) &&
513+
((CopyStmt *)parsetree)->is_from))) /* COPY FROM */
514+
{
515+
ereport(LOG,
516+
(errmsg("statement: %s", query_string)));
517+
break;
518+
}
519+
commandTag = CreateCommandTag(parsetree);
520+
if (strncmp(commandTag, "CREATE ", strlen("CREATE ")) == 0 ||
521+
strncmp(commandTag, "ALTER ", strlen("ALTER ")) == 0 ||
522+
strncmp(commandTag, "DROP ", strlen("DROP ")) == 0 ||
523+
IsA(parsetree, GrantStmt) || /* GRANT or REVOKE */
524+
IsA(parsetree, CommentStmt))
525+
{
526+
ereport(LOG,
527+
(errmsg("statement: %s", query_string)));
528+
break;
529+
}
530+
}
531+
}
532+
485533
if (log_parser_stats)
486534
ShowUsage("PARSER STATISTICS");
487535

@@ -2488,7 +2536,7 @@ PostgresMain(int argc, char *argv[], const char *username)
24882536
SetConfigOption("log_disconnections", "true", debug_context, gucsource);
24892537
}
24902538
if (debug_flag >= 2)
2491-
SetConfigOption("log_statement", "true", debug_context, gucsource);
2539+
SetConfigOption("log_statement", "all", debug_context, gucsource);
24922540
if (debug_flag >= 3)
24932541
SetConfigOption("debug_print_parse", "true", debug_context, gucsource);
24942542
if (debug_flag >= 4)

src/backend/utils/misc/guc.c

Lines changed: 77 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.197 2004/04/05 03:02:07 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.198 2004/04/07 05:05:50 momjian Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -86,18 +86,22 @@ static const char *assign_facility(const char *facility,
8686
bool doit, GucSource source);
8787
#endif
8888

89-
static const char *assign_defaultxactisolevel(const char *newval,
90-
bool doit, GucSource source);
91-
static const char *assign_log_min_messages(const char *newval,
92-
bool doit, GucSource source);
89+
static const char *assign_defaultxactisolevel(const char *newval, bool doit,
90+
GucSource source);
91+
static const char *assign_log_min_messages(const char *newval, bool doit,
92+
GucSource source);
9393
static const char *assign_client_min_messages(const char *newval,
9494
bool doit, GucSource source);
9595
static const char *assign_min_error_statement(const char *newval, bool doit,
9696
GucSource source);
97-
static const char *assign_msglvl(int *var, const char *newval,
98-
bool doit, GucSource source);
97+
static const char *assign_msglvl(int *var, const char *newval, bool doit,
98+
GucSource source);
9999
static const char *assign_log_error_verbosity(const char *newval, bool doit,
100100
GucSource source);
101+
static const char *assign_log_statement(const char *newval, bool doit,
102+
GucSource source);
103+
static const char *assign_log_stmtlvl(int *var, const char *newval,
104+
bool doit, GucSource source);
101105
static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
102106

103107

@@ -107,7 +111,6 @@ static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
107111
#ifdef USE_ASSERT_CHECKING
108112
bool assert_enabled = true;
109113
#endif
110-
bool log_statement = false;
111114
bool log_duration = false;
112115
bool Debug_print_plan = false;
113116
bool Debug_print_parse = false;
@@ -145,6 +148,7 @@ int log_min_duration_statement = -1;
145148
static char *client_min_messages_str;
146149
static char *log_min_messages_str;
147150
static char *log_error_verbosity_str;
151+
static char *log_statement_str;
148152
static char *log_min_error_statement_str;
149153
static char *log_destination_string;
150154
static bool phony_autocommit;
@@ -527,14 +531,6 @@ static struct config_bool ConfigureNamesBool[] =
527531
&ExitOnAnyError,
528532
false, NULL, NULL
529533
},
530-
{
531-
{"log_statement", PGC_USERLIMIT, LOGGING_WHAT,
532-
gettext_noop("Logs each SQL statement."),
533-
NULL
534-
},
535-
&log_statement,
536-
false, NULL, NULL
537-
},
538534
{
539535
{"log_duration", PGC_USERLIMIT, LOGGING_WHAT,
540536
gettext_noop("Logs the duration each completed SQL statement."),
@@ -1442,6 +1438,14 @@ static struct config_string ConfigureNamesString[] =
14421438
&log_error_verbosity_str,
14431439
"default", assign_log_error_verbosity, NULL
14441440
},
1441+
{
1442+
{"log_statement", PGC_USERLIMIT, LOGGING_WHAT,
1443+
gettext_noop("Sets the type of statements logged."),
1444+
gettext_noop("Valid values are \"none\", \"mod\", \"ddl\", and \"all\".")
1445+
},
1446+
&log_statement_str,
1447+
"none", assign_log_statement, NULL
1448+
},
14451449

14461450
{
14471451
{"log_min_error_statement", PGC_USERLIMIT, LOGGING_WHEN,
@@ -2007,14 +2011,11 @@ InitializeGUCOptions(void)
20072011
struct config_string *conf = (struct config_string *) gconf;
20082012
char *str;
20092013

2010-
/*
2011-
* Check to make sure we only have valid
2012-
* PGC_USERLIMITs
2013-
*/
2014+
/* Check to make sure we only have valid PGC_USERLIMITs */
20142015
Assert(conf->gen.context != PGC_USERLIMIT ||
20152016
conf->assign_hook == assign_log_min_messages ||
2016-
conf->assign_hook == assign_client_min_messages ||
2017-
conf->assign_hook == assign_min_error_statement);
2017+
conf->assign_hook == assign_min_error_statement ||
2018+
conf->assign_hook == assign_log_statement);
20182019
*conf->variable = NULL;
20192020
conf->reset_val = NULL;
20202021
conf->session_val = NULL;
@@ -3025,15 +3026,23 @@ set_config_option(const char *name, const char *value,
30253026
if (record->context == PGC_USERLIMIT &&
30263027
IsUnderPostmaster && !superuser())
30273028
{
3028-
int old_int_value,
3029-
new_int_value;
3030-
3031-
/* all USERLIMIT strings are message levels */
3032-
assign_msglvl(&new_int_value, newval,
3033-
true, source);
3034-
assign_msglvl(&old_int_value, conf->reset_val,
3035-
true, source);
3036-
if (new_int_value > old_int_value)
3029+
int var_value, reset_value, new_value;
3030+
const char * (*var_hook) (int *var, const char *newval,
3031+
bool doit, GucSource source);
3032+
3033+
if (conf->assign_hook == assign_log_statement)
3034+
var_hook = assign_log_stmtlvl;
3035+
else
3036+
var_hook = assign_msglvl;
3037+
3038+
(*var_hook) (&new_value, newval, true, source);
3039+
(*var_hook) (&reset_value, conf->reset_val, true,
3040+
source);
3041+
(*var_hook) (&var_value, *conf->variable, true,
3042+
source);
3043+
3044+
/* Limit non-superuser changes */
3045+
if (new_value > reset_value)
30373046
{
30383047
/* Limit non-superuser changes */
30393048
if (source > PGC_S_UNPRIVILEGED)
@@ -3046,10 +3055,9 @@ set_config_option(const char *name, const char *value,
30463055
return false;
30473056
}
30483057
}
3049-
/* Allow change if admin should override */
3050-
assign_msglvl(&old_int_value, *conf->variable,
3051-
true, source);
3052-
if (new_int_value < old_int_value)
3058+
3059+
/* Allow change if admin should override */
3060+
if (new_value < var_value)
30533061
{
30543062
if (source < PGC_S_UNPRIVILEGED &&
30553063
record->source > PGC_S_UNPRIVILEGED)
@@ -4652,6 +4660,40 @@ assign_log_error_verbosity(const char *newval, bool doit, GucSource source)
46524660
return newval; /* OK */
46534661
}
46544662

4663+
static const char *
4664+
assign_log_statement(const char *newval, bool doit, GucSource source)
4665+
{
4666+
return (assign_log_stmtlvl((int *)&log_statement, newval, doit, source));
4667+
}
4668+
4669+
static const char *
4670+
assign_log_stmtlvl(int *var, const char *newval, bool doit, GucSource source)
4671+
{
4672+
if (strcasecmp(newval, "none") == 0)
4673+
{
4674+
if (doit)
4675+
(*var) = LOGSTMT_NONE;
4676+
}
4677+
else if (strcasecmp(newval, "mod") == 0)
4678+
{
4679+
if (doit)
4680+
(*var) = LOGSTMT_MOD;
4681+
}
4682+
else if (strcasecmp(newval, "ddl") == 0)
4683+
{
4684+
if (doit)
4685+
(*var) = LOGSTMT_DDL;
4686+
}
4687+
else if (strcasecmp(newval, "all") == 0)
4688+
{
4689+
if (doit)
4690+
(*var) = LOGSTMT_ALL;
4691+
}
4692+
else
4693+
return NULL; /* fail */
4694+
return newval; /* OK */
4695+
}
4696+
46554697
static bool
46564698
assign_phony_autocommit(bool newval, bool doit, GucSource source)
46574699
{

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
# %s=session start timestamp
192192
# %x=stop here in non-session processes
193193
# %%='%'
194-
#log_statement = false
194+
#log_statement = 'none' # none, mod, ddl, all
195195
#log_hostname = false
196196

197197

src/include/tcop/tcopprot.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.63 2004/03/24 22:40:29 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.64 2004/04/07 05:05:50 momjian Exp $
1111
*
1212
* OLD COMMENTS
1313
* This file was created so that other c files could get the two
@@ -35,6 +35,19 @@ extern DLLIMPORT const char *debug_query_string;
3535
extern char *rendezvous_name;
3636
extern int max_stack_depth;
3737

38+
/* GUC-configurable parameters */
39+
40+
typedef enum
41+
{
42+
/* Reverse order so GUC USERLIMIT is easier */
43+
LOGSTMT_ALL, /* log all statements */
44+
LOGSTMT_DDL, /* log data definition statements */
45+
LOGSTMT_MOD, /* log modification statements, plus DDL */
46+
LOGSTMT_NONE /* log no statements */
47+
} LogStmtLevel;
48+
49+
extern LogStmtLevel log_statement;
50+
3851
#ifndef BOOTSTRAP_INCLUDE
3952

4053
extern List *pg_parse_and_rewrite(const char *query_string,

src/include/utils/guc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
88
* Written by Peter Eisentraut <peter_e@gmx.net>.
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.44 2004/01/19 19:04:40 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.45 2004/04/07 05:05:50 momjian Exp $
1111
*--------------------------------------------------------------------
1212
*/
1313
#ifndef GUC_H
@@ -103,7 +103,6 @@ typedef enum
103103
} GucSource;
104104

105105
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
106-
extern bool log_statement;
107106
extern bool log_duration;
108107
extern bool Debug_print_plan;
109108
extern bool Debug_print_parse;

0 commit comments

Comments
 (0)