diff options
| author | Robert Haas | 2011-04-01 15:28:28 +0000 |
|---|---|---|
| committer | Robert Haas | 2011-04-01 15:28:28 +0000 |
| commit | 50533a6dc515cc3182f52838275c9d2a1f587604 (patch) | |
| tree | 16489ffa766ce9d3134888d11466c228dbf8d49c /src/backend | |
| parent | 7fcc75dd26ff0fee0b02f1b8b4215c298ca974ca (diff) | |
Support comments on FOREIGN DATA WRAPPER and SERVER objects.
This mostly involves making it work with the objectaddress.c framework,
which does most of the heavy lifting. In that vein, change
GetForeignDataWrapperOidByName to get_foreign_data_wrapper_oid and
GetForeignServerOidByName to get_foreign_server_oid, to match the
pattern we use for other object types.
Robert Haas and Shigeru Hanada
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/catalog/aclchk.c | 31 | ||||
| -rw-r--r-- | src/backend/catalog/objectaddress.c | 33 | ||||
| -rw-r--r-- | src/backend/commands/foreigncmds.c | 4 | ||||
| -rw-r--r-- | src/backend/foreign/foreign.c | 82 | ||||
| -rw-r--r-- | src/backend/parser/gram.y | 13 | ||||
| -rw-r--r-- | src/backend/utils/adt/acl.c | 4 |
6 files changed, 114 insertions, 53 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 48fa6d48b7f..aa3d59d4c9a 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -683,7 +683,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) foreach(cell, objnames) { char *fdwname = strVal(lfirst(cell)); - Oid fdwid = GetForeignDataWrapperOidByName(fdwname, false); + Oid fdwid = get_foreign_data_wrapper_oid(fdwname, false); objects = lappend_oid(objects, fdwid); } @@ -692,7 +692,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) foreach(cell, objnames) { char *srvname = strVal(lfirst(cell)); - Oid srvid = GetForeignServerOidByName(srvname, false); + Oid srvid = get_foreign_server_oid(srvname, false); objects = lappend_oid(objects, srvid); } @@ -4589,6 +4589,33 @@ pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid) } /* + * Ownership check for a foreign-data wrapper (specified by OID). + */ +bool +pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid) +{ + HeapTuple tuple; + Oid ownerId; + + /* Superusers bypass all permission checking. */ + if (superuser_arg(roleid)) + return true; + + tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(srv_oid)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("foreign-data wrapper with OID %u does not exist", + srv_oid))); + + ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner; + + ReleaseSysCache(tuple); + + return has_privs_of_role(roleid, ownerId); +} + +/* * Ownership check for a foreign server (specified by OID). */ bool diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 880b95df020..0d21d310a65 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -30,6 +30,8 @@ #include "catalog/pg_conversion.h" #include "catalog/pg_database.h" #include "catalog/pg_extension.h" +#include "catalog/pg_foreign_data_wrapper.h" +#include "catalog/pg_foreign_server.h" #include "catalog/pg_language.h" #include "catalog/pg_largeobject.h" #include "catalog/pg_largeobject_metadata.h" @@ -52,6 +54,7 @@ #include "commands/proclang.h" #include "commands/tablespace.h" #include "commands/trigger.h" +#include "foreign/foreign.h" #include "libpq/be-fsstubs.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -140,6 +143,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs, case OBJECT_ROLE: case OBJECT_SCHEMA: case OBJECT_LANGUAGE: + case OBJECT_FDW: + case OBJECT_FOREIGN_SERVER: address = get_object_address_unqualified(objtype, objname); break; case OBJECT_TYPE: @@ -295,6 +300,12 @@ get_object_address_unqualified(ObjectType objtype, List *qualname) case OBJECT_LANGUAGE: msg = gettext_noop("language name cannot be qualified"); break; + case OBJECT_FDW: + msg = gettext_noop("foreign-data wrapper name cannot be qualified"); + break; + case OBJECT_FOREIGN_SERVER: + msg = gettext_noop("server name cannot be qualified"); + break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); msg = NULL; /* placate compiler */ @@ -340,6 +351,16 @@ get_object_address_unqualified(ObjectType objtype, List *qualname) address.objectId = get_language_oid(name, false); address.objectSubId = 0; break; + case OBJECT_FDW: + address.classId = ForeignDataWrapperRelationId; + address.objectId = get_foreign_data_wrapper_oid(name, false); + address.objectSubId = 0; + break; + case OBJECT_FOREIGN_SERVER: + address.classId = ForeignServerRelationId; + address.objectId = get_foreign_server_oid(name, false); + address.objectSubId = 0; + break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ @@ -655,6 +676,12 @@ object_exists(ObjectAddress address) case CastRelationId: indexoid = CastOidIndexId; break; + case ForeignDataWrapperRelationId: + cache = FOREIGNDATAWRAPPEROID; + break; + case ForeignServerRelationId: + cache = FOREIGNSERVEROID; + break; case TSParserRelationId: cache = TSPARSEROID; break; @@ -758,6 +785,11 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION, NameListToString(objname)); break; + case OBJECT_FDW: + if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid)) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FDW, + NameListToString(objname)); + break; case OBJECT_FOREIGN_SERVER: if (!pg_foreign_server_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, @@ -838,7 +870,6 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, errmsg("must have CREATEROLE privilege"))); } break; - case OBJECT_FDW: case OBJECT_TSPARSER: case OBJECT_TSTEMPLATE: /* We treat these object types as being owned by superusers */ diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index acd40c1f4e9..13d6d882f88 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -686,7 +686,7 @@ RemoveForeignDataWrapper(DropFdwStmt *stmt) Oid fdwId; ObjectAddress object; - fdwId = GetForeignDataWrapperOidByName(stmt->fdwname, true); + fdwId = get_foreign_data_wrapper_oid(stmt->fdwname, true); if (!superuser()) ereport(ERROR, @@ -959,7 +959,7 @@ RemoveForeignServer(DropForeignServerStmt *stmt) Oid srvId; ObjectAddress object; - srvId = GetForeignServerOidByName(stmt->servername, true); + srvId = get_foreign_server_oid(stmt->servername, true); if (!OidIsValid(srvId)) { diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index 44cd18177c6..cda90a6b0cb 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -79,26 +79,6 @@ GetForeignDataWrapper(Oid fdwid) } -/* - * GetForeignDataWrapperOidByName - look up the foreign-data wrapper - * OID by name. - */ -Oid -GetForeignDataWrapperOidByName(const char *fdwname, bool missing_ok) -{ - Oid fdwId; - - fdwId = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(fdwname)); - - if (!OidIsValid(fdwId) && !missing_ok) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("foreign-data wrapper \"%s\" does not exist", - fdwname))); - - return fdwId; -} - /* * GetForeignDataWrapperByName - look up the foreign-data wrapper @@ -107,7 +87,7 @@ GetForeignDataWrapperOidByName(const char *fdwname, bool missing_ok) ForeignDataWrapper * GetForeignDataWrapperByName(const char *fdwname, bool missing_ok) { - Oid fdwId = GetForeignDataWrapperOidByName(fdwname, missing_ok); + Oid fdwId = get_foreign_data_wrapper_oid(fdwname, missing_ok); if (!OidIsValid(fdwId)) return NULL; @@ -172,31 +152,12 @@ GetForeignServer(Oid serverid) /* - * GetForeignServerByName - look up the foreign server oid by name. - */ -Oid -GetForeignServerOidByName(const char *srvname, bool missing_ok) -{ - Oid serverid; - - serverid = GetSysCacheOid1(FOREIGNSERVERNAME, CStringGetDatum(srvname)); - - if (!OidIsValid(serverid) && !missing_ok) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("server \"%s\" does not exist", srvname))); - - return serverid; -} - - -/* * GetForeignServerByName - look up the foreign server definition by name. */ ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok) { - Oid serverid = GetForeignServerOidByName(srvname, missing_ok); + Oid serverid = get_foreign_server_oid(srvname, missing_ok); if (!OidIsValid(serverid)) return NULL; @@ -538,3 +499,42 @@ postgresql_fdw_validator(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } + +/* + * get_foreign_data_wrapper_oid - given a FDW name, look up the OID + * + * If missing_ok is false, throw an error if name not found. If true, just + * return InvalidOid. + */ +Oid +get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok) +{ + Oid oid; + + oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(fdwname)); + if (!OidIsValid(oid) && !missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("foreign-data wrapper \"%s\" does not exist", + fdwname))); + return oid; +} + +/* + * get_foreign_server_oid - given a FDW name, look up the OID + * + * If missing_ok is false, throw an error if name not found. If true, just + * return InvalidOid. + */ +Oid +get_foreign_server_oid(const char *servername, bool missing_ok) +{ + Oid oid; + + oid = GetSysCacheOid1(FOREIGNSERVERNAME, CStringGetDatum(servername)); + if (!OidIsValid(oid) && !missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("server \"%s\" does not exist", servername))); + return oid; +} diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 27fdccae5b8..a22ab66ae59 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -4787,11 +4787,12 @@ opt_restart_seqs: * the object associated with the comment. The form of the statement is: * * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | - * COLLATION | CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT | - * CAST | COLUMN | SCHEMA | TABLESPACE | EXTENSION | ROLE | - * TEXT SEARCH PARSER | TEXT SEARCH DICTIONARY | - * TEXT SEARCH TEMPLATE | TEXT SEARCH CONFIGURATION | - * FOREIGN TABLE ] <objname> | + * COLLATION | CONVERSION | LANGUAGE | OPERATOR CLASS | + * LARGE OBJECT | CAST | COLUMN | SCHEMA | TABLESPACE | + * EXTENSION | ROLE | TEXT SEARCH PARSER | + * TEXT SEARCH DICTIONARY | TEXT SEARCH TEMPLATE | + * TEXT SEARCH CONFIGURATION | FOREIGN TABLE | + * FOREIGN DATA WRAPPER | SERVER ] <objname> | * AGGREGATE <aggname> (arg1, ...) | * FUNCTION <funcname> (arg1, arg2, ...) | * OPERATOR <op> (leftoperand_typ, rightoperand_typ) | @@ -4971,6 +4972,8 @@ comment_type: | EXTENSION { $$ = OBJECT_EXTENSION; } | ROLE { $$ = OBJECT_ROLE; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } + | SERVER { $$ = OBJECT_FOREIGN_SERVER; } + | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } ; comment_text: diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 691ba3bd95a..2f27018b256 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -3162,7 +3162,7 @@ convert_foreign_data_wrapper_name(text *fdwname) { char *fdwstr = text_to_cstring(fdwname); - return GetForeignDataWrapperOidByName(fdwstr, false); + return get_foreign_data_wrapper_oid(fdwstr, false); } /* @@ -3928,7 +3928,7 @@ convert_server_name(text *servername) { char *serverstr = text_to_cstring(servername); - return GetForeignServerOidByName(serverstr, false); + return get_foreign_server_oid(serverstr, false); } /* |
