Add OAT hook calls for more subcommands of ALTER TABLE

The OAT hooks are added in ALTER TABLE for the following subcommands:
- { ENABLE | DISABLE | [NO] FORCE } ROW LEVEL SECURITY
- { ENABLE | DISABLE } TRIGGER
- { ENABLE | DISABLE } RULE.  Note that there was hook for pg_rewrite,
but not for relation ALTER'ed in pg_class.

Tests are added to test_oat_hook for all the subcommand patterns gaining
hooks here.  Based on an ask from Legs Mansion.

Discussion: https://postgr.es/m/tencent_083B3850655AC6EE04FA0A400766D3FE8309@qq.com
This commit is contained in:
Michael Paquier 2023-08-17 08:54:17 +09:00
parent dca20013eb
commit 352ea3acf8
5 changed files with 225 additions and 1 deletions

View File

@ -14843,6 +14843,9 @@ ATExecEnableDisableTrigger(Relation rel, const char *trigname,
EnableDisableTrigger(rel, trigname, InvalidOid,
fires_when, skip_system, recurse,
lockmode);
InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), 0);
}
/*
@ -14855,6 +14858,9 @@ ATExecEnableDisableRule(Relation rel, const char *rulename,
char fires_when, LOCKMODE lockmode)
{
EnableDisableRule(rel, rulename, fires_when);
InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), 0);
}
/*
@ -16134,6 +16140,9 @@ ATExecSetRowSecurity(Relation rel, bool rls)
((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = rls;
CatalogTupleUpdate(pg_class, &tuple->t_self, tuple);
InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), 0);
table_close(pg_class, RowExclusiveLock);
heap_freetuple(tuple);
}
@ -16160,6 +16169,9 @@ ATExecForceNoForceRowSecurity(Relation rel, bool force_rls)
((Form_pg_class) GETSTRUCT(tuple))->relforcerowsecurity = force_rls;
CatalogTupleUpdate(pg_class, &tuple->t_self, tuple);
InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), 0);
table_close(pg_class, RowExclusiveLock);
heap_freetuple(tuple);
}

View File

@ -6,7 +6,7 @@ OBJS = \
test_oat_hooks.o
PGFILEDESC = "test_oat_hooks - example use of object access hooks"
REGRESS = test_oat_hooks
REGRESS = test_oat_hooks alter_table
# disable installcheck for now
NO_INSTALLCHECK = 1

View File

@ -0,0 +1,163 @@
--
-- OAT checks for ALTER TABLE
--
-- This test script fails if debug_discard_caches is enabled, because cache
-- flushes cause extra calls of the OAT hook in recomputeNamespacePath,
-- resulting in more NOTICE messages than are in the expected output.
SET debug_discard_caches = 0;
LOAD 'test_oat_hooks';
SET test_oat_hooks.audit = true;
NOTICE: in object_access_hook_str: superuser attempting alter (subId=0x1000, set) [test_oat_hooks.audit]
NOTICE: in object_access_hook_str: superuser finished alter (subId=0x1000, set) [test_oat_hooks.audit]
NOTICE: in process utility: superuser finished SET
CREATE SCHEMA test_oat_schema;
NOTICE: in process utility: superuser attempting CREATE SCHEMA
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE SCHEMA
CREATE TABLE test_oat_schema.test_oat_tab (c1 int, c2 text);
NOTICE: in process utility: superuser attempting CREATE TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
LINE 1: CREATE TABLE test_oat_schema.test_oat_tab (c1 int, c2 text);
^
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
LINE 1: CREATE TABLE test_oat_schema.test_oat_tab (c1 int, c2 text);
^
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in object access: superuser attempting create (subId=0x0) [internal]
NOTICE: in object access: superuser finished create (subId=0x0) [internal]
NOTICE: in object access: superuser attempting create (subId=0x0) [internal]
NOTICE: in object access: superuser finished create (subId=0x0) [internal]
NOTICE: in process utility: superuser finished CREATE TABLE
CREATE RULE test_oat_notify AS
ON UPDATE TO test_oat_schema.test_oat_tab
DO ALSO NOTIFY test_oat_tab;
NOTICE: in process utility: superuser attempting CREATE RULE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE RULE
CREATE FUNCTION test_oat_schema.test_trigger()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF TG_OP = 'DELETE'
THEN
RETURN OLD;
ELSE
RETURN NEW;
END IF;
END; $$;
NOTICE: in process utility: superuser attempting CREATE FUNCTION
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE FUNCTION
CREATE TRIGGER test_oat_trigger BEFORE INSERT ON test_oat_schema.test_oat_tab
FOR EACH STATEMENT EXECUTE FUNCTION test_oat_schema.test_trigger();
NOTICE: in process utility: superuser attempting CREATE TRIGGER
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE TRIGGER
-- RLS
ALTER TABLE test_oat_schema.test_oat_tab ENABLE ROW LEVEL SECURITY;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
ALTER TABLE test_oat_schema.test_oat_tab DISABLE ROW LEVEL SECURITY;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
ALTER TABLE test_oat_schema.test_oat_tab FORCE ROW LEVEL SECURITY;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
ALTER TABLE test_oat_schema.test_oat_tab NO FORCE ROW LEVEL SECURITY;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
-- Rules
ALTER TABLE test_oat_schema.test_oat_tab DISABLE RULE test_oat_notify;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
ALTER TABLE test_oat_schema.test_oat_tab ENABLE RULE test_oat_notify;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
-- Triggers
ALTER TABLE test_oat_schema.test_oat_tab DISABLE TRIGGER test_oat_trigger;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
ALTER TABLE test_oat_schema.test_oat_tab ENABLE TRIGGER test_oat_trigger;
NOTICE: in process utility: superuser attempting ALTER TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser attempting alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in object access: superuser finished alter (subId=0x0) [explicit without auxiliary object]
NOTICE: in process utility: superuser finished ALTER TABLE
DROP TABLE test_oat_schema.test_oat_tab;
NOTICE: in process utility: superuser attempting DROP TABLE
NOTICE: in object access: superuser attempting namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser finished namespace search (subId=0x0) [report on violation, allowed]
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in object access: superuser attempting drop (subId=0x0) []
NOTICE: in object access: superuser finished drop (subId=0x0) []
NOTICE: in process utility: superuser finished DROP TABLE

View File

@ -23,6 +23,7 @@ tests += {
'regress': {
'sql': [
'test_oat_hooks',
'alter_table',
],
'regress_args': ['--no-locale', '--encoding=UTF8'],
'runningcheck': false,

View File

@ -0,0 +1,48 @@
--
-- OAT checks for ALTER TABLE
--
-- This test script fails if debug_discard_caches is enabled, because cache
-- flushes cause extra calls of the OAT hook in recomputeNamespacePath,
-- resulting in more NOTICE messages than are in the expected output.
SET debug_discard_caches = 0;
LOAD 'test_oat_hooks';
SET test_oat_hooks.audit = true;
CREATE SCHEMA test_oat_schema;
CREATE TABLE test_oat_schema.test_oat_tab (c1 int, c2 text);
CREATE RULE test_oat_notify AS
ON UPDATE TO test_oat_schema.test_oat_tab
DO ALSO NOTIFY test_oat_tab;
CREATE FUNCTION test_oat_schema.test_trigger()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF TG_OP = 'DELETE'
THEN
RETURN OLD;
ELSE
RETURN NEW;
END IF;
END; $$;
CREATE TRIGGER test_oat_trigger BEFORE INSERT ON test_oat_schema.test_oat_tab
FOR EACH STATEMENT EXECUTE FUNCTION test_oat_schema.test_trigger();
-- RLS
ALTER TABLE test_oat_schema.test_oat_tab ENABLE ROW LEVEL SECURITY;
ALTER TABLE test_oat_schema.test_oat_tab DISABLE ROW LEVEL SECURITY;
ALTER TABLE test_oat_schema.test_oat_tab FORCE ROW LEVEL SECURITY;
ALTER TABLE test_oat_schema.test_oat_tab NO FORCE ROW LEVEL SECURITY;
-- Rules
ALTER TABLE test_oat_schema.test_oat_tab DISABLE RULE test_oat_notify;
ALTER TABLE test_oat_schema.test_oat_tab ENABLE RULE test_oat_notify;
-- Triggers
ALTER TABLE test_oat_schema.test_oat_tab DISABLE TRIGGER test_oat_trigger;
ALTER TABLE test_oat_schema.test_oat_tab ENABLE TRIGGER test_oat_trigger;
DROP TABLE test_oat_schema.test_oat_tab;