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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy