Hi here is initial version of reduced patch. It is small code, but relative big (although I expected bigger) change in tests.
if these changes are too big, then we have to introduce a plpgsql GUC plpgsql.client_min_context and plpgsql.log_min_client. These GUC overwrite global setting for plpgsql functions. I'll be more happy without these variables. It decrease a impact of changes, but there is not clean what behave is expected when PL are used together - and when fails PLpgSQL function called from PLPerl. The context filtering should be really solved on TOP level. Regards Pavel 2015-07-08 14:09 GMT+02:00 Merlin Moncure <mmonc...@gmail.com>: > On Wed, Jul 8, 2015 at 1:35 AM, Pavel Stehule <pavel.steh...@gmail.com> > wrote: > > > > > > 2015-07-07 18:15 GMT+02:00 Merlin Moncure <mmonc...@gmail.com>: > >> > >> On Tue, Jul 7, 2015 at 9:04 AM, Pavel Stehule <pavel.steh...@gmail.com> > >> wrote: > >> >> It doesn't have to if the behavior is guarded with a GUC. I just > >> >> don't understand what all the fuss is about. The default behavior of > >> >> logging that is well established by other languages (for example > java) > >> >> that manage error stack for you should be to: > >> >> > >> >> *) Give stack trace when an uncaught exception is thrown > >> >> *) Do not give stack trace in all other logging cases unless asked > for > >> > > >> > what is RAISE EXCEPTION - first or second case? > >> > >> First: RAISE (unless caught) is no different than any other kind of > error. > >> > >> On Tue, Jul 7, 2015 at 9:42 AM, Heikki Linnakangas <hlinn...@iki.fi> > >> wrote: > >> > On 07/07/2015 04:56 PM, Merlin Moncure wrote: > >> >> It doesn't have to if the behavior is guarded with a GUC. I just > >> >> don't understand what all the fuss is about. The default behavior of > >> >> logging that is well established by other languages (for example > java) > >> >> that manage error stack for you should be to: > >> >> > >> >> *) Give stack trace when an uncaught exception is thrown > >> >> *) Do not give stack trace in all other logging cases unless asked > for > >> > > >> > Java's exception handling is so different from PostgreSQL's errors > that > >> > I > >> > don't think there's much to be learned from that. But I'll bite: > >> > > >> > First of all, Java's exceptions always contain a stack trace. It's up > to > >> > you > >> > when you catch an exception to decide whether to print it or not. > "try { > >> > ... > >> > } catch (Exception e) { e.printStackTrace() }" is fairly common, > >> > actually. > >> > There is nothing like a NOTICE in Java, i.e. an exception that's > thrown > >> > but > >> > doesn't affect the control flow. The best I can think of is > >> > System.out.println(), which of course has no stack trace attached to > it. > >> > >> exactly. > >> > >> > Perhaps you're arguing that NOTICE is more like printing to stderr, > and > >> > should never contain any context information. I don't think that would > >> > be an > >> > improvement. It's very handy to have the context information available > >> > if > >> > don't know where a NOTICE is coming from, even if in most cases you're > >> > not > >> > interested in it. > >> > >> That's exactly what I'm arguing. NOTICE (and WARNING) are for > >> printing out information to client side logging; it's really the only > >> tool we have for that purpose and it fits that role perfectly. Of > >> course, you may want to have NOTICE print context, especially when > >> debugging, but some control over that would be nice and in most cases > >> it's really not necessary. I really don't understand the objection to > >> offering control over that behavior although I certainly understand > >> wanting to keep the default behavior as it currently is. > >> > >> > This is really quite different from a programming language's exception > >> > handling. First, there's a server, which produces the errors, and a > >> > separate > >> > client, which displays them. You cannot catch an exception in the > >> > client. > >> > > >> > BTW, let me throw in one use case to consider. We've been talking > about > >> > psql, and what to print, but imagine a more sophisticated client like > >> > pgAdmin. It's not limited to either printing the context or not. It > >> > could > >> > e.g. hide the context information of all messages when they occur, but > >> > if > >> > you double-click on it, it's expanded to show all the context, > location > >> > and > >> > all. You can't do that if the server doesn't send the context > >> > information in > >> > the first place. > >> > > >> >> I would be happy to show you the psql redirected output logs from my > >> >> nightly server processes that spew into the megabytes because of > >> >> logging various high level steps (did this, did that). > >> > > >> > Oh, I believe you. I understand what the problem is, we're only > talking > >> > about how best to address it. > >> > >> Yeah. For posterity, a psql based solution would work fine for me, > >> but a server side solution has a lot of advantages (less protocol > >> chatter, more configurability, keeping libpq/psql light). > > > > > > After some work on reduced version of "plpgsql.min_context" patch I am > > inclining to think so ideal solution needs more steps - because this > issue > > has more than one dimension. > > > > There are two independent issues: > > > > 1. old plpgsql workaround that reduced the unwanted call stack info for > > RAISE NOTICE. Negative side effect of this workaround is missing context > > info about the RAISE command that raises the exception. We know a > function, > > but we don't know a line of related RAISE statement. The important is > fact, > > so NOTICE doesn't bubble to up. So this workaround was relative > successful > > without to implement some filtering on client or log side. > > > > 2. second issue is general suppressing context info for interactive > client > > or for log. > > > > These issues should be solved separately, because solution for @2 doesn't > > fix @1, and @1 is too local for @2. > > > > So what we can do? > > > > 1. remove current plpgsql workaround - and implement client_min_context > and > > log_min_context > > 2. implement plpgsql.min_context, and client_min_context and > log_min_context > > > > @1 is consistent, but isn't possible to configure same behave as was > before > > > > @2 is difficult in definition what plpgsql.min_context should to really > do > > - and what is relation to client_min_context and log_min_context, but I > can > > prepare configuration, that is fully compatible. > > > > Comments, any other ideas? > > > > Personally, I prefer @1 as general solution, that will work for all PL > > +1 > > merlin >
commit e3053e47ab7a9735aeda24995501c7b74042e7c6 Author: Pavel Stehule <pavel.steh...@gooddata.com> Date: Wed Jul 8 22:12:30 2015 +0200 initial diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 088c714..9445230 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -2730,7 +2730,7 @@ write_csvlog(ErrorData *edata) appendStringInfoChar(&buf, ','); /* errcontext */ - if (!edata->hide_ctx) + if (!edata->hide_ctx && edata->elevel >= log_min_context) appendCSVLiteral(&buf, edata->context); appendStringInfoChar(&buf, ','); @@ -2863,7 +2863,7 @@ send_message_to_server_log(ErrorData *edata) append_with_tabs(&buf, edata->internalquery); appendStringInfoChar(&buf, '\n'); } - if (edata->context && !edata->hide_ctx) + if (edata->context && !edata->hide_ctx && edata->elevel >= log_min_context) { log_line_prefix(&buf, edata); appendStringInfoString(&buf, _("CONTEXT: ")); @@ -3137,7 +3137,7 @@ send_message_to_frontend(ErrorData *edata) err_sendstring(&msgbuf, edata->hint); } - if (edata->context) + if (edata->context && edata->elevel >= client_min_context) { pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT); err_sendstring(&msgbuf, edata->context); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 595a609..ca63bf5 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -430,6 +430,8 @@ bool Password_encryption = true; int log_min_error_statement = ERROR; int log_min_messages = WARNING; int client_min_messages = NOTICE; +int log_min_context = ERROR; +int client_min_context = ERROR; int log_min_duration_statement = -1; int log_temp_files = -1; int trace_recovery_messages = LOG; @@ -3426,6 +3428,17 @@ static struct config_enum ConfigureNamesEnum[] = }, { + {"client_min_context", PGC_USERSET, LOGGING_WHEN, + gettext_noop("Sets the message levels when the context is send to the client."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the less content are sent.") + }, + &client_min_context, + ERROR, client_message_level_options, + NULL, NULL, NULL + }, + + { {"client_min_messages", PGC_USERSET, LOGGING_WHEN, gettext_noop("Sets the message levels that are sent to the client."), gettext_noop("Each level includes all the levels that follow it. The later" @@ -3479,6 +3492,17 @@ static struct config_enum ConfigureNamesEnum[] = }, { + {"log_min_context", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the message levels that has context logged."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the less content are sent.") + }, + &log_min_context, + WARNING, server_message_level_options, + NULL, NULL, NULL + }, + + { {"log_min_messages", PGC_SUSET, LOGGING_WHEN, gettext_noop("Sets the message levels that are logged."), gettext_noop("Each level includes all the levels that follow it. The later" diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 06dfc06..8695e8b 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -360,6 +360,31 @@ # - When to Log - +#client_min_context = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error + +#log_min_context = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + #client_min_messages = notice # values in order of decreasing detail: # debug5 # debug4 diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index dc167f9..f03a5e1 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -246,6 +246,8 @@ extern PGDLLIMPORT bool check_function_bodies; extern bool default_with_oids; extern bool SQL_inheritance; +extern int log_min_context; +extern int client_min_context; extern int log_min_error_statement; extern int log_min_messages; extern int client_min_messages; diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 7d4001c..e1a6b7d 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -42,8 +42,6 @@ #include "utils/typcache.h" -static const char *const raise_skip_msg = "RAISE"; - typedef struct { int nargs; /* number of arguments */ @@ -939,10 +937,6 @@ plpgsql_exec_error_callback(void *arg) { PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg; - /* if we are doing RAISE, don't report its location */ - if (estate->err_text == raise_skip_msg) - return; - if (estate->err_text != NULL) { /* @@ -3158,8 +3152,6 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt) /* * Throw the error (may or may not come back) */ - estate->err_text = raise_skip_msg; /* suppress traceback of raise */ - ereport(stmt->elog_level, (err_code ? errcode(err_code) : 0, errmsg_internal("%s", err_message), diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out index 5e31737..72ada21 100644 --- a/src/test/regress/expected/copy2.out +++ b/src/test/regress/expected/copy2.out @@ -447,12 +447,9 @@ Check constraints: copy check_con_tbl from stdin; NOTICE: input = {"f1":1} -CONTEXT: COPY check_con_tbl, line 1: "1" NOTICE: input = {"f1":null} -CONTEXT: COPY check_con_tbl, line 2: "\N" copy check_con_tbl from stdin; NOTICE: input = {"f1":0} -CONTEXT: COPY check_con_tbl, line 1: "0" ERROR: new row for relation "check_con_tbl" violates check constraint "check_con_tbl_check" DETAIL: Failing row contains (0). CONTEXT: COPY check_con_tbl, line 1: "0" diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out index e70c315..05ac0ad 100644 --- a/src/test/regress/expected/event_trigger.out +++ b/src/test/regress/expected/event_trigger.out @@ -234,15 +234,10 @@ drop cascades to table schema_one.table_one drop cascades to table schema_one."table two" drop cascades to table schema_one.table_three NOTICE: table "schema_two_table_two" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_two" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "audit_tbls_schema_two_table_three" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.audit_tbls_schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement -SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement ERROR: object audit_tbls.schema_two_table_three of type table cannot be dropped -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three" +CONTEXT: PL/pgSQL function undroppable() line 14 at RAISE +SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three" PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three'; DROP SCHEMA schema_one, schema_two CASCADE; @@ -255,23 +250,12 @@ drop cascades to table schema_one.table_one drop cascades to table schema_one."table two" drop cascades to table schema_one.table_three NOTICE: table "schema_two_table_two" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_two" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "audit_tbls_schema_two_table_three" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.audit_tbls_schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement -SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table_one" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_one_table_one" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table two" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls."schema_one_table two"" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table_three" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_one_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement ERROR: object schema_one.table_three of type table cannot be dropped +CONTEXT: PL/pgSQL function undroppable() line 14 at RAISE DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three'; DROP SCHEMA schema_one, schema_two CASCADE; NOTICE: drop cascades to 7 other objects @@ -283,22 +267,10 @@ drop cascades to table schema_one.table_one drop cascades to table schema_one."table two" drop cascades to table schema_one.table_three NOTICE: table "schema_two_table_two" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_two" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "audit_tbls_schema_two_table_three" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.audit_tbls_schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement -SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table_one" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_one_table_one" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table two" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls."schema_one_table two"" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement NOTICE: table "schema_one_table_three" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_one_table_three" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement SELECT * FROM dropped_objects WHERE schema IS NULL OR schema <> 'pg_toast'; type | schema | object --------------+------------+------------------------------------- @@ -329,8 +301,6 @@ SELECT * FROM dropped_objects WHERE schema IS NULL OR schema <> 'pg_toast'; DROP OWNED BY regression_bob; NOTICE: schema "audit_tbls" does not exist, skipping -CONTEXT: SQL statement "DROP TABLE IF EXISTS audit_tbls.audit_tbls_schema_one_table_two" -PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE statement SELECT * FROM dropped_objects WHERE type = 'schema'; type | schema | object --------+--------+------------ @@ -402,8 +372,10 @@ insert into rewriteme select x * 1.001 from generate_series(1, 500) as t(x); alter table rewriteme alter column foo type numeric; ERROR: I'm sorry Sir, No Rewrite Allowed. +CONTEXT: PL/pgSQL function test_evtrig_no_rewrite() line 3 at RAISE alter table rewriteme add column baz int default 0; ERROR: I'm sorry Sir, No Rewrite Allowed. +CONTEXT: PL/pgSQL function test_evtrig_no_rewrite() line 3 at RAISE -- test with more than one reason to rewrite a single table CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS $$ diff --git a/src/test/regress/expected/plancache.out b/src/test/regress/expected/plancache.out index 864f70f..3f3db33 100644 --- a/src/test/regress/expected/plancache.out +++ b/src/test/regress/expected/plancache.out @@ -234,8 +234,6 @@ begin end$$ language plpgsql; select cachebug(); NOTICE: table "temptable" does not exist, skipping -CONTEXT: SQL statement "drop table if exists temptable cascade" -PL/pgSQL function cachebug() line 4 at SQL statement NOTICE: 1 NOTICE: 2 NOTICE: 3 @@ -246,8 +244,6 @@ NOTICE: 3 select cachebug(); NOTICE: drop cascades to view vv -CONTEXT: SQL statement "drop table if exists temptable cascade" -PL/pgSQL function cachebug() line 4 at SQL statement NOTICE: 1 NOTICE: 2 NOTICE: 3 diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 7ce5415..a19424d 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -1518,27 +1518,35 @@ ERROR: duplicate key value violates unique constraint "pfield_name" DETAIL: Key (name)=(PF1_1) already exists. update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1'; ERROR: WS.not.there does not exist -CONTEXT: PL/pgSQL function tg_backlink_a() line 17 at assignment +CONTEXT: PL/pgSQL function tg_backlink_set(character,character) line 30 at RAISE +PL/pgSQL function tg_backlink_a() line 17 at assignment update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal backlink beginning with XX -CONTEXT: PL/pgSQL function tg_backlink_a() line 17 at assignment +CONTEXT: PL/pgSQL function tg_backlink_set(character,character) line 47 at RAISE +PL/pgSQL function tg_backlink_a() line 17 at assignment update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1'; ERROR: PS.not.there does not exist -CONTEXT: PL/pgSQL function tg_slotlink_a() line 17 at assignment +CONTEXT: PL/pgSQL function tg_slotlink_set(character,character) line 30 at RAISE +PL/pgSQL function tg_slotlink_a() line 17 at assignment update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1'; ERROR: illegal slotlink beginning with XX -CONTEXT: PL/pgSQL function tg_slotlink_a() line 17 at assignment +CONTEXT: PL/pgSQL function tg_slotlink_set(character,character) line 77 at RAISE +PL/pgSQL function tg_slotlink_a() line 17 at assignment insert into HSlot values ('HS', 'base.hub1', 1, ''); ERROR: duplicate key value violates unique constraint "hslot_name" DETAIL: Key (slotname)=(HS.base.hub1.1 ) already exists. insert into HSlot values ('HS', 'base.hub1', 20, ''); ERROR: no manual manipulation of HSlot +CONTEXT: PL/pgSQL function tg_hslot_biu() line 12 at RAISE delete from HSlot; ERROR: no manual manipulation of HSlot +CONTEXT: PL/pgSQL function tg_hslot_bd() line 12 at RAISE insert into IFace values ('IF', 'notthere', 'eth0', ''); ERROR: system "notthere" does not exist +CONTEXT: PL/pgSQL function tg_iface_biu() line 8 at RAISE insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', ''); ERROR: IFace slotname "IF.orion.ethernet_interface_name_too_long" too long (20 char max) +CONTEXT: PL/pgSQL function tg_iface_biu() line 14 at RAISE -- -- The following tests are unrelated to the scenario outlined above; -- they merely exercise specific parts of PL/pgSQL @@ -1963,6 +1971,7 @@ NOTICE: should see this NOTICE: should see this only if -100 <> 0 NOTICE: should see this only if -100 fits in smallint ERROR: -100 is less than zero +CONTEXT: PL/pgSQL function trap_zero_divide(integer) line 12 at RAISE create function trap_matching_test(int) returns int as $$ declare x int; sx smallint; @@ -2066,14 +2075,8 @@ begin end$$ language plpgsql; select test_variable_storage(); NOTICE: should see this -CONTEXT: SQL statement "SELECT trap_zero_divide(-100)" -PL/pgSQL function test_variable_storage() line 8 at PERFORM NOTICE: should see this only if -100 <> 0 -CONTEXT: SQL statement "SELECT trap_zero_divide(-100)" -PL/pgSQL function test_variable_storage() line 8 at PERFORM NOTICE: should see this only if -100 fits in smallint -CONTEXT: SQL statement "SELECT trap_zero_divide(-100)" -PL/pgSQL function test_variable_storage() line 8 at PERFORM test_variable_storage ----------------------- 123456789012 @@ -4052,6 +4055,7 @@ DETAIL: some detail info HINT: some hint ERROR: 1 2 3 DETAIL: some detail info +CONTEXT: PL/pgSQL function raise_test() line 5 at RAISE -- Since we can't actually see the thrown SQLSTATE in default psql output, -- test it like this; this also tests re-RAISE create or replace function raise_test() returns void as $$ @@ -4068,6 +4072,7 @@ select raise_test(); NOTICE: SQLSTATE: 22012 SQLERRM: check me ERROR: check me DETAIL: some detail info +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise 'check me' @@ -4082,6 +4087,7 @@ select raise_test(); NOTICE: SQLSTATE: 1234F SQLERRM: check me ERROR: check me DETAIL: some detail info +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE -- SQLSTATE specification in WHEN create or replace function raise_test() returns void as $$ begin @@ -4097,6 +4103,7 @@ select raise_test(); NOTICE: SQLSTATE: 1234F SQLERRM: check me ERROR: check me DETAIL: some detail info +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero using detail = 'some detail info'; @@ -4110,6 +4117,7 @@ select raise_test(); NOTICE: SQLSTATE: 22012 SQLERRM: division_by_zero ERROR: division_by_zero DETAIL: some detail info +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero; @@ -4117,6 +4125,7 @@ end; $$ language plpgsql; select raise_test(); ERROR: division_by_zero +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise sqlstate '1234F'; @@ -4124,6 +4133,7 @@ end; $$ language plpgsql; select raise_test(); ERROR: 1234F +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise division_by_zero using message = 'custom' || ' message'; @@ -4131,6 +4141,7 @@ end; $$ language plpgsql; select raise_test(); ERROR: custom message +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE create or replace function raise_test() returns void as $$ begin raise using message = 'custom' || ' message', errcode = '22012'; @@ -4138,6 +4149,7 @@ end; $$ language plpgsql; select raise_test(); ERROR: custom message +CONTEXT: PL/pgSQL function raise_test() line 3 at RAISE -- conflict on message create or replace function raise_test() returns void as $$ begin @@ -4254,6 +4266,7 @@ $$ language plpgsql; select raise_test(); NOTICE: 22012 ERROR: substitute message +CONTEXT: PL/pgSQL function raise_test() line 7 at RAISE drop function raise_test(); -- test passing column_name, constraint_name, datatype_name, table_name -- and schema_name error fields @@ -4744,7 +4757,6 @@ LINE 1: SELECT 'foo\\bar\041baz' ^ HINT: Use the escape string syntax for backslashes, e.g., E'\\'. QUERY: SELECT 'foo\\bar\041baz' -CONTEXT: PL/pgSQL function strtest() line 4 at RETURN strtest ------------- foo\bar!baz @@ -5260,22 +5272,14 @@ $$ language plpgsql; select outer_outer_func(10); NOTICE: calling down into outer_func() NOTICE: calling down into inner_func() -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: lets make sure we didnt break anything -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: inner_func() done -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: outer_func() done outer_outer_func ------------------ @@ -5286,22 +5290,14 @@ NOTICE: outer_func() done select outer_outer_func(20); NOTICE: calling down into outer_func() NOTICE: calling down into inner_func() -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: lets make sure we didnt break anything -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: inner_func() done -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: outer_func() done outer_outer_func ------------------ @@ -5358,22 +5354,14 @@ $$ language plpgsql; select outer_outer_func(10); NOTICE: calling down into outer_func() NOTICE: calling down into inner_func() -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 10 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 15 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: lets make sure we didnt break anything -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: inner_func() done -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: outer_func() done outer_outer_func ------------------ @@ -5384,22 +5372,14 @@ NOTICE: outer_func() done select outer_outer_func(20); NOTICE: calling down into outer_func() NOTICE: calling down into inner_func() -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 10 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: ***PL/pgSQL function inner_func(integer) line 15 at GET DIAGNOSTICS PL/pgSQL function outer_func(integer) line 6 at assignment PL/pgSQL function outer_outer_func(integer) line 6 at assignment*** -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: lets make sure we didnt break anything -CONTEXT: PL/pgSQL function outer_func(integer) line 6 at assignment -PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: inner_func() done -CONTEXT: PL/pgSQL function outer_outer_func(integer) line 6 at assignment NOTICE: outer_func() done outer_outer_func ------------------ diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index c0cd9fa..88bdc2c 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -1023,7 +1023,6 @@ GRANT regressgroup2 TO regressuser5; -- fails: no ADMIN OPTION ERROR: must have admin option on role "regressgroup2" SELECT dogrant_ok(); -- ok: SECURITY DEFINER conveys ADMIN NOTICE: role "regressuser5" is already a member of role "regressgroup2" -CONTEXT: SQL function "dogrant_ok" statement 1 dogrant_ok ------------ diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out index 6dabe50..00ef421 100644 --- a/src/test/regress/expected/rangefuncs.out +++ b/src/test/regress/expected/rangefuncs.out @@ -1704,9 +1704,7 @@ create trigger tnoticetrigger after insert on tt for each row execute procedure noticetrigger(); select insert_tt2('foolme','barme') limit 1; NOTICE: noticetrigger 11 foolme -CONTEXT: SQL function "insert_tt2" statement 1 NOTICE: noticetrigger 12 barme -CONTEXT: SQL function "insert_tt2" statement 1 insert_tt2 ------------ 11 @@ -1735,9 +1733,7 @@ create rule insert_tt_rule as on insert to tt do also insert into tt_log values(new.*); select insert_tt2('foollog','barlog') limit 1; NOTICE: noticetrigger 13 foollog -CONTEXT: SQL function "insert_tt2" statement 1 NOTICE: noticetrigger 14 barlog -CONTEXT: SQL function "insert_tt2" statement 1 insert_tt2 ------------ 13 diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index 3b32e8f..cd43e46 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -958,11 +958,7 @@ NOTICE: main_view BEFORE INSERT STATEMENT (before_view_ins_stmt) NOTICE: main_view INSTEAD OF INSERT ROW (instead_of_ins) NOTICE: NEW: (20,30) NOTICE: trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)" -PL/pgSQL function view_trigger() line 17 at SQL statement NOTICE: trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)" -PL/pgSQL function view_trigger() line 17 at SQL statement NOTICE: main_view AFTER INSERT STATEMENT (after_view_ins_stmt) INSERT 0 1 INSERT INTO main_view VALUES (21, 31) RETURNING a, b; @@ -970,11 +966,7 @@ NOTICE: main_view BEFORE INSERT STATEMENT (before_view_ins_stmt) NOTICE: main_view INSTEAD OF INSERT ROW (instead_of_ins) NOTICE: NEW: (21,31) NOTICE: trigger_func(before_ins_stmt) called: action = INSERT, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)" -PL/pgSQL function view_trigger() line 17 at SQL statement NOTICE: trigger_func(after_ins_stmt) called: action = INSERT, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "INSERT INTO main_table VALUES (NEW.a, NEW.b)" -PL/pgSQL function view_trigger() line 17 at SQL statement NOTICE: main_view AFTER INSERT STATEMENT (after_view_ins_stmt) a | b ----+---- @@ -988,17 +980,9 @@ NOTICE: main_view BEFORE UPDATE STATEMENT (before_view_upd_stmt) NOTICE: main_view INSTEAD OF UPDATE ROW (instead_of_upd) NOTICE: OLD: (20,30), NEW: (20,31) NOTICE: trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: main_view AFTER UPDATE STATEMENT (after_view_upd_stmt) UPDATE 0 UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b; @@ -1006,17 +990,9 @@ NOTICE: main_view BEFORE UPDATE STATEMENT (before_view_upd_stmt) NOTICE: main_view INSTEAD OF UPDATE ROW (instead_of_upd) NOTICE: OLD: (21,31), NEW: (21,32) NOTICE: trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(before_upd_a_row) called: action = UPDATE, when = BEFORE, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: main_view AFTER UPDATE STATEMENT (after_view_upd_stmt) a | b ---+--- @@ -1031,20 +1007,10 @@ NOTICE: main_view BEFORE UPDATE STATEMENT (before_view_upd_stmt) NOTICE: main_view INSTEAD OF UPDATE ROW (instead_of_upd) NOTICE: OLD: (20,30), NEW: (20,31) NOTICE: trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: main_view AFTER UPDATE STATEMENT (after_view_upd_stmt) UPDATE 1 UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b; @@ -1052,20 +1018,10 @@ NOTICE: main_view BEFORE UPDATE STATEMENT (before_view_upd_stmt) NOTICE: main_view INSTEAD OF UPDATE ROW (instead_of_upd) NOTICE: OLD: (21,31), NEW: (21,32) NOTICE: trigger_func(before_upd_a_stmt) called: action = UPDATE, when = BEFORE, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_a_b_row) called: action = UPDATE, when = AFTER, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_row) called: action = UPDATE, when = AFTER, level = ROW -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_b_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: trigger_func(after_upd_stmt) called: action = UPDATE, when = AFTER, level = STATEMENT -CONTEXT: SQL statement "UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b" -PL/pgSQL function view_trigger() line 23 at SQL statement NOTICE: main_view AFTER UPDATE STATEMENT (after_view_upd_stmt) a | b ----+---- @@ -1277,6 +1233,7 @@ INSERT 0 1 -- UPDATE .. RETURNING UPDATE city_view SET country_name = 'Japon' WHERE city_name = 'Tokyo'; -- error ERROR: No such country: "Japon" +CONTEXT: PL/pgSQL function city_update() line 9 at RAISE UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Takyo'; -- no match UPDATE 0 UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Tokyo' RETURNING *; -- OK @@ -1489,26 +1446,13 @@ select pg_trigger_depth(); insert into depth_a values (1); NOTICE: depth_a_tr: depth = 1 NOTICE: depth_b_tr: depth = 2 -CONTEXT: SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_c_tr: depth = 3 -CONTEXT: SQL statement "insert into depth_c values (1)" -PL/pgSQL function depth_b_tf() line 5 at EXECUTE statement -SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: SQLSTATE = U9999: depth = 2 -CONTEXT: SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_b_tr: depth = 2 -CONTEXT: SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_c_tr: depth = 3 -CONTEXT: SQL statement "insert into depth_c values (1)" -PL/pgSQL function depth_b_tf() line 12 at EXECUTE statement -SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement ERROR: U9999 -CONTEXT: SQL statement "insert into depth_c values (1)" +CONTEXT: PL/pgSQL function depth_c_tf() line 5 at RAISE +SQL statement "insert into depth_c values (1)" PL/pgSQL function depth_b_tf() line 12 at EXECUTE statement SQL statement "insert into depth_b values (new.id)" PL/pgSQL function depth_a_tf() line 4 at SQL statement @@ -1521,21 +1465,9 @@ select pg_trigger_depth(); insert into depth_a values (2); NOTICE: depth_a_tr: depth = 1 NOTICE: depth_b_tr: depth = 2 -CONTEXT: SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_c_tr: depth = 3 -CONTEXT: SQL statement "insert into depth_c values (2)" -PL/pgSQL function depth_b_tf() line 5 at EXECUTE statement -SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_c_tr: depth = 3 -CONTEXT: SQL statement "insert into depth_c values (2)" -PL/pgSQL function depth_b_tf() line 5 at EXECUTE statement -SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_b_tr: depth = 2 -CONTEXT: SQL statement "insert into depth_b values (new.id)" -PL/pgSQL function depth_a_tf() line 4 at SQL statement NOTICE: depth_a_tr: depth = 1 select pg_trigger_depth(); pg_trigger_depth diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 9b2d264..5691e47 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -934,7 +934,6 @@ SELECT xpath('/*', '<relativens xmlns=''relative''/>'); WARNING: line 1: xmlns: URI relative is not absolute <relativens xmlns='relative'/> ^ -CONTEXT: SQL function "xpath" statement 1 xpath -------------------------------------- {"<relativens xmlns=\"relative\"/>"}
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers