TG_table_name and TG_table_schema for plpgsql, plus docs and regression.

This commit is contained in:
Andrew Dunstan 2006-05-28 03:03:17 +00:00
parent 3d58a1c168
commit 3a9ae3d206
6 changed files with 229 additions and 5 deletions

View 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>

View 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),

View 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;

View 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;

View 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;

View 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;