mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Arrange for the pg_foo_is_visible and has_foo_privilege families of functions
to return NULL, instead of erroring out, if the target object is specified by OID and we can't find that OID in the catalogs. Since these functions operate internally on SnapshotNow rules, there is a race condition when using them in user queries: the query's MVCC snapshot might "see" a catalog row that's already committed dead, leading to a failure when the inquiry function is applied. Returning NULL should generally provide more convenient behavior. This issue has been complained of before, and in particular we are now seeing it in the regression tests due to another recent patch.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.142 2008/09/09 18:58:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.143 2008/12/15 18:09:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1361,7 +1361,9 @@ convert_priv_string(text *priv_type_text)
|
||||
* user name, user OID, or implicit user = current_user.
|
||||
*
|
||||
* The result is a boolean value: true if user has the indicated
|
||||
* privilege, false if not.
|
||||
* privilege, false if not. The variants that take a relation OID
|
||||
* return NULL if the OID doesn't exist (rather than failing, as
|
||||
* they did before Postgres 8.4).
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1432,6 +1434,11 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
|
||||
roleid = get_roleid_checked(NameStr(*username));
|
||||
mode = convert_table_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(RELOID,
|
||||
ObjectIdGetDatum(tableoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1455,6 +1462,11 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
|
||||
roleid = GetUserId();
|
||||
mode = convert_table_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(RELOID,
|
||||
ObjectIdGetDatum(tableoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1499,6 +1511,11 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
|
||||
mode = convert_table_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(RELOID,
|
||||
ObjectIdGetDatum(tableoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_class_aclcheck(tableoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1587,7 +1604,7 @@ convert_table_priv_string(text *priv_type_text)
|
||||
* user name, user OID, or implicit user = current_user.
|
||||
*
|
||||
* The result is a boolean value: true if user has the indicated
|
||||
* privilege, false if not.
|
||||
* privilege, false if not, or NULL if object doesn't exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1658,6 +1675,11 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
|
||||
roleid = get_roleid_checked(NameStr(*username));
|
||||
mode = convert_database_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(DATABASEOID,
|
||||
ObjectIdGetDatum(databaseoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1681,6 +1703,11 @@ has_database_privilege_id(PG_FUNCTION_ARGS)
|
||||
roleid = GetUserId();
|
||||
mode = convert_database_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(DATABASEOID,
|
||||
ObjectIdGetDatum(databaseoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1725,6 +1752,11 @@ has_database_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
|
||||
mode = convert_database_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(DATABASEOID,
|
||||
ObjectIdGetDatum(databaseoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1798,7 +1830,7 @@ convert_database_priv_string(text *priv_type_text)
|
||||
* user name, user OID, or implicit user = current_user.
|
||||
*
|
||||
* The result is a boolean value: true if user has the indicated
|
||||
* privilege, false if not.
|
||||
* privilege, false if not, or NULL if object doesn't exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1869,6 +1901,11 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
|
||||
roleid = get_roleid_checked(NameStr(*username));
|
||||
mode = convert_function_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(PROCOID,
|
||||
ObjectIdGetDatum(functionoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1892,6 +1929,11 @@ has_function_privilege_id(PG_FUNCTION_ARGS)
|
||||
roleid = GetUserId();
|
||||
mode = convert_function_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(PROCOID,
|
||||
ObjectIdGetDatum(functionoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1936,6 +1978,11 @@ has_function_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
|
||||
mode = convert_function_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(PROCOID,
|
||||
ObjectIdGetDatum(functionoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -1996,7 +2043,7 @@ convert_function_priv_string(text *priv_type_text)
|
||||
* user name, user OID, or implicit user = current_user.
|
||||
*
|
||||
* The result is a boolean value: true if user has the indicated
|
||||
* privilege, false if not.
|
||||
* privilege, false if not, or NULL if object doesn't exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2067,6 +2114,11 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
|
||||
roleid = get_roleid_checked(NameStr(*username));
|
||||
mode = convert_language_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(LANGOID,
|
||||
ObjectIdGetDatum(languageoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_language_aclcheck(languageoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -2090,6 +2142,11 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
|
||||
roleid = GetUserId();
|
||||
mode = convert_language_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(LANGOID,
|
||||
ObjectIdGetDatum(languageoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_language_aclcheck(languageoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -2134,6 +2191,11 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
|
||||
mode = convert_language_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(LANGOID,
|
||||
ObjectIdGetDatum(languageoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_language_aclcheck(languageoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -2194,7 +2256,7 @@ convert_language_priv_string(text *priv_type_text)
|
||||
* user name, user OID, or implicit user = current_user.
|
||||
*
|
||||
* The result is a boolean value: true if user has the indicated
|
||||
* privilege, false if not.
|
||||
* privilege, false if not, or NULL if object doesn't exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2265,6 +2327,11 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
|
||||
roleid = get_roleid_checked(NameStr(*username));
|
||||
mode = convert_schema_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(NAMESPACEOID,
|
||||
ObjectIdGetDatum(schemaoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -2288,6 +2355,11 @@ has_schema_privilege_id(PG_FUNCTION_ARGS)
|
||||
roleid = GetUserId();
|
||||
mode = convert_schema_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(NAMESPACEOID,
|
||||
ObjectIdGetDatum(schemaoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
@ -2332,6 +2404,11 @@ has_schema_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
|
||||
mode = convert_schema_priv_string(priv_type_text);
|
||||
|
||||
if (!SearchSysCacheExists(NAMESPACEOID,
|
||||
ObjectIdGetDatum(schemaoid),
|
||||
0, 0, 0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
|
||||
|
||||
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
|
||||
|
Reference in New Issue
Block a user