tg_table_name and tg_table_schema for plpgsql - Mailing list pgsql-patches
From | Andrew Dunstan |
---|---|
Subject | tg_table_name and tg_table_schema for plpgsql |
Date | |
Msg-id | 4478D16C.3030501@dunslane.net Whole thread Raw |
Responses |
Re: tg_table_name and tg_table_schema for plpgsql
|
List | pgsql-patches |
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;
pgsql-patches by date: