aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/plpgsql.sgml25
-rw-r--r--src/pl/plpgsql/src/pl_comp.c16
-rw-r--r--src/pl/plpgsql/src/pl_exec.c17
-rw-r--r--src/pl/plpgsql/src/plpgsql.h4
-rw-r--r--src/test/regress/expected/triggers.out100
-rw-r--r--src/test/regress/sql/triggers.sql72
6 files changed, 229 insertions, 5 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index 2d1351d9c7e..4f302a858e7 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.88 2006/03/10 19:10:48 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.89 2006/05/28 03:03:17 adunstan Exp $ -->
<chapter id="plpgsql">
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
@@ -2745,7 +2745,28 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id;
<listitem>
<para>
Data type <type>name</type>; the name of the table that caused the trigger
- invocation.
+ 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>
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 93814db1665..673ae54ca64 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.101 2006/03/14 22:48:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.102 2006/05/28 03:03:17 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@@ -581,6 +581,20 @@ do_compile(FunctionCallInfo fcinfo,
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),
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index ee30902dedb..d2ff1fffd52 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.164 2006/04/22 01:26:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.165 2006/05/28 03:03:17 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@@ -539,6 +539,21 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
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;
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 43b912287b9..50fe382b323 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.69 2006/03/09 21:29:38 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.70 2006/05/28 03:03:17 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@@ -572,6 +572,8 @@ typedef struct PLpgSQL_function
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;
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index e91c5a36320..6d8a436f500 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -386,3 +386,103 @@ 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;
+ relid text;
+
+begin
+
+ relid := TG_relid::regclass;
+
+ -- 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::regclass: %', relid;
+ 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::regclass: trigger_test
+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::regclass: trigger_test
+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::regclass: trigger_test
+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;
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 140b0f2d485..fc688a08f9c 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -294,3 +294,75 @@ insert into trigtest default values;
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;
+ relid text;
+
+begin
+
+ relid := TG_relid::regclass;
+
+ -- 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::regclass: %', relid;
+ 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;