-
Notifications
You must be signed in to change notification settings - Fork 104
Description
Description:
The trigger_is function fails to correctly identify the function executed by a trigger when that trigger is defined on a temporary table. The test fails with have: NULL, indicating trigger_is could not find the linked function in the catalogs. This happens despite direct catalog queries (pg_trigger, pg_proc) showing the trigger is correctly linked within the database session. has_trigger correctly finds the trigger on the temp table, and trigger_is works correctly for identical triggers on persistent tables.
Environment:
pgTAP Version: 1.2.0
PostgreSQL Version: 15
Operating System: Docker
Steps to Reproduce:
-- Minimal Reproducible Example for trigger_is on temp table issue
BEGIN;
SELECT plan(7);
-- 1. Create a simple trigger function in public schema
CREATE OR REPLACE FUNCTION public.my_temp_trigger_func()
RETURNS TRIGGER AS $$ BEGIN RETURN NEW; END; $$ LANGUAGE plpgsql;
SELECT has_function('public', 'my_temp_trigger_func', ARRAY[]::text[], 'Trigger function should exist');
-- 2. Create a dummy persistent table
CREATE TABLE public.persistent_table (id serial primary key, data text);
SELECT has_table('public', 'persistent_table', 'Persistent table should exist');
-- 3. Create a trigger on the persistent table (using the function)
CREATE TRIGGER persistent_trigger
BEFORE UPDATE ON public.persistent_table
FOR EACH ROW EXECUTE FUNCTION public.my_temp_trigger_func();
SELECT has_trigger('public', 'persistent_table', 'persistent_trigger', 'Trigger on persistent table should exist');
-- 4. Create a dummy temporary table
CREATE TEMPORARY TABLE temp_table (id serial primary key, data text) ON COMMIT PRESERVE ROWS;
SELECT has_table('temp_table', 'Temporary table should exist'); -- Note: has_table checks search_path
-- 5. Create an identical trigger on the temporary table
CREATE TRIGGER temp_trigger
BEFORE UPDATE ON temp_table
FOR EACH ROW EXECUTE FUNCTION public.my_temp_trigger_func();
SELECT has_trigger('temp_table', 'temp_trigger', 'Trigger on temporary table should exist');
-- 6. Test trigger_is on the PERSISTENT table (EXPECTED TO PASS)
SELECT trigger_is(
'public', -- table schema
'persistent_table', -- table name
'persistent_trigger', -- trigger name
'public', -- function schema
'my_temp_trigger_func', -- function name
'trigger_is should PASS for persistent table trigger'
);
-- 7. Test trigger_is on the TEMPORARY table (EXPECTED TO FAIL with have: NULL)
-- Diagnostic query (optional, uncomment to show DB state is correct):
/*
SELECT diag((
SELECT format('Trigger info from pg_trigger for temp_trigger: tgfoid=%s, resolved=%s',
tg.tgfoid, tg.tgfoid::regproc)
FROM pg_trigger tg
JOIN pg_class tbl ON tg.tgrelid = tbl.oid
JOIN pg_namespace ns ON tbl.relnamespace = ns.oid
WHERE tbl.relname = 'temp_table' AND ns.nspname LIKE 'pg_temp%' AND tg.tgname = 'temp_trigger'
));
*/
SELECT trigger_is(
'temp_table', -- table name (pgTAP should search temp schemas)
'temp_trigger', -- trigger name
'public', -- expected function schema
'my_temp_trigger_func', -- expected function name
'trigger_is should FAIL for temporary table trigger (bug)'
);
SELECT * FROM finish();
ROLLBACK;
Expected Behavior:
The final trigger_is test (Test 7 in the example script) should pass, correctly identifying public.my_temp_trigger_func as the function executed by temp_trigger on the temporary table temp_table.
Actual Behavior:
The final trigger_is test fails.
For example:
Failed test 7: "trigger_is should FAIL for temporary table trigger (bug)"
have: NULL
want: my_temp_trigger_func
Workaround:
There is no known workaround using standard pgTAP functions to reliably assert the trigger-function linkage on temporary tables. Users must rely on has_trigger and behavioral tests, or potentially skip this specific assertion for temporary objects.
Additional Context:
Direct inspection of pg_trigger.tgfoid confirms the database linkage is correct at the time of the test, strongly suggesting the issue lies within pgTAP's lookup mechanism for temporary relations in this context.