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,