OSDN Git Service

TG_table_name and TG_table_schema for plpgsql, plus docs and regression.
authorAndrew Dunstan <andrew@dunslane.net>
Sun, 28 May 2006 03:03:17 +0000 (03:03 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Sun, 28 May 2006 03:03:17 +0000 (03:03 +0000)
doc/src/sgml/plpgsql.sgml
src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/plpgsql.h
src/test/regress/expected/triggers.out
src/test/regress/sql/triggers.sql

index 2d1351d..4f302a8 100644 (file)
@@ -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>
index 93814db..673ae54 100644 (file)
@@ -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),
index ee30902..d2ff1ff 100644 (file)
@@ -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;
index 43b9122..50fe382 100644 (file)
@@ -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;
index e91c5a3..6d8a436 100644 (file)
@@ -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;
index 140b0f2..fc688a0 100644 (file)
@@ -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;