mirror of
https://github.com/postgres/postgres.git
synced 2025-07-21 00:01:45 -04:00
Compare commits
4 Commits
22655aa231
...
5f27b5f848
Author | SHA1 | Date | |
---|---|---|---|
|
5f27b5f848 | ||
|
90ebcc32d9 | ||
|
fcdd6689d0 | ||
|
403ac226dd |
@ -31,6 +31,7 @@
|
|||||||
#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"
|
||||||
@ -338,10 +339,20 @@ 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,
|
||||||
|
@ -13,6 +13,27 @@
|
|||||||
* 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"
|
||||||
@ -139,6 +160,9 @@ 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,
|
||||||
@ -151,10 +175,12 @@ 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(Oid nsp_oid, Oid roleid,
|
static AclMode pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid,
|
||||||
AclMode mask, AclMaskHow how);
|
AclMode mask, AclMaskHow how,
|
||||||
static AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
|
bool *is_missing);
|
||||||
AclMode mask, AclMaskHow how);
|
static AclMode pg_type_aclmask_ext(Oid type_oid, Oid roleid,
|
||||||
|
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,
|
||||||
@ -3064,6 +3090,18 @@ 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;
|
||||||
@ -3077,9 +3115,11 @@ object_aclmask(Oid classid, Oid objectid, Oid roleid,
|
|||||||
switch (classid)
|
switch (classid)
|
||||||
{
|
{
|
||||||
case NamespaceRelationId:
|
case NamespaceRelationId:
|
||||||
return pg_namespace_aclmask(objectid, roleid, mask, how);
|
return pg_namespace_aclmask_ext(objectid, roleid, mask, how,
|
||||||
|
is_missing);
|
||||||
case TypeRelationId:
|
case TypeRelationId:
|
||||||
return pg_type_aclmask(objectid, roleid, mask, how);
|
return pg_type_aclmask_ext(objectid, roleid, mask, how,
|
||||||
|
is_missing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Even more special cases */
|
/* Even more special cases */
|
||||||
@ -3092,16 +3132,26 @@ object_aclmask(Oid classid, Oid objectid, Oid roleid,
|
|||||||
return mask;
|
return mask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the objects's ACL from its catalog
|
* Get the object'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))
|
||||||
ereport(ERROR,
|
{
|
||||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
if (is_missing != NULL)
|
||||||
errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
|
{
|
||||||
|
/* return "no privileges" instead of throwing an error */
|
||||||
|
*is_missing = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("%s with OID %u does not exist",
|
||||||
|
get_object_class_descr(classid), objectid)));
|
||||||
|
}
|
||||||
|
|
||||||
ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
|
ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
|
||||||
tuple,
|
tuple,
|
||||||
@ -3149,10 +3199,7 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine for examining a user's privileges for a column
|
* Routine for examining a user's privileges for a column, with is_missing
|
||||||
*
|
|
||||||
* 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,
|
||||||
@ -3226,15 +3273,24 @@ 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). We prefer to report "no
|
* happen if we don't have lock on the relation). Treat that similarly to
|
||||||
* privileges" rather than failing in such a case, so as to avoid unwanted
|
* not finding the attribute entry.
|
||||||
* 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);
|
||||||
return 0;
|
if (is_missing != NULL)
|
||||||
|
{
|
||||||
|
/* return "no privileges" instead of throwing an error */
|
||||||
|
*is_missing = true;
|
||||||
|
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);
|
||||||
|
|
||||||
@ -3267,10 +3323,7 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine for examining a user's privileges for a table
|
* Routine for examining a user's privileges for a table, with is_missing
|
||||||
*
|
|
||||||
* 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,
|
||||||
@ -3585,11 +3638,12 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine for examining a user's privileges for a namespace
|
* Routine for examining a user's privileges for a namespace, with is_missing
|
||||||
*/
|
*/
|
||||||
static AclMode
|
static AclMode
|
||||||
pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
|
pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid,
|
||||||
AclMode mask, AclMaskHow how)
|
AclMode mask, AclMaskHow how,
|
||||||
|
bool *is_missing)
|
||||||
{
|
{
|
||||||
AclMode result;
|
AclMode result;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
@ -3623,8 +3677,8 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
|
|||||||
*/
|
*/
|
||||||
if (isTempNamespace(nsp_oid))
|
if (isTempNamespace(nsp_oid))
|
||||||
{
|
{
|
||||||
if (object_aclcheck(DatabaseRelationId, MyDatabaseId, roleid,
|
if (object_aclcheck_ext(DatabaseRelationId, MyDatabaseId, roleid,
|
||||||
ACL_CREATE_TEMP) == ACLCHECK_OK)
|
ACL_CREATE_TEMP, is_missing) == ACLCHECK_OK)
|
||||||
return mask & ACL_ALL_RIGHTS_SCHEMA;
|
return mask & ACL_ALL_RIGHTS_SCHEMA;
|
||||||
else
|
else
|
||||||
return mask & ACL_USAGE;
|
return mask & ACL_USAGE;
|
||||||
@ -3635,9 +3689,18 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
|
|||||||
*/
|
*/
|
||||||
tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
|
tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
ereport(ERROR,
|
{
|
||||||
(errcode(ERRCODE_UNDEFINED_SCHEMA),
|
if (is_missing != NULL)
|
||||||
errmsg("schema with OID %u does not exist", nsp_oid)));
|
{
|
||||||
|
/* return "no privileges" instead of throwing an error */
|
||||||
|
*is_missing = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_SCHEMA),
|
||||||
|
errmsg("schema with OID %u does not exist", nsp_oid)));
|
||||||
|
}
|
||||||
|
|
||||||
ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
|
ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
|
||||||
|
|
||||||
@ -3677,20 +3740,20 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine for examining a user's privileges for a type.
|
* Routine for examining a user's privileges for a type, with is_missing
|
||||||
*/
|
*/
|
||||||
static AclMode
|
static AclMode
|
||||||
pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
|
pg_type_aclmask_ext(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;
|
||||||
@ -3700,10 +3763,19 @@ pg_type_aclmask(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))
|
||||||
ereport(ERROR,
|
{
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
if (is_missing != NULL)
|
||||||
errmsg("type with OID %u does not exist",
|
{
|
||||||
type_oid)));
|
/* 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",
|
||||||
|
type_oid)));
|
||||||
|
}
|
||||||
typeForm = (Form_pg_type) GETSTRUCT(tuple);
|
typeForm = (Form_pg_type) GETSTRUCT(tuple);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3717,9 +3789,20 @@ pg_type_aclmask(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3759,7 +3842,20 @@ pg_type_aclmask(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)
|
||||||
{
|
{
|
||||||
if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
|
return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
@ -3784,10 +3880,8 @@ 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,
|
||||||
@ -3822,23 +3916,47 @@ 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 check number of attributes. As in
|
* Must fetch pg_class row to get owner ID and number of attributes.
|
||||||
* 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))
|
||||||
return ACLCHECK_NO_PRIV;
|
{
|
||||||
|
if (is_missing != NULL)
|
||||||
|
{
|
||||||
|
/* return "no privileges" instead of throwing an error */
|
||||||
|
*is_missing = true;
|
||||||
|
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);
|
||||||
@ -3852,11 +3970,20 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
|
|||||||
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;
|
||||||
|
|
||||||
@ -3867,16 +3994,27 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
|
|||||||
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 (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
|
if (isNull)
|
||||||
attmask = 0;
|
attmask = 0;
|
||||||
else
|
else
|
||||||
attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
|
{
|
||||||
mode, ACLMASK_ANY);
|
/* detoast column's ACL if necessary */
|
||||||
|
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);
|
||||||
|
|
||||||
@ -3911,10 +4049,8 @@ 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,
|
||||||
|
@ -183,6 +183,19 @@ 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);
|
||||||
@ -691,6 +704,18 @@ 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;
|
||||||
@ -699,7 +724,14 @@ RelationIsVisible(Oid relid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -799,6 +831,18 @@ 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;
|
||||||
@ -807,7 +851,14 @@ TypeIsVisible(Oid typid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -1436,6 +1487,18 @@ 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;
|
||||||
@ -1444,7 +1507,14 @@ FunctionIsVisible(Oid funcid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -1770,6 +1840,18 @@ 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;
|
||||||
@ -1778,7 +1860,14 @@ OperatorIsVisible(Oid oprid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -1856,6 +1945,18 @@ 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;
|
||||||
@ -1864,7 +1965,14 @@ OpclassIsVisible(Oid opcid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -1939,6 +2047,18 @@ 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;
|
||||||
@ -1947,7 +2067,14 @@ OpfamilyIsVisible(Oid opfid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2071,6 +2198,18 @@ 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;
|
||||||
@ -2079,7 +2218,14 @@ CollationIsVisible(Oid collid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2154,6 +2300,18 @@ 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;
|
||||||
@ -2162,7 +2320,14 @@ ConversionIsVisible(Oid conid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2257,16 +2422,35 @@ 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 relid)
|
StatisticsObjIsVisible(Oid stxid)
|
||||||
|
{
|
||||||
|
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(relid));
|
stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stxid));
|
||||||
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();
|
||||||
@ -2381,6 +2565,18 @@ 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;
|
||||||
@ -2389,7 +2585,14 @@ TSParserIsVisible(Oid prsId)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2507,6 +2710,18 @@ 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;
|
||||||
@ -2515,8 +2730,15 @@ TSDictionaryIsVisible(Oid dictId)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2634,6 +2856,18 @@ 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;
|
||||||
@ -2642,7 +2876,14 @@ TSTemplateIsVisible(Oid tmplId)
|
|||||||
|
|
||||||
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();
|
||||||
@ -2760,6 +3001,18 @@ 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;
|
||||||
@ -2768,8 +3021,15 @@ TSConfigIsVisible(Oid cfgid)
|
|||||||
|
|
||||||
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();
|
||||||
@ -4283,152 +4543,189 @@ 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. (There is no race
|
* gone when it's still visible to the transaction snapshot.
|
||||||
* 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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(oid)))
|
result = RelationIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(oid)))
|
result = TypeIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(oid)))
|
result = FunctionIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(OPEROID, ObjectIdGetDatum(oid)))
|
result = OperatorIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(CLAOID, ObjectIdGetDatum(oid)))
|
result = OpclassIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(OPFAMILYOID, ObjectIdGetDatum(oid)))
|
result = OpfamilyIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(COLLOID, ObjectIdGetDatum(oid)))
|
result = CollationIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(CONVOID, ObjectIdGetDatum(oid)))
|
result = ConversionIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(STATEXTOID, ObjectIdGetDatum(oid)))
|
result = StatisticsObjIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TSPARSEROID, ObjectIdGetDatum(oid)))
|
result = TSParserIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(oid)))
|
result = TSDictionaryIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TSTEMPLATEOID, ObjectIdGetDatum(oid)))
|
result = TSTemplateIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(oid)))
|
result = TSConfigIsVisibleExt(oid, &is_missing);
|
||||||
|
|
||||||
|
if (is_missing)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
PG_RETURN_BOOL(result);
|
||||||
PG_RETURN_BOOL(TSConfigIsVisible(oid));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
|
@ -1915,14 +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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
PG_RETURN_NULL();
|
|
||||||
|
|
||||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -1941,14 +1942,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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
PG_RETURN_NULL();
|
|
||||||
|
|
||||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -1989,13 +1991,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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
PG_RETURN_NULL();
|
|
||||||
|
|
||||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -2134,6 +2137,7 @@ 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);
|
||||||
@ -2146,7 +2150,10 @@ 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(sequenceoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing);
|
||||||
|
|
||||||
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -2166,6 +2173,7 @@ 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);
|
||||||
@ -2178,7 +2186,10 @@ 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(sequenceoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing);
|
||||||
|
|
||||||
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -2225,6 +2236,7 @@ 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);
|
||||||
@ -2236,7 +2248,10 @@ 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(sequenceoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(sequenceoid, roleid, mode, &is_missing);
|
||||||
|
|
||||||
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -2345,18 +2360,22 @@ 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(tableoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
|
{
|
||||||
ACLMASK_ANY);
|
if (is_missing)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@ -2375,18 +2394,22 @@ 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(tableoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
|
{
|
||||||
ACLMASK_ANY);
|
if (is_missing)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@ -2431,17 +2454,21 @@ 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(tableoid, roleid, mode);
|
aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclresult = pg_attribute_aclcheck_all(tableoid, roleid, mode,
|
{
|
||||||
ACLMASK_ANY);
|
if (is_missing)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@ -2981,14 +3008,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
|
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3007,14 +3037,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
|
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3055,13 +3088,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
|
aclresult = object_aclcheck_ext(DatabaseRelationId, databaseoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(DatabaseRelationId, databaseoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3178,14 +3214,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
|
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3204,14 +3243,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
|
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3252,13 +3294,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)))
|
aclresult = object_aclcheck_ext(ForeignDataWrapperRelationId, fdwid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdwid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3369,14 +3414,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
|
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3395,14 +3443,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
|
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3443,13 +3494,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
|
aclresult = object_aclcheck_ext(ProcedureRelationId, functionoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ProcedureRelationId, functionoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3569,14 +3623,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
|
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3595,14 +3652,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
|
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3643,13 +3703,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
|
aclresult = object_aclcheck_ext(LanguageRelationId, languageoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(LanguageRelationId, languageoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3760,14 +3823,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
|
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3786,14 +3852,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
|
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3834,13 +3903,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
|
aclresult = object_aclcheck_ext(NamespaceRelationId, schemaoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(NamespaceRelationId, schemaoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3953,14 +4025,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
|
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -3979,14 +4054,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
|
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4027,13 +4105,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)))
|
aclresult = object_aclcheck_ext(ForeignServerRelationId, serverid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(ForeignServerRelationId, serverid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4144,14 +4225,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
|
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4170,14 +4254,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
|
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4218,13 +4305,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid)))
|
aclresult = object_aclcheck_ext(TableSpaceRelationId, tablespaceoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TableSpaceRelationId, tablespaceoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4334,14 +4424,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
|
aclresult = object_aclcheck_ext(TypeRelationId, typeoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4360,14 +4453,17 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
|
aclresult = object_aclcheck_ext(TypeRelationId, typeoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
@ -4408,13 +4504,16 @@ 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);
|
||||||
|
|
||||||
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid)))
|
aclresult = object_aclcheck_ext(TypeRelationId, typeoid,
|
||||||
PG_RETURN_NULL();
|
roleid, mode,
|
||||||
|
&is_missing);
|
||||||
|
|
||||||
aclresult = object_aclcheck(TypeRelationId, typeoid, roleid, mode);
|
if (is_missing)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||||
}
|
}
|
||||||
|
@ -7837,14 +7837,23 @@ 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",
|
||||||
* Doing a hard exit here is a bit grotty, but it doesn't seem worth
|
fd);
|
||||||
* complicating the API to make it less grotty.
|
pg_log_error_hint("Try fewer concurrent database clients.");
|
||||||
*/
|
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;
|
||||||
|
@ -295,8 +295,41 @@ 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)
|
/*
|
||||||
pg_fatal("too many jobs for this platform");
|
* POSIX defines FD_SETSIZE as the highest file descriptor acceptable to
|
||||||
|
* 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)
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202310131
|
#define CATALOG_VERSION_NO 202310141
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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 relid);
|
extern bool StatisticsObjIsVisible(Oid stxid);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -172,8 +172,6 @@
|
|||||||
{ 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',
|
||||||
|
@ -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 => '1982', oid_symbol => 'INTERVAL_BTREE_FAM_OID',
|
||||||
opfmethod => 'btree', opfname => 'interval_ops' },
|
opfmethod => 'btree', opfname => 'interval_ops' },
|
||||||
{ oid => '1983',
|
{ oid => '1983',
|
||||||
opfmethod => 'hash', opfname => 'interval_ops' },
|
opfmethod => 'hash', opfname => 'interval_ops' },
|
||||||
|
@ -239,8 +239,12 @@ 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 function */
|
/* generic functions */
|
||||||
extern AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode);
|
extern AclResult object_aclcheck(Oid classid, Oid objectid,
|
||||||
|
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,
|
||||||
@ -250,6 +254,9 @@ 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);
|
||||||
|
@ -2208,6 +2208,7 @@ 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
|
||||||
@ -2216,7 +2217,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
|
||||||
(15 rows)
|
(16 rows)
|
||||||
|
|
||||||
-- **************** pg_index ****************
|
-- **************** pg_index ****************
|
||||||
-- Look for illegal values in pg_index fields.
|
-- Look for illegal values in pg_index fields.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user