Hello, I was using an object access hook for oat_post_create access while creating an extension and expected that I would be able to query for the newly created extension with get_extension_oid(), but it was returning InvalidOid. However, the same process works for triggers, so I was wondering what the expected behavior is? >From the documentation in objectaccess.h, it doesn't mention anything about CommandCounterIncrement() for POST_CREATE which implied to me that it wasn't something I would need to worry about. One option I thought of was this patch where CCI is called before the access hook so that the new tuple is visible in the hook. Another option would be to revise the documentation to reflect the expected behavior.
Thanks, Mary Xu
diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c index 1c51df02d2..e098443915 100644 --- a/src/backend/catalog/objectaccess.c +++ b/src/backend/catalog/objectaccess.c @@ -10,6 +10,7 @@ */ #include "postgres.h" +#include "access/xact.h" #include "catalog/objectaccess.h" #include "catalog/pg_class.h" #include "catalog/pg_namespace.h" @@ -40,6 +41,7 @@ RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, memset(&pc_arg, 0, sizeof(ObjectAccessPostCreate)); pc_arg.is_internal = is_internal; + CommandCounterIncrement(); (*object_access_hook) (OAT_POST_CREATE, classId, objectId, subId, (void *) &pc_arg); diff --git a/src/test/modules/test_oat_hooks/Makefile b/src/test/modules/test_oat_hooks/Makefile index 2b5d2687f8..74ef7f0239 100644 --- a/src/test/modules/test_oat_hooks/Makefile +++ b/src/test/modules/test_oat_hooks/Makefile @@ -6,6 +6,10 @@ OBJS = \ test_oat_hooks.o PGFILEDESC = "test_oat_hooks - example use of object access hooks" +EXTENSION = test_ext1 + +DATA = test_ext1--1.0.sql + REGRESS = test_oat_hooks # disable installcheck for now diff --git a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out index 39b274b8fa..c680bf4d9e 100644 --- a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out +++ b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out @@ -61,6 +61,13 @@ NOTICE: in process utility: superuser attempting CreateRoleStmt 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 CreateRoleStmt +CREATE EXTENSION test_ext1; +NOTICE: in process utility: superuser attempting CreateExtensionStmt +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 create (subId=0x0) [explicit] +NOTICE: in object access: superuser finished create (subId=0x0) [explicit] +NOTICE: in process utility: superuser finished CreateExtensionStmt CREATE TABLE regress_test_table (t text); NOTICE: in process utility: superuser attempting CreateStmt NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed] @@ -293,6 +300,8 @@ privileges for parameter test_oat_hooks.user_var2 privileges for parameter test_oat_hooks.super_var2 privileges for parameter none.such privileges for parameter another.bogus +DROP EXTENSION test_ext1; +DROP TABLE regress_test_table; REVOKE ALL PRIVILEGES ON PARAMETER none.such, another.bogus, test_oat_hooks.user_var1, test_oat_hooks.super_var1, diff --git a/src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql b/src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql index 8b6d5373aa..4e40d23571 100644 --- a/src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql +++ b/src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql @@ -36,6 +36,7 @@ REVOKE ALL ON PARAMETER "none.such" FROM PUBLIC; -- Create objects for use in the test CREATE USER regress_test_user; +CREATE EXTENSION test_ext1; CREATE TABLE regress_test_table (t text); GRANT SELECT ON Table regress_test_table TO public; CREATE FUNCTION regress_test_func (t text) RETURNS text AS $$ @@ -92,6 +93,8 @@ RESET SESSION AUTHORIZATION; SET test_oat_hooks.audit = false; DROP ROLE regress_role_joe; -- fails +DROP EXTENSION test_ext1; +DROP TABLE regress_test_table; REVOKE ALL PRIVILEGES ON PARAMETER none.such, another.bogus, test_oat_hooks.user_var1, test_oat_hooks.super_var1, diff --git a/src/test/modules/test_oat_hooks/test_ext1--1.0.sql b/src/test/modules/test_oat_hooks/test_ext1--1.0.sql new file mode 100644 index 0000000000..fc15f19684 --- /dev/null +++ b/src/test/modules/test_oat_hooks/test_ext1--1.0.sql @@ -0,0 +1,2 @@ +/* src/test/modules/test_oat_hooks/test_ext1--1.0.sql */ +/* empty sql file */ diff --git a/src/test/modules/test_oat_hooks/test_ext1.control b/src/test/modules/test_oat_hooks/test_ext1.control new file mode 100644 index 0000000000..fc8bba46c0 --- /dev/null +++ b/src/test/modules/test_oat_hooks/test_ext1.control @@ -0,0 +1,3 @@ +comment = 'Test extension 1' +default_version = '1.0' +relocatable = false diff --git a/src/test/modules/test_oat_hooks/test_oat_hooks.c b/src/test/modules/test_oat_hooks/test_oat_hooks.c index 7ef272cc7a..3a4e48bc50 100644 --- a/src/test/modules/test_oat_hooks/test_oat_hooks.c +++ b/src/test/modules/test_oat_hooks/test_oat_hooks.c @@ -14,13 +14,19 @@ #include "postgres.h" #include "access/parallel.h" +#include "access/relation.h" #include "catalog/dependency.h" #include "catalog/objectaccess.h" +#include "catalog/pg_authid.h" +#include "catalog/pg_class.h" +#include "catalog/pg_extension.h" #include "catalog/pg_proc.h" +#include "commands/extension.h" #include "executor/executor.h" #include "fmgr.h" #include "miscadmin.h" #include "tcop/utility.h" +#include "utils/lsyscache.h" PG_MODULE_MAGIC; @@ -67,6 +73,7 @@ static void REGRESS_utility_command(PlannedStmt *pstmt, static const char *nodetag_to_string(NodeTag tag); static char *accesstype_to_string(ObjectAccessType access, int subId); static char *accesstype_arg_to_string(ObjectAccessType access, void *arg); +static void CheckObjectVisible(Oid classId, Oid objectId); void _PG_init(void); @@ -338,6 +345,12 @@ REGRESS_object_access_hook(ObjectAccessType access, Oid classId, Oid objectId, i accesstype_to_string(access, 0), accesstype_arg_to_string(access, arg)))); + /* See if new object is visible */ + if (access == OAT_POST_CREATE) + { + CheckObjectVisible(classId, objectId); + } + /* Forward to next hook in the chain */ if (next_object_access_hook) (*next_object_access_hook) (access, classId, objectId, subId, arg); @@ -1844,3 +1857,41 @@ accesstype_arg_to_string(ObjectAccessType access, void *arg) return pstrdup("unknown"); } + +/* Checks to see if created object is visible in its respective table*/ +static void +CheckObjectVisible(Oid classId, Oid objectId) +{ + switch (classId) + { + case RelationRelationId: + { + if (get_rel_name(objectId) == NULL) + { + ereport(ERROR, errmsg("Relation object with OID %d is not visible in POST_CREATE access hook", + objectId)); + } + break; + } + case ExtensionRelationId: + { + if (get_extension_name(objectId) == NULL) + { + ereport(ERROR, errmsg("Extension object with OID %d is not visible in POST_CREATE access hook", + objectId)); + } + break; + } + case AuthIdRelationId: + { + if (GetUserNameFromId(objectId, true) == NULL) + { + ereport(ERROR, errmsg("AuthId object with OID %d is not visible in POST_CREATE access hook", + objectId)); + } + break; + } + default: + return; + } +}