Here's a patch for tg_table_name and tg_table_schema for plpgsql, which
I would appreciate a quick review of just to make sure I haven't missed
something or done something silly. This will complete this exercise - I
have already committed analogous changes for plperl, plpython and pltcl.
cheers
andrew
Index: doc/src/sgml/plpgsql.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v
retrieving revision 1.88
diff -c -r1.88 plpgsql.sgml
*** doc/src/sgml/plpgsql.sgml 10 Mar 2006 19:10:48 -0000 1.88
--- doc/src/sgml/plpgsql.sgml 27 May 2006 22:19:28 -0000
***************
*** 2745,2751 ****
<listitem>
<para>
Data type <type>name</type>; the name of the table that caused the trigger
! invocation.
</para>
</listitem>
</varlistentry>
--- 2745,2772 ----
<listitem>
<para>
Data type <type>name</type>; the name of the table that caused the trigger
! invocation. This is now deprecated, and could disappear in a future
! release. Use <literal>TG_TABLE_NAME</> instead.
! </para>
! </listitem>
! </varlistentry>
!
! <varlistentry>
! <term><varname>TG_TABLE_NAME</varname></term>
! <listitem>
! <para>
! Data type <type>name</type>; the name of the table that
! caused the trigger invocation.
! </para>
! </listitem>
! </varlistentry>
!
! <varlistentry>
! <term><varname>TG_TABLE_SCHEMA</varname></term>
! <listitem>
! <para>
! Data type <type>name</type>; the name of the schema of the
! table that caused the trigger invocation.
</para>
</listitem>
</varlistentry>
Index: src/pl/plpgsql/src/pl_comp.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.101
diff -c -r1.101 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c 14 Mar 2006 22:48:23 -0000 1.101
--- src/pl/plpgsql/src/pl_comp.c 27 May 2006 22:19:32 -0000
***************
*** 581,586 ****
--- 581,600 ----
true);
function->tg_relname_varno = var->dno;
+ /* tg_table_name is now preferred to tg_relname */
+ var = plpgsql_build_variable("tg_table_name", 0,
+ plpgsql_build_datatype(NAMEOID, -1),
+ true);
+ function->tg_table_name_varno = var->dno;
+
+
+ /* add variable tg_table_schema */
+ var = plpgsql_build_variable("tg_table_schema", 0,
+ plpgsql_build_datatype(NAMEOID, -1),
+ true);
+ function->tg_table_schema_varno = var->dno;
+
+
/* Add the variable tg_nargs */
var = plpgsql_build_variable("tg_nargs", 0,
plpgsql_build_datatype(INT4OID, -1),
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.164
diff -c -r1.164 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c 22 Apr 2006 01:26:01 -0000 1.164
--- src/pl/plpgsql/src/pl_exec.c 27 May 2006 22:19:34 -0000
***************
*** 539,544 ****
--- 539,559 ----
var->isnull = false;
var->freeval = true;
+ var = (PLpgSQL_var *) (estate.datums[func->tg_table_name_varno]);
+ var->value = DirectFunctionCall1(namein,
+ CStringGetDatum(RelationGetRelationName(trigdata->tg_relation)));
+ var->isnull = false;
+ var->freeval = true;
+
+ var = (PLpgSQL_var *) (estate.datums[func->tg_table_schema_varno]);
+ var->value = DirectFunctionCall1(namein,
+ CStringGetDatum(
+ get_namespace_name(
+ RelationGetNamespace(
+ trigdata->tg_relation))));
+ var->isnull = false;
+ var->freeval = true;
+
var = (PLpgSQL_var *) (estate.datums[func->tg_nargs_varno]);
var->value = Int16GetDatum(trigdata->tg_trigger->tgnargs);
var->isnull = false;
Index: src/pl/plpgsql/src/plpgsql.h
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v
retrieving revision 1.69
diff -c -r1.69 plpgsql.h
*** src/pl/plpgsql/src/plpgsql.h 9 Mar 2006 21:29:38 -0000 1.69
--- src/pl/plpgsql/src/plpgsql.h 27 May 2006 22:19:35 -0000
***************
*** 572,577 ****
--- 572,579 ----
int tg_op_varno;
int tg_relid_varno;
int tg_relname_varno;
+ int tg_table_name_varno;
+ int tg_table_schema_varno;
int tg_nargs_varno;
int ndatums;
Index: src/test/regress/expected/triggers.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/triggers.out,v
retrieving revision 1.20
diff -c -r1.20 triggers.out
*** src/test/regress/expected/triggers.out 27 Feb 2006 16:09:50 -0000 1.20
--- src/test/regress/expected/triggers.out 27 May 2006 22:19:36 -0000
***************
*** 386,388 ****
--- 386,485 ----
drop table trigtest2;
drop table trigtest;
+ -- dump trigger data
+ CREATE TABLE trigger_test (
+ i int,
+ v varchar
+ );
+ CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger
+ LANGUAGE plpgsql AS $$
+
+ declare
+
+ argstr text;
+
+ begin
+
+ -- plpgsql can't discover it's trigger data in a hash like perl and python
+ -- can, or by a sort of reflection like tcl can,
+ -- so we have to hard code the names.
+ raise NOTICE 'TG_NAME: %', TG_name;
+ raise NOTICE 'TG_WHEN: %', TG_when;
+ raise NOTICE 'TG_LEVEL: %', TG_level;
+ raise NOTICE 'TG_OP: %', TG_op;
+ raise NOTICE 'TG_RELID: %', 'bogus:12345';
+ raise NOTICE 'TG_RELNAME: %', TG_relname;
+ raise NOTICE 'TG_TABLE_NAME: %', TG_table_name;
+ raise NOTICE 'TG_TABLE_SCHEMA: %', TG_table_schema;
+ raise NOTICE 'TG_NARGS: %', TG_nargs;
+
+ argstr := '[';
+ for i in 0 .. TG_nargs - 1 loop
+ if i > 0 then
+ argstr := argstr || ', ';
+ end if;
+ argstr := argstr || TG_argv[i];
+ end loop;
+ argstr := argstr || ']';
+ raise NOTICE 'TG_ARGV: %', argstr;
+
+ if TG_OP != 'INSERT' then
+ raise NOTICE 'OLD: %', OLD;
+ end if;
+
+ if TG_OP != 'DELETE' then
+ raise NOTICE 'NEW: %', NEW;
+ end if;
+ if TG_OP = 'DELETE' then
+ return OLD;
+ else
+ return NEW;
+ end if;
+
+ end;
+ $$;
+ CREATE TRIGGER show_trigger_data_trig
+ BEFORE INSERT OR UPDATE OR DELETE ON trigger_test
+ FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
+ insert into trigger_test values(1,'insert');
+ NOTICE: TG_NAME: show_trigger_data_trig
+ NOTICE: TG_WHEN: BEFORE
+ NOTICE: TG_LEVEL: ROW
+ NOTICE: TG_OP: INSERT
+ NOTICE: TG_RELID: bogus:12345
+ NOTICE: TG_RELNAME: trigger_test
+ NOTICE: TG_TABLE_NAME: trigger_test
+ NOTICE: TG_TABLE_SCHEMA: public
+ NOTICE: TG_NARGS: 2
+ NOTICE: TG_ARGV: [23, skidoo]
+ NOTICE: NEW: (1,insert)
+ update trigger_test set v = 'update' where i = 1;
+ NOTICE: TG_NAME: show_trigger_data_trig
+ NOTICE: TG_WHEN: BEFORE
+ NOTICE: TG_LEVEL: ROW
+ NOTICE: TG_OP: UPDATE
+ NOTICE: TG_RELID: bogus:12345
+ NOTICE: TG_RELNAME: trigger_test
+ NOTICE: TG_TABLE_NAME: trigger_test
+ NOTICE: TG_TABLE_SCHEMA: public
+ NOTICE: TG_NARGS: 2
+ NOTICE: TG_ARGV: [23, skidoo]
+ NOTICE: OLD: (1,insert)
+ NOTICE: NEW: (1,update)
+ delete from trigger_test;
+ NOTICE: TG_NAME: show_trigger_data_trig
+ NOTICE: TG_WHEN: BEFORE
+ NOTICE: TG_LEVEL: ROW
+ NOTICE: TG_OP: DELETE
+ NOTICE: TG_RELID: bogus:12345
+ NOTICE: TG_RELNAME: trigger_test
+ NOTICE: TG_TABLE_NAME: trigger_test
+ NOTICE: TG_TABLE_SCHEMA: public
+ NOTICE: TG_NARGS: 2
+ NOTICE: TG_ARGV: [23, skidoo]
+ NOTICE: OLD: (1,update)
+
+ DROP TRIGGER show_trigger_data_trig on trigger_test;
+
+ DROP FUNCTION trigger_data();
+ DROP TABLE trigger_test;
Index: src/test/regress/sql/triggers.sql
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/sql/triggers.sql,v
retrieving revision 1.10
diff -c -r1.10 triggers.sql
*** src/test/regress/sql/triggers.sql 27 Feb 2006 16:09:50 -0000 1.10
--- src/test/regress/sql/triggers.sql 27 May 2006 22:19:36 -0000
***************
*** 294,296 ****
--- 294,365 ----
select * from trigtest;
drop table trigtest2;
drop table trigtest;
+
+
+ -- dump trigger data
+ CREATE TABLE trigger_test (
+ i int,
+ v varchar
+ );
+
+ CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger
+ LANGUAGE plpgsql AS $$
+
+ declare
+
+ argstr text;
+
+ begin
+
+ -- plpgsql can't discover it's trigger data in a hash like perl and python
+ -- can, or by a sort of reflection like tcl can,
+ -- so we have to hard code the names.
+ raise NOTICE 'TG_NAME: %', TG_name;
+ raise NOTICE 'TG_WHEN: %', TG_when;
+ raise NOTICE 'TG_LEVEL: %', TG_level;
+ raise NOTICE 'TG_OP: %', TG_op;
+ raise NOTICE 'TG_RELID: %', 'bogus:12345';
+ raise NOTICE 'TG_RELNAME: %', TG_relname;
+ raise NOTICE 'TG_TABLE_NAME: %', TG_table_name;
+ raise NOTICE 'TG_TABLE_SCHEMA: %', TG_table_schema;
+ raise NOTICE 'TG_NARGS: %', TG_nargs;
+
+ argstr := '[';
+ for i in 0 .. TG_nargs - 1 loop
+ if i > 0 then
+ argstr := argstr || ', ';
+ end if;
+ argstr := argstr || TG_argv[i];
+ end loop;
+ argstr := argstr || ']';
+ raise NOTICE 'TG_ARGV: %', argstr;
+
+ if TG_OP != 'INSERT' then
+ raise NOTICE 'OLD: %', OLD;
+ end if;
+
+ if TG_OP != 'DELETE' then
+ raise NOTICE 'NEW: %', NEW;
+ end if;
+ if TG_OP = 'DELETE' then
+ return OLD;
+ else
+ return NEW;
+ end if;
+
+ end;
+ $$;
+
+ CREATE TRIGGER show_trigger_data_trig
+ BEFORE INSERT OR UPDATE OR DELETE ON trigger_test
+ FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
+
+ insert into trigger_test values(1,'insert');
+ update trigger_test set v = 'update' where i = 1;
+ delete from trigger_test;
+
+ DROP TRIGGER show_trigger_data_trig on trigger_test;
+
+ DROP FUNCTION trigger_data();
+
+ DROP TABLE trigger_test;