Compare commits

..

No commits in common. "5f27b5f848a433ba54c521ccb889788b8f4d6ba7" and "22655aa23132a0645fdcdce4b233a1fff0c0cf8f" have entirely different histories.

12 changed files with 219 additions and 810 deletions

View File

@ -31,7 +31,6 @@
#include "access/xact.h" #include "access/xact.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/pg_am.h" #include "catalog/pg_am.h"
#include "catalog/pg_opfamily_d.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "common/pg_prng.h" #include "common/pg_prng.h"
#include "lib/bloomfilter.h" #include "lib/bloomfilter.h"
@ -339,20 +338,10 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
errmsg("index \"%s\" metapage has equalimage field set on unsupported nbtree version", errmsg("index \"%s\" metapage has equalimage field set on unsupported nbtree version",
RelationGetRelationName(indrel)))); RelationGetRelationName(indrel))));
if (allequalimage && !_bt_allequalimage(indrel, false)) if (allequalimage && !_bt_allequalimage(indrel, false))
{
bool has_interval_ops = false;
for (int i = 0; i < IndexRelationGetNumberOfKeyAttributes(indrel); i++)
if (indrel->rd_opfamily[i] == INTERVAL_BTREE_FAM_OID)
has_interval_ops = true;
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED), (errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe", errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe",
RelationGetRelationName(indrel)), RelationGetRelationName(indrel))));
has_interval_ops
? errhint("This is known of \"interval\" indexes last built on a version predating 2023-11.")
: 0));
}
/* Check index, possibly against table it is an index on */ /* Check index, possibly against table it is an index on */
bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck, bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck,

View File

@ -13,27 +13,6 @@
* NOTES * NOTES
* See acl.h. * See acl.h.
* *
* The xxx_aclmask() functions in this file are wrappers around
* acl.c's aclmask() function; see that for basic usage information.
* The wrapper functions add object-type-specific lookup capability.
* Generally, they will throw error if the object doesn't exist.
*
* The xxx_aclmask_ext() functions add the ability to not throw
* error if the object doesn't exist. If their "is_missing" argument
* isn't NULL, then when the object isn't found they will set
* *is_missing = true and return zero (no privileges) instead of
* throwing an error. Caller must initialize *is_missing = false.
*
* The xxx_aclcheck() functions are simplified wrappers around the
* corresponding xxx_aclmask() functions, simply returning ACLCHECK_OK
* if any of the privileges specified in "mode" are held, and otherwise
* a suitable error code (in practice, always ACLCHECK_NO_PRIV).
* Again, they will throw error if the object doesn't exist.
*
* The xxx_aclcheck_ext() functions add the ability to not throw
* error if the object doesn't exist. Their "is_missing" argument
* works similarly to the xxx_aclmask_ext() functions.
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
@ -160,9 +139,6 @@ static AclMode pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum,
Oid roleid, AclMode mask, AclMaskHow how); Oid roleid, AclMode mask, AclMaskHow how);
static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid, static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
static AclMode object_aclmask_ext(Oid classid, Oid objectid, Oid roleid,
AclMode mask, AclMaskHow how,
bool *is_missing);
static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
Oid roleid, AclMode mask, AclMaskHow how); Oid roleid, AclMode mask, AclMaskHow how);
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
@ -175,12 +151,10 @@ static AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
AclMode mask, AclMaskHow how, Snapshot snapshot); AclMode mask, AclMaskHow how, Snapshot snapshot);
static AclMode pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid, static AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how, AclMode mask, AclMaskHow how);
bool *is_missing); static AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
static AclMode pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how);
AclMode mask, AclMaskHow how,
bool *is_missing);
static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid,
Acl *new_acl); Acl *new_acl);
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid,
@ -3090,18 +3064,6 @@ pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid,
static AclMode static AclMode
object_aclmask(Oid classid, Oid objectid, Oid roleid, object_aclmask(Oid classid, Oid objectid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{
return object_aclmask_ext(classid, objectid, roleid, mask, how, NULL);
}
/*
* Generic routine for examining a user's privileges for an object,
* with is_missing
*/
static AclMode
object_aclmask_ext(Oid classid, Oid objectid, Oid roleid,
AclMode mask, AclMaskHow how,
bool *is_missing)
{ {
int cacheid; int cacheid;
AclMode result; AclMode result;
@ -3115,11 +3077,9 @@ object_aclmask_ext(Oid classid, Oid objectid, Oid roleid,
switch (classid) switch (classid)
{ {
case NamespaceRelationId: case NamespaceRelationId:
return pg_namespace_aclmask_ext(objectid, roleid, mask, how, return pg_namespace_aclmask(objectid, roleid, mask, how);
is_missing);
case TypeRelationId: case TypeRelationId:
return pg_type_aclmask_ext(objectid, roleid, mask, how, return pg_type_aclmask(objectid, roleid, mask, how);
is_missing);
} }
/* Even more special cases */ /* Even more special cases */
@ -3132,26 +3092,16 @@ object_aclmask_ext(Oid classid, Oid objectid, Oid roleid,
return mask; return mask;
/* /*
* Get the object's ACL from its catalog * Get the objects's ACL from its catalog
*/ */
cacheid = get_object_catcache_oid(classid); cacheid = get_object_catcache_oid(classid);
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid)); tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return 0;
}
else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("%s with OID %u does not exist", errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
get_object_class_descr(classid), objectid)));
}
ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid, ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
tuple, tuple,
@ -3199,7 +3149,10 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
} }
/* /*
* Routine for examining a user's privileges for a column, with is_missing * Routine for examining a user's privileges for a column
*
* Does the bulk of the work for pg_attribute_aclmask(), and allows other
* callers to avoid the missing attribute ERROR when is_missing is non-NULL.
*/ */
static AclMode static AclMode
pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
@ -3273,25 +3226,16 @@ pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
* Must get the relation's ownerId from pg_class. Since we already found * Must get the relation's ownerId from pg_class. Since we already found
* a pg_attribute entry, the only likely reason for this to fail is that a * a pg_attribute entry, the only likely reason for this to fail is that a
* concurrent DROP of the relation committed since then (which could only * concurrent DROP of the relation committed since then (which could only
* happen if we don't have lock on the relation). Treat that similarly to * happen if we don't have lock on the relation). We prefer to report "no
* not finding the attribute entry. * privileges" rather than failing in such a case, so as to avoid unwanted
* failures in has_column_privilege() tests.
*/ */
classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
if (!HeapTupleIsValid(classTuple)) if (!HeapTupleIsValid(classTuple))
{ {
ReleaseSysCache(attTuple); ReleaseSysCache(attTuple);
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return 0; return 0;
} }
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation with OID %u does not exist",
table_oid)));
}
classForm = (Form_pg_class) GETSTRUCT(classTuple); classForm = (Form_pg_class) GETSTRUCT(classTuple);
ownerId = classForm->relowner; ownerId = classForm->relowner;
@ -3323,7 +3267,10 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
} }
/* /*
* Routine for examining a user's privileges for a table, with is_missing * Routine for examining a user's privileges for a table
*
* Does the bulk of the work for pg_class_aclmask(), and allows other
* callers to avoid the missing relation ERROR when is_missing is non-NULL.
*/ */
static AclMode static AclMode
pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
@ -3638,12 +3585,11 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
} }
/* /*
* Routine for examining a user's privileges for a namespace, with is_missing * Routine for examining a user's privileges for a namespace
*/ */
static AclMode static AclMode
pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid, pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how, AclMode mask, AclMaskHow how)
bool *is_missing)
{ {
AclMode result; AclMode result;
HeapTuple tuple; HeapTuple tuple;
@ -3677,8 +3623,8 @@ pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid,
*/ */
if (isTempNamespace(nsp_oid)) if (isTempNamespace(nsp_oid))
{ {
if (object_aclcheck_ext(DatabaseRelationId, MyDatabaseId, roleid, if (object_aclcheck(DatabaseRelationId, MyDatabaseId, roleid,
ACL_CREATE_TEMP, is_missing) == ACLCHECK_OK) ACL_CREATE_TEMP) == ACLCHECK_OK)
return mask & ACL_ALL_RIGHTS_SCHEMA; return mask & ACL_ALL_RIGHTS_SCHEMA;
else else
return mask & ACL_USAGE; return mask & ACL_USAGE;
@ -3689,18 +3635,9 @@ pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid,
*/ */
tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid)); tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return 0;
}
else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA), (errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema with OID %u does not exist", nsp_oid))); errmsg("schema with OID %u does not exist", nsp_oid)));
}
ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
@ -3740,20 +3677,20 @@ pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid,
} }
/* /*
* Routine for examining a user's privileges for a type, with is_missing * Routine for examining a user's privileges for a type.
*/ */
static AclMode static AclMode
pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how, pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
bool *is_missing)
{ {
AclMode result; AclMode result;
HeapTuple tuple; HeapTuple tuple;
Form_pg_type typeForm;
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
Oid ownerId; Oid ownerId;
Form_pg_type typeForm;
/* Bypass permission checks for superusers */ /* Bypass permission checks for superusers */
if (superuser_arg(roleid)) if (superuser_arg(roleid))
return mask; return mask;
@ -3763,19 +3700,10 @@ pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how,
*/ */
tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return 0;
}
else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type with OID %u does not exist", errmsg("type with OID %u does not exist",
type_oid))); type_oid)));
}
typeForm = (Form_pg_type) GETSTRUCT(tuple); typeForm = (Form_pg_type) GETSTRUCT(tuple);
/* /*
@ -3789,20 +3717,9 @@ pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how,
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(elttype_oid)); tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(elttype_oid));
/* this case is not a user-facing error, so elog not ereport */
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ elog(ERROR, "cache lookup failed for type %u", elttype_oid);
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return 0;
}
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type with OID %u does not exist",
elttype_oid)));
}
typeForm = (Form_pg_type) GETSTRUCT(tuple); typeForm = (Form_pg_type) GETSTRUCT(tuple);
} }
@ -3842,20 +3759,7 @@ pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how,
AclResult AclResult
object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode) object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
{ {
return object_aclcheck_ext(classid, objectid, roleid, mode, NULL); if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
}
/*
* Exported generic routine for checking a user's access privileges to an
* object, with is_missing
*/
AclResult
object_aclcheck_ext(Oid classid, Oid objectid,
Oid roleid, AclMode mode,
bool *is_missing)
{
if (object_aclmask_ext(classid, objectid, roleid, mode, ACLMASK_ANY,
is_missing) != 0)
return ACLCHECK_OK; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; return ACLCHECK_NO_PRIV;
@ -3880,8 +3784,10 @@ pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
/* /*
* Exported routine for checking a user's access privileges to a column, * Exported routine for checking a user's access privileges to a column
* with is_missing *
* Does the bulk of the work for pg_attribute_aclcheck(), and allows other
* callers to avoid the missing attribute ERROR when is_missing is non-NULL.
*/ */
AclResult AclResult
pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
@ -3916,47 +3822,23 @@ pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
AclResult AclResult
pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
AclMaskHow how) AclMaskHow how)
{
return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
}
/*
* Exported routine for checking a user's access privileges to any/all columns,
* with is_missing
*/
AclResult
pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid,
AclMode mode, AclMaskHow how,
bool *is_missing)
{ {
AclResult result; AclResult result;
HeapTuple classTuple; HeapTuple classTuple;
Form_pg_class classForm; Form_pg_class classForm;
Oid ownerId;
AttrNumber nattrs; AttrNumber nattrs;
AttrNumber curr_att; AttrNumber curr_att;
/* /*
* Must fetch pg_class row to get owner ID and number of attributes. * Must fetch pg_class row to check number of attributes. As in
* pg_attribute_aclmask, we prefer to return "no privileges" instead of
* throwing an error if we get any unexpected lookup errors.
*/ */
classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
if (!HeapTupleIsValid(classTuple)) if (!HeapTupleIsValid(classTuple))
{
if (is_missing != NULL)
{
/* return "no privileges" instead of throwing an error */
*is_missing = true;
return ACLCHECK_NO_PRIV; return ACLCHECK_NO_PRIV;
}
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation with OID %u does not exist",
table_oid)));
}
classForm = (Form_pg_class) GETSTRUCT(classTuple); classForm = (Form_pg_class) GETSTRUCT(classTuple);
ownerId = classForm->relowner;
nattrs = classForm->relnatts; nattrs = classForm->relnatts;
ReleaseSysCache(classTuple); ReleaseSysCache(classTuple);
@ -3970,20 +3852,11 @@ pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid,
for (curr_att = 1; curr_att <= nattrs; curr_att++) for (curr_att = 1; curr_att <= nattrs; curr_att++)
{ {
HeapTuple attTuple; HeapTuple attTuple;
Datum aclDatum;
bool isNull;
Acl *acl;
AclMode attmask; AclMode attmask;
attTuple = SearchSysCache2(ATTNUM, attTuple = SearchSysCache2(ATTNUM,
ObjectIdGetDatum(table_oid), ObjectIdGetDatum(table_oid),
Int16GetDatum(curr_att)); Int16GetDatum(curr_att));
/*
* Lookup failure probably indicates that the table was just dropped,
* but we'll treat it the same as a dropped column rather than
* throwing error.
*/
if (!HeapTupleIsValid(attTuple)) if (!HeapTupleIsValid(attTuple))
continue; continue;
@ -3994,27 +3867,16 @@ pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid,
continue; continue;
} }
aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
&isNull);
/* /*
* Here we hard-wire knowledge that the default ACL for a column * Here we hard-wire knowledge that the default ACL for a column
* grants no privileges, so that we can fall out quickly in the very * grants no privileges, so that we can fall out quickly in the very
* common case where attacl is null. * common case where attacl is null.
*/ */
if (isNull) if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
attmask = 0; attmask = 0;
else else
{ attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
/* detoast column's ACL if necessary */ mode, ACLMASK_ANY);
acl = DatumGetAclP(aclDatum);
attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
/* if we have a detoasted copy, free it */
if ((Pointer) acl != DatumGetPointer(aclDatum))
pfree(acl);
}
ReleaseSysCache(attTuple); ReleaseSysCache(attTuple);
@ -4049,8 +3911,10 @@ pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
} }
/* /*
* Exported routine for checking a user's access privileges to a table, * Exported routine for checking a user's access privileges to a table
* with is_missing *
* Does the bulk of the work for pg_class_aclcheck(), and allows other
* callers to avoid the missing relation ERROR when is_missing is non-NULL.
*/ */
AclResult AclResult
pg_class_aclcheck_ext(Oid table_oid, Oid roleid, pg_class_aclcheck_ext(Oid table_oid, Oid roleid,

View File

@ -183,19 +183,6 @@ char *namespace_search_path = NULL;
/* Local functions */ /* Local functions */
static bool RelationIsVisibleExt(Oid relid, bool *is_missing);
static bool TypeIsVisibleExt(Oid typid, bool *is_missing);
static bool FunctionIsVisibleExt(Oid funcid, bool *is_missing);
static bool OperatorIsVisibleExt(Oid oprid, bool *is_missing);
static bool OpclassIsVisibleExt(Oid opcid, bool *is_missing);
static bool OpfamilyIsVisibleExt(Oid opfid, bool *is_missing);
static bool CollationIsVisibleExt(Oid collid, bool *is_missing);
static bool ConversionIsVisibleExt(Oid conid, bool *is_missing);
static bool StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing);
static bool TSParserIsVisibleExt(Oid prsId, bool *is_missing);
static bool TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing);
static bool TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing);
static bool TSConfigIsVisibleExt(Oid cfgid, bool *is_missing);
static void recomputeNamespacePath(void); static void recomputeNamespacePath(void);
static void AccessTempTableNamespace(bool force); static void AccessTempTableNamespace(bool force);
static void InitTempTableNamespace(void); static void InitTempTableNamespace(void);
@ -704,18 +691,6 @@ RelnameGetRelid(const char *relname)
*/ */
bool bool
RelationIsVisible(Oid relid) RelationIsVisible(Oid relid)
{
return RelationIsVisibleExt(relid, NULL);
}
/*
* RelationIsVisibleExt
* As above, but if the relation isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
RelationIsVisibleExt(Oid relid, bool *is_missing)
{ {
HeapTuple reltup; HeapTuple reltup;
Form_pg_class relform; Form_pg_class relform;
@ -724,14 +699,7 @@ RelationIsVisibleExt(Oid relid, bool *is_missing)
reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for relation %u", relid); elog(ERROR, "cache lookup failed for relation %u", relid);
}
relform = (Form_pg_class) GETSTRUCT(reltup); relform = (Form_pg_class) GETSTRUCT(reltup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -831,18 +799,6 @@ TypenameGetTypidExtended(const char *typname, bool temp_ok)
*/ */
bool bool
TypeIsVisible(Oid typid) TypeIsVisible(Oid typid)
{
return TypeIsVisibleExt(typid, NULL);
}
/*
* TypeIsVisibleExt
* As above, but if the type isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
TypeIsVisibleExt(Oid typid, bool *is_missing)
{ {
HeapTuple typtup; HeapTuple typtup;
Form_pg_type typform; Form_pg_type typform;
@ -851,14 +807,7 @@ TypeIsVisibleExt(Oid typid, bool *is_missing)
typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
if (!HeapTupleIsValid(typtup)) if (!HeapTupleIsValid(typtup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for type %u", typid); elog(ERROR, "cache lookup failed for type %u", typid);
}
typform = (Form_pg_type) GETSTRUCT(typtup); typform = (Form_pg_type) GETSTRUCT(typtup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -1487,18 +1436,6 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
*/ */
bool bool
FunctionIsVisible(Oid funcid) FunctionIsVisible(Oid funcid)
{
return FunctionIsVisibleExt(funcid, NULL);
}
/*
* FunctionIsVisibleExt
* As above, but if the function isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
FunctionIsVisibleExt(Oid funcid, bool *is_missing)
{ {
HeapTuple proctup; HeapTuple proctup;
Form_pg_proc procform; Form_pg_proc procform;
@ -1507,14 +1444,7 @@ FunctionIsVisibleExt(Oid funcid, bool *is_missing)
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
if (!HeapTupleIsValid(proctup)) if (!HeapTupleIsValid(proctup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for function %u", funcid); elog(ERROR, "cache lookup failed for function %u", funcid);
}
procform = (Form_pg_proc) GETSTRUCT(proctup); procform = (Form_pg_proc) GETSTRUCT(proctup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -1840,18 +1770,6 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
*/ */
bool bool
OperatorIsVisible(Oid oprid) OperatorIsVisible(Oid oprid)
{
return OperatorIsVisibleExt(oprid, NULL);
}
/*
* OperatorIsVisibleExt
* As above, but if the operator isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
OperatorIsVisibleExt(Oid oprid, bool *is_missing)
{ {
HeapTuple oprtup; HeapTuple oprtup;
Form_pg_operator oprform; Form_pg_operator oprform;
@ -1860,14 +1778,7 @@ OperatorIsVisibleExt(Oid oprid, bool *is_missing)
oprtup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid)); oprtup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid));
if (!HeapTupleIsValid(oprtup)) if (!HeapTupleIsValid(oprtup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for operator %u", oprid); elog(ERROR, "cache lookup failed for operator %u", oprid);
}
oprform = (Form_pg_operator) GETSTRUCT(oprtup); oprform = (Form_pg_operator) GETSTRUCT(oprtup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -1945,18 +1856,6 @@ OpclassnameGetOpcid(Oid amid, const char *opcname)
*/ */
bool bool
OpclassIsVisible(Oid opcid) OpclassIsVisible(Oid opcid)
{
return OpclassIsVisibleExt(opcid, NULL);
}
/*
* OpclassIsVisibleExt
* As above, but if the opclass isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
OpclassIsVisibleExt(Oid opcid, bool *is_missing)
{ {
HeapTuple opctup; HeapTuple opctup;
Form_pg_opclass opcform; Form_pg_opclass opcform;
@ -1965,14 +1864,7 @@ OpclassIsVisibleExt(Oid opcid, bool *is_missing)
opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid)); opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
if (!HeapTupleIsValid(opctup)) if (!HeapTupleIsValid(opctup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for opclass %u", opcid); elog(ERROR, "cache lookup failed for opclass %u", opcid);
}
opcform = (Form_pg_opclass) GETSTRUCT(opctup); opcform = (Form_pg_opclass) GETSTRUCT(opctup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2047,18 +1939,6 @@ OpfamilynameGetOpfid(Oid amid, const char *opfname)
*/ */
bool bool
OpfamilyIsVisible(Oid opfid) OpfamilyIsVisible(Oid opfid)
{
return OpfamilyIsVisibleExt(opfid, NULL);
}
/*
* OpfamilyIsVisibleExt
* As above, but if the opfamily isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
{ {
HeapTuple opftup; HeapTuple opftup;
Form_pg_opfamily opfform; Form_pg_opfamily opfform;
@ -2067,14 +1947,7 @@ OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid)); opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
if (!HeapTupleIsValid(opftup)) if (!HeapTupleIsValid(opftup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for opfamily %u", opfid); elog(ERROR, "cache lookup failed for opfamily %u", opfid);
}
opfform = (Form_pg_opfamily) GETSTRUCT(opftup); opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2198,18 +2071,6 @@ CollationGetCollid(const char *collname)
*/ */
bool bool
CollationIsVisible(Oid collid) CollationIsVisible(Oid collid)
{
return CollationIsVisibleExt(collid, NULL);
}
/*
* CollationIsVisibleExt
* As above, but if the collation isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
CollationIsVisibleExt(Oid collid, bool *is_missing)
{ {
HeapTuple colltup; HeapTuple colltup;
Form_pg_collation collform; Form_pg_collation collform;
@ -2218,14 +2079,7 @@ CollationIsVisibleExt(Oid collid, bool *is_missing)
colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid)); colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
if (!HeapTupleIsValid(colltup)) if (!HeapTupleIsValid(colltup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for collation %u", collid); elog(ERROR, "cache lookup failed for collation %u", collid);
}
collform = (Form_pg_collation) GETSTRUCT(colltup); collform = (Form_pg_collation) GETSTRUCT(colltup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2300,18 +2154,6 @@ ConversionGetConid(const char *conname)
*/ */
bool bool
ConversionIsVisible(Oid conid) ConversionIsVisible(Oid conid)
{
return ConversionIsVisibleExt(conid, NULL);
}
/*
* ConversionIsVisibleExt
* As above, but if the conversion isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
ConversionIsVisibleExt(Oid conid, bool *is_missing)
{ {
HeapTuple contup; HeapTuple contup;
Form_pg_conversion conform; Form_pg_conversion conform;
@ -2320,14 +2162,7 @@ ConversionIsVisibleExt(Oid conid, bool *is_missing)
contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid)); contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
if (!HeapTupleIsValid(contup)) if (!HeapTupleIsValid(contup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for conversion %u", conid); elog(ERROR, "cache lookup failed for conversion %u", conid);
}
conform = (Form_pg_conversion) GETSTRUCT(contup); conform = (Form_pg_conversion) GETSTRUCT(contup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2422,35 +2257,16 @@ get_statistics_object_oid(List *names, bool missing_ok)
* for the unqualified statistics object name". * for the unqualified statistics object name".
*/ */
bool bool
StatisticsObjIsVisible(Oid stxid) StatisticsObjIsVisible(Oid relid)
{
return StatisticsObjIsVisibleExt(stxid, NULL);
}
/*
* StatisticsObjIsVisibleExt
* As above, but if the statistics object isn't found and is_missing is
* not NULL, then set *is_missing = true and return false instead of
* throwing an error. (Caller must initialize *is_missing = false.)
*/
static bool
StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
{ {
HeapTuple stxtup; HeapTuple stxtup;
Form_pg_statistic_ext stxform; Form_pg_statistic_ext stxform;
Oid stxnamespace; Oid stxnamespace;
bool visible; bool visible;
stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stxid)); stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(stxtup)) if (!HeapTupleIsValid(stxtup))
{ elog(ERROR, "cache lookup failed for statistics object %u", relid);
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for statistics object %u", stxid);
}
stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup); stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2565,18 +2381,6 @@ get_ts_parser_oid(List *names, bool missing_ok)
*/ */
bool bool
TSParserIsVisible(Oid prsId) TSParserIsVisible(Oid prsId)
{
return TSParserIsVisibleExt(prsId, NULL);
}
/*
* TSParserIsVisibleExt
* As above, but if the parser isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
TSParserIsVisibleExt(Oid prsId, bool *is_missing)
{ {
HeapTuple tup; HeapTuple tup;
Form_pg_ts_parser form; Form_pg_ts_parser form;
@ -2585,14 +2389,7 @@ TSParserIsVisibleExt(Oid prsId, bool *is_missing)
tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId)); tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for text search parser %u", prsId); elog(ERROR, "cache lookup failed for text search parser %u", prsId);
}
form = (Form_pg_ts_parser) GETSTRUCT(tup); form = (Form_pg_ts_parser) GETSTRUCT(tup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2710,18 +2507,6 @@ get_ts_dict_oid(List *names, bool missing_ok)
*/ */
bool bool
TSDictionaryIsVisible(Oid dictId) TSDictionaryIsVisible(Oid dictId)
{
return TSDictionaryIsVisibleExt(dictId, NULL);
}
/*
* TSDictionaryIsVisibleExt
* As above, but if the dictionary isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
{ {
HeapTuple tup; HeapTuple tup;
Form_pg_ts_dict form; Form_pg_ts_dict form;
@ -2730,15 +2515,8 @@ TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId)); tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for text search dictionary %u", elog(ERROR, "cache lookup failed for text search dictionary %u",
dictId); dictId);
}
form = (Form_pg_ts_dict) GETSTRUCT(tup); form = (Form_pg_ts_dict) GETSTRUCT(tup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -2856,18 +2634,6 @@ get_ts_template_oid(List *names, bool missing_ok)
*/ */
bool bool
TSTemplateIsVisible(Oid tmplId) TSTemplateIsVisible(Oid tmplId)
{
return TSTemplateIsVisibleExt(tmplId, NULL);
}
/*
* TSTemplateIsVisibleExt
* As above, but if the template isn't found and is_missing is not NULL,
* then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
{ {
HeapTuple tup; HeapTuple tup;
Form_pg_ts_template form; Form_pg_ts_template form;
@ -2876,14 +2642,7 @@ TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId)); tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for text search template %u", tmplId); elog(ERROR, "cache lookup failed for text search template %u", tmplId);
}
form = (Form_pg_ts_template) GETSTRUCT(tup); form = (Form_pg_ts_template) GETSTRUCT(tup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -3001,18 +2760,6 @@ get_ts_config_oid(List *names, bool missing_ok)
*/ */
bool bool
TSConfigIsVisible(Oid cfgid) TSConfigIsVisible(Oid cfgid)
{
return TSConfigIsVisibleExt(cfgid, NULL);
}
/*
* TSConfigIsVisibleExt
* As above, but if the configuration isn't found and is_missing is not
* NULL, then set *is_missing = true and return false instead of throwing
* an error. (Caller must initialize *is_missing = false.)
*/
static bool
TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
{ {
HeapTuple tup; HeapTuple tup;
Form_pg_ts_config form; Form_pg_ts_config form;
@ -3021,15 +2768,8 @@ TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid)); tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
if (is_missing != NULL)
{
*is_missing = true;
return false;
}
elog(ERROR, "cache lookup failed for text search configuration %u", elog(ERROR, "cache lookup failed for text search configuration %u",
cfgid); cfgid);
}
form = (Form_pg_ts_config) GETSTRUCT(tup); form = (Form_pg_ts_config) GETSTRUCT(tup);
recomputeNamespacePath(); recomputeNamespacePath();
@ -4543,189 +4283,152 @@ fetch_search_path_array(Oid *sarray, int sarray_len)
* condition errors when a query that's scanning a catalog using an MVCC * condition errors when a query that's scanning a catalog using an MVCC
* snapshot uses one of these functions. The underlying IsVisible functions * snapshot uses one of these functions. The underlying IsVisible functions
* always use an up-to-date snapshot and so might see the object as already * always use an up-to-date snapshot and so might see the object as already
* gone when it's still visible to the transaction snapshot. * gone when it's still visible to the transaction snapshot. (There is no race
* condition in the current coding because we don't accept sinval messages
* between the SearchSysCacheExists test and the subsequent lookup.)
*/ */
Datum Datum
pg_table_is_visible(PG_FUNCTION_ARGS) pg_table_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = RelationIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(RelationIsVisible(oid));
} }
Datum Datum
pg_type_is_visible(PG_FUNCTION_ARGS) pg_type_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = TypeIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(TypeIsVisible(oid));
} }
Datum Datum
pg_function_is_visible(PG_FUNCTION_ARGS) pg_function_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = FunctionIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(FunctionIsVisible(oid));
} }
Datum Datum
pg_operator_is_visible(PG_FUNCTION_ARGS) pg_operator_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = OperatorIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(OPEROID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(OperatorIsVisible(oid));
} }
Datum Datum
pg_opclass_is_visible(PG_FUNCTION_ARGS) pg_opclass_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = OpclassIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(CLAOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(OpclassIsVisible(oid));
} }
Datum Datum
pg_opfamily_is_visible(PG_FUNCTION_ARGS) pg_opfamily_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = OpfamilyIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(OPFAMILYOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(OpfamilyIsVisible(oid));
} }
Datum Datum
pg_collation_is_visible(PG_FUNCTION_ARGS) pg_collation_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = CollationIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(COLLOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(CollationIsVisible(oid));
} }
Datum Datum
pg_conversion_is_visible(PG_FUNCTION_ARGS) pg_conversion_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = ConversionIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(CONVOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(ConversionIsVisible(oid));
} }
Datum Datum
pg_statistics_obj_is_visible(PG_FUNCTION_ARGS) pg_statistics_obj_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = StatisticsObjIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(STATEXTOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(StatisticsObjIsVisible(oid));
} }
Datum Datum
pg_ts_parser_is_visible(PG_FUNCTION_ARGS) pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = TSParserIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(TSPARSEROID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(TSParserIsVisible(oid));
} }
Datum Datum
pg_ts_dict_is_visible(PG_FUNCTION_ARGS) pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = TSDictionaryIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(TSDictionaryIsVisible(oid));
} }
Datum Datum
pg_ts_template_is_visible(PG_FUNCTION_ARGS) pg_ts_template_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = TSTemplateIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(TSTEMPLATEOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(TSTemplateIsVisible(oid));
} }
Datum Datum
pg_ts_config_is_visible(PG_FUNCTION_ARGS) pg_ts_config_is_visible(PG_FUNCTION_ARGS)
{ {
Oid oid = PG_GETARG_OID(0); Oid oid = PG_GETARG_OID(0);
bool result;
bool is_missing = false;
result = TSConfigIsVisibleExt(oid, &is_missing); if (!SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(oid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_BOOL(result);
PG_RETURN_BOOL(TSConfigIsVisible(oid));
} }
Datum Datum

View File

@ -1915,16 +1915,15 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_table_priv_string(priv_type_text); mode = convert_table_priv_string(priv_type_text);
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -1942,16 +1941,15 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_table_priv_string(priv_type_text); mode = convert_table_priv_string(priv_type_text);
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -1991,15 +1989,14 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_table_priv_string(priv_type_text); mode = convert_table_priv_string(priv_type_text);
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2137,7 +2134,6 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
char relkind; char relkind;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_sequence_priv_string(priv_type_text); mode = convert_sequence_priv_string(priv_type_text);
@ -2150,10 +2146,7 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
errmsg("\"%s\" is not a sequence", errmsg("\"%s\" is not a sequence",
get_rel_name(sequenceoid)))); get_rel_name(sequenceoid))));
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(sequenceoid, roleid, mode);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2173,7 +2166,6 @@ has_sequence_privilege_id(PG_FUNCTION_ARGS)
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
char relkind; char relkind;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_sequence_priv_string(priv_type_text); mode = convert_sequence_priv_string(priv_type_text);
@ -2186,10 +2178,7 @@ has_sequence_privilege_id(PG_FUNCTION_ARGS)
errmsg("\"%s\" is not a sequence", errmsg("\"%s\" is not a sequence",
get_rel_name(sequenceoid)))); get_rel_name(sequenceoid))));
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(sequenceoid, roleid, mode);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2236,7 +2225,6 @@ has_sequence_privilege_id_id(PG_FUNCTION_ARGS)
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
char relkind; char relkind;
bool is_missing = false;
mode = convert_sequence_priv_string(priv_type_text); mode = convert_sequence_priv_string(priv_type_text);
relkind = get_rel_relkind(sequenceoid); relkind = get_rel_relkind(sequenceoid);
@ -2248,10 +2236,7 @@ has_sequence_privilege_id_id(PG_FUNCTION_ARGS)
errmsg("\"%s\" is not a sequence", errmsg("\"%s\" is not a sequence",
get_rel_name(sequenceoid)))); get_rel_name(sequenceoid))));
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(sequenceoid, roleid, mode);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2360,22 +2345,18 @@ has_any_column_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_column_priv_string(priv_type_text); mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
PG_RETURN_NULL();
/* First check at table level, then examine each column if needed */ /* First check at table level, then examine each column if needed */
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(tableoid, roleid, mode);
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
{ aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
if (is_missing) ACLMASK_ANY);
PG_RETURN_NULL();
aclresult = pg_attribute_aclcheck_all_ext(tableoid, roleid, mode,
ACLMASK_ANY, &is_missing);
if (is_missing)
PG_RETURN_NULL();
}
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2394,22 +2375,18 @@ has_any_column_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_column_priv_string(priv_type_text); mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
PG_RETURN_NULL();
/* First check at table level, then examine each column if needed */ /* First check at table level, then examine each column if needed */
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(tableoid, roleid, mode);
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
{ aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
if (is_missing) ACLMASK_ANY);
PG_RETURN_NULL();
aclresult = pg_attribute_aclcheck_all_ext(tableoid, roleid, mode,
ACLMASK_ANY, &is_missing);
if (is_missing)
PG_RETURN_NULL();
}
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -2454,21 +2431,17 @@ has_any_column_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_column_priv_string(priv_type_text); mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
PG_RETURN_NULL();
/* First check at table level, then examine each column if needed */ /* First check at table level, then examine each column if needed */
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); aclresult = pg_class_aclcheck(tableoid, roleid, mode);
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
{ aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
if (is_missing) ACLMASK_ANY);
PG_RETURN_NULL();
aclresult = pg_attribute_aclcheck_all_ext(tableoid, roleid, mode,
ACLMASK_ANY, &is_missing);
if (is_missing)
PG_RETURN_NULL();
}
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3008,18 +2981,15 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_database_priv_string(priv_type_text); mode = convert_database_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid, if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3037,18 +3007,15 @@ has_database_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_database_priv_string(priv_type_text); mode = convert_database_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid, if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3088,17 +3055,14 @@ has_database_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_database_priv_string(priv_type_text); mode = convert_database_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid, if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3214,18 +3178,15 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_foreign_data_wrapper_priv_string(priv_type_text); mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid, if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3243,18 +3204,15 @@ has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_foreign_data_wrapper_priv_string(priv_type_text); mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid, if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3294,17 +3252,14 @@ has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_foreign_data_wrapper_priv_string(priv_type_text); mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid, if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3414,18 +3369,15 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_function_priv_string(priv_type_text); mode = convert_function_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid, if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3443,18 +3395,15 @@ has_function_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_function_priv_string(priv_type_text); mode = convert_function_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid, if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3494,17 +3443,14 @@ has_function_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_function_priv_string(priv_type_text); mode = convert_function_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid, if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3623,18 +3569,15 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_language_priv_string(priv_type_text); mode = convert_language_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid, if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3652,18 +3595,15 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_language_priv_string(priv_type_text); mode = convert_language_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid, if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3703,17 +3643,14 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_language_priv_string(priv_type_text); mode = convert_language_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid, if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3823,18 +3760,15 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_schema_priv_string(priv_type_text); mode = convert_schema_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid, if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3852,18 +3786,15 @@ has_schema_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_schema_priv_string(priv_type_text); mode = convert_schema_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid, if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -3903,17 +3834,14 @@ has_schema_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_schema_priv_string(priv_type_text); mode = convert_schema_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid, if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4025,18 +3953,15 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_server_priv_string(priv_type_text); mode = convert_server_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid, if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4054,18 +3979,15 @@ has_server_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_server_priv_string(priv_type_text); mode = convert_server_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid, if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4105,17 +4027,14 @@ has_server_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_server_priv_string(priv_type_text); mode = convert_server_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid, if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4225,18 +4144,15 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_tablespace_priv_string(priv_type_text); mode = convert_tablespace_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid, if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4254,18 +4170,15 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_tablespace_priv_string(priv_type_text); mode = convert_tablespace_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid, if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4305,17 +4218,14 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_tablespace_priv_string(priv_type_text); mode = convert_tablespace_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid, if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4424,18 +4334,15 @@ has_type_privilege_name_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = get_role_oid_or_public(NameStr(*username)); roleid = get_role_oid_or_public(NameStr(*username));
mode = convert_type_priv_string(priv_type_text); mode = convert_type_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TypeRelationId, typeoid, if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4453,18 +4360,15 @@ has_type_privilege_id(PG_FUNCTION_ARGS)
Oid roleid; Oid roleid;
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
roleid = GetUserId(); roleid = GetUserId();
mode = convert_type_priv_string(priv_type_text); mode = convert_type_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TypeRelationId, typeoid, if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }
@ -4504,17 +4408,14 @@ has_type_privilege_id_id(PG_FUNCTION_ARGS)
text *priv_type_text = PG_GETARG_TEXT_PP(2); text *priv_type_text = PG_GETARG_TEXT_PP(2);
AclMode mode; AclMode mode;
AclResult aclresult; AclResult aclresult;
bool is_missing = false;
mode = convert_type_priv_string(priv_type_text); mode = convert_type_priv_string(priv_type_text);
aclresult = object_aclcheck_ext(TypeRelationId, typeoid, if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
roleid, mode,
&is_missing);
if (is_missing)
PG_RETURN_NULL(); PG_RETURN_NULL();
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK); PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
} }

View File

@ -7837,23 +7837,14 @@ clear_socket_set(socket_set *sa)
static void static void
add_socket_to_set(socket_set *sa, int fd, int idx) add_socket_to_set(socket_set *sa, int fd, int idx)
{ {
/* See connect_slot() for background on this code. */
#ifdef WIN32
if (sa->fds.fd_count + 1 >= FD_SETSIZE)
{
pg_log_error("too many concurrent database clients for this platform: %d",
sa->fds.fd_count + 1);
exit(1);
}
#else
if (fd < 0 || fd >= FD_SETSIZE) if (fd < 0 || fd >= FD_SETSIZE)
{ {
pg_log_error("socket file descriptor out of range for select(): %d", /*
fd); * Doing a hard exit here is a bit grotty, but it doesn't seem worth
pg_log_error_hint("Try fewer concurrent database clients."); * complicating the API to make it less grotty.
exit(1); */
pg_fatal("too many client connections for select()");
} }
#endif
FD_SET(fd, &sa->fds); FD_SET(fd, &sa->fds);
if (fd > sa->maxfd) if (fd > sa->maxfd)
sa->maxfd = fd; sa->maxfd = fd;

View File

@ -295,41 +295,8 @@ connect_slot(ParallelSlotArray *sa, int slotno, const char *dbname)
slot->connection = connectDatabase(sa->cparams, sa->progname, sa->echo, false, true); slot->connection = connectDatabase(sa->cparams, sa->progname, sa->echo, false, true);
sa->cparams->override_dbname = old_override; sa->cparams->override_dbname = old_override;
/* if (PQsocket(slot->connection) >= FD_SETSIZE)
* POSIX defines FD_SETSIZE as the highest file descriptor acceptable to pg_fatal("too many jobs for this platform");
* FD_SET() and allied macros. Windows defines it as a ceiling on the
* count of file descriptors in the set, not a ceiling on the value of
* each file descriptor; see
* https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
* and
* https://learn.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-fd_set.
* We can't ignore that, because Windows starts file descriptors at a
* higher value, delays reuse, and skips values. With less than ten
* concurrent file descriptors, opened and closed rapidly, one can reach
* file descriptor 1024.
*
* Doing a hard exit here is a bit grotty, but it doesn't seem worth
* complicating the API to make it less grotty.
*/
#ifdef WIN32
if (slotno >= FD_SETSIZE)
{
pg_log_error("too many jobs for this platform: %d", slotno);
exit(1);
}
#else
{
int fd = PQsocket(slot->connection);
if (fd >= FD_SETSIZE)
{
pg_log_error("socket file descriptor out of range for select(): %d",
fd);
pg_log_error_hint("Try fewer jobs.");
exit(1);
}
}
#endif
/* Setup the connection using the supplied command, if any. */ /* Setup the connection using the supplied command, if any. */
if (sa->initcmd) if (sa->initcmd)

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202310141 #define CATALOG_VERSION_NO 202310131
#endif #endif

View File

@ -122,7 +122,7 @@ extern Oid ConversionGetConid(const char *conname);
extern bool ConversionIsVisible(Oid conid); extern bool ConversionIsVisible(Oid conid);
extern Oid get_statistics_object_oid(List *names, bool missing_ok); extern Oid get_statistics_object_oid(List *names, bool missing_ok);
extern bool StatisticsObjIsVisible(Oid stxid); extern bool StatisticsObjIsVisible(Oid relid);
extern Oid get_ts_parser_oid(List *names, bool missing_ok); extern Oid get_ts_parser_oid(List *names, bool missing_ok);
extern bool TSParserIsVisible(Oid prsId); extern bool TSParserIsVisible(Oid prsId);

View File

@ -172,6 +172,8 @@
{ amprocfamily => 'btree/interval_ops', amproclefttype => 'interval', { amprocfamily => 'btree/interval_ops', amproclefttype => 'interval',
amprocrighttype => 'interval', amprocnum => '3', amprocrighttype => 'interval', amprocnum => '3',
amproc => 'in_range(interval,interval,interval,bool,bool)' }, amproc => 'in_range(interval,interval,interval,bool,bool)' },
{ amprocfamily => 'btree/interval_ops', amproclefttype => 'interval',
amprocrighttype => 'interval', amprocnum => '4', amproc => 'btequalimage' },
{ amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr', { amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr',
amprocrighttype => 'macaddr', amprocnum => '1', amproc => 'macaddr_cmp' }, amprocrighttype => 'macaddr', amprocnum => '1', amproc => 'macaddr_cmp' },
{ amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr', { amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr',

View File

@ -50,7 +50,7 @@
opfmethod => 'btree', opfname => 'integer_ops' }, opfmethod => 'btree', opfname => 'integer_ops' },
{ oid => '1977', { oid => '1977',
opfmethod => 'hash', opfname => 'integer_ops' }, opfmethod => 'hash', opfname => 'integer_ops' },
{ oid => '1982', oid_symbol => 'INTERVAL_BTREE_FAM_OID', { oid => '1982',
opfmethod => 'btree', opfname => 'interval_ops' }, opfmethod => 'btree', opfname => 'interval_ops' },
{ oid => '1983', { oid => '1983',
opfmethod => 'hash', opfname => 'interval_ops' }, opfmethod => 'hash', opfname => 'interval_ops' },

View File

@ -239,12 +239,8 @@ extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
/* generic functions */ /* generic function */
extern AclResult object_aclcheck(Oid classid, Oid objectid, extern AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode);
Oid roleid, AclMode mode);
extern AclResult object_aclcheck_ext(Oid classid, Oid objectid,
Oid roleid, AclMode mode,
bool *is_missing);
/* special cases */ /* special cases */
extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
@ -254,9 +250,6 @@ extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
bool *is_missing); bool *is_missing);
extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
AclMode mode, AclMaskHow how); AclMode mode, AclMaskHow how);
extern AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid,
AclMode mode, AclMaskHow how,
bool *is_missing);
extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode); extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid,
AclMode mode, bool *is_missing); AclMode mode, bool *is_missing);

View File

@ -2208,7 +2208,6 @@ ORDER BY 1, 2, 3;
| array_ops | array_ops | anyarray | array_ops | array_ops | anyarray
| float_ops | float4_ops | real | float_ops | float4_ops | real
| float_ops | float8_ops | double precision | float_ops | float8_ops | double precision
| interval_ops | interval_ops | interval
| jsonb_ops | jsonb_ops | jsonb | jsonb_ops | jsonb_ops | jsonb
| multirange_ops | multirange_ops | anymultirange | multirange_ops | multirange_ops | anymultirange
| numeric_ops | numeric_ops | numeric | numeric_ops | numeric_ops | numeric
@ -2217,7 +2216,7 @@ ORDER BY 1, 2, 3;
| record_ops | record_ops | record | record_ops | record_ops | record
| tsquery_ops | tsquery_ops | tsquery | tsquery_ops | tsquery_ops | tsquery
| tsvector_ops | tsvector_ops | tsvector | tsvector_ops | tsvector_ops | tsvector
(16 rows) (15 rows)
-- **************** pg_index **************** -- **************** pg_index ****************
-- Look for illegal values in pg_index fields. -- Look for illegal values in pg_index fields.