doc/src/sgml/catalogs.sgml | 4 +- src/backend/commands/seclabel.c | 41 +++++++++++++++++++++++++++++++---- src/backend/utils/cache/syscache.c | 12 ++++++++++ src/include/catalog/indexing.h | 2 +- src/include/catalog/pg_seclabel.h | 2 +- src/include/utils/syscache.h | 1 + 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 713ee25..6c57f7d 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -4722,7 +4722,7 @@ provider - text + name The label provider associated with this label. @@ -7564,7 +7564,7 @@ provider - text + name pg_seclabel.provider The label provider associated with this label. diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index 51a5567..012fc28 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -15,12 +15,14 @@ #include "catalog/catalog.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_largeobject.h" #include "catalog/pg_seclabel.h" #include "commands/seclabel.h" #include "miscadmin.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/syscache.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/tqual.h" @@ -150,6 +152,33 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider) Assert(!IsSharedRelation(object->classId)); + /* + * XXX - The reason why we don't reference security label of + * large objects is the number of large objects being scanned + * is unexpectable. If we would try to scan millions of objects, + * the syscache mechanism must have a complex cache reclaim + * mechanism. However, frequent cache flushing is fundamentally + * nonsense. So, we always use raw scanning for large objects. + */ + if (object->classId != LargeObjectRelationId) + { + tuple = SearchSysCache4(SECLABELOID, + ObjectIdGetDatum(object->objectId), + ObjectIdGetDatum(object->classId), + Int32GetDatum(object->objectSubId), + CStringGetDatum(provider)); + if (HeapTupleIsValid(tuple)) + { + datum = SysCacheGetAttr(SECLABELOID, tuple, + Anum_pg_seclabel_label, &isnull); + if (!isnull) + seclabel = TextDatumGetCString(datum); + + ReleaseSysCache(tuple); + } + return seclabel; + } + ScanKeyInit(&keys[0], Anum_pg_seclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, @@ -164,8 +193,8 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider) Int32GetDatum(object->objectSubId)); ScanKeyInit(&keys[3], Anum_pg_seclabel_provider, - BTEqualStrategyNumber, F_TEXTEQ, - CStringGetTextDatum(provider)); + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(provider)); pg_seclabel = heap_open(SecLabelRelationId, AccessShareLock); @@ -201,6 +230,7 @@ SetSecurityLabel(const ObjectAddress *object, SysScanDesc scan; HeapTuple oldtup; HeapTuple newtup = NULL; + NameData name; Datum values[Natts_pg_seclabel]; bool nulls[Natts_pg_seclabel]; bool replaces[Natts_pg_seclabel]; @@ -211,10 +241,11 @@ SetSecurityLabel(const ObjectAddress *object, /* Prepare to form or update a tuple, if necessary. */ memset(nulls, false, sizeof(nulls)); memset(replaces, false, sizeof(replaces)); + namestrcpy(&name, provider); values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId); values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId); values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId); - values[Anum_pg_seclabel_provider - 1] = CStringGetTextDatum(provider); + values[Anum_pg_seclabel_provider - 1] = NameGetDatum(&name); if (label != NULL) values[Anum_pg_seclabel_label - 1] = CStringGetTextDatum(label); @@ -233,8 +264,8 @@ SetSecurityLabel(const ObjectAddress *object, Int32GetDatum(object->objectSubId)); ScanKeyInit(&keys[3], Anum_pg_seclabel_provider, - BTEqualStrategyNumber, F_TEXTEQ, - CStringGetTextDatum(provider)); + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(provider)); pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock); diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 99e5f1d..18194d1 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -44,6 +44,7 @@ #include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" +#include "catalog/pg_seclabel.h" #include "catalog/pg_statistic.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_ts_config.h" @@ -587,6 +588,17 @@ static const struct cachedesc cacheinfo[] = { }, 1024 }, + {SecLabelRelationId, /* SECLABELOID */ + SecLabelObjectIndexId, + 4, + { + Anum_pg_seclabel_objoid, + Anum_pg_seclabel_classoid, + Anum_pg_seclabel_objsubid, + Anum_pg_seclabel_provider + }, + 2048 + }, {StatisticRelationId, /* STATRELATTINH */ StatisticRelidAttnumInhIndexId, 3, diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 4118e64..6b5a7aa 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -291,7 +291,7 @@ DECLARE_UNIQUE_INDEX(pg_default_acl_oid_index, 828, on pg_default_acl using btre DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops)); #define DbRoleSettingDatidRolidIndexId 2965 -DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops)); +DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider name_ops)); #define SecLabelObjectIndexId 3597 DECLARE_UNIQUE_INDEX(pg_extension_oid_index, 3080, on pg_extension using btree(oid oid_ops)); diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h index 1f9a6a0..1ed8b87 100644 --- a/src/include/catalog/pg_seclabel.h +++ b/src/include/catalog/pg_seclabel.h @@ -25,7 +25,7 @@ CATALOG(pg_seclabel,3596) BKI_WITHOUT_OIDS Oid objoid; /* OID of the object itself */ Oid classoid; /* OID of table containing the object */ int4 objsubid; /* column number, or 0 if not used */ - text provider; /* name of label provider */ + NameData provider; /* name of label provider */ text label; /* security label of the object */ } FormData_pg_seclabel; diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 55d2230..4fbbab5 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -73,6 +73,7 @@ enum SysCacheIdentifier RELNAMENSP, RELOID, RULERELNAME, + SECLABELOID, STATRELATTINH, TABLESPACEOID, TSCONFIGMAP,