提交 7ebc17ad 编写于 作者: H Heikki Linnakangas

Refactor DROP PROTOCOL command.

The handling of DROP commands for various objects was refactored in
PostgreSQL 9.2, to reducate code duplication (commit 82a4a777). This
commit changes DROP PROTOCOL command handling to follow that model. No
user-visible changes.
上级 1c35fe0e
......@@ -868,7 +868,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *ptcname = strVal(lfirst(cell));
Oid ptcid = LookupExtProtocolOid(ptcname, false);
Oid ptcid = get_extprotocol_oid(ptcname, false);
objects = lappend_oid(objects, ptcid);
}
......
......@@ -28,6 +28,7 @@
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_extprotocol.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_language.h"
......@@ -239,6 +240,16 @@ static ObjectPropertyType ObjectProperty[] =
TYPEOID,
Anum_pg_type_typnamespace
}
/* GPDB additions */
,
{
ExtprotocolRelationId,
ExtprotocolOidIndexId,
-1,
InvalidAttrNumber
},
};
static ObjectAddress get_object_address_unqualified(ObjectType objtype,
......@@ -331,6 +342,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
case OBJECT_LANGUAGE:
case OBJECT_FDW:
case OBJECT_FOREIGN_SERVER:
case OBJECT_EXTPROTOCOL:
address = get_object_address_unqualified(objtype,
objname, missing_ok);
break;
......@@ -562,6 +574,9 @@ get_object_address_unqualified(ObjectType objtype,
case OBJECT_FOREIGN_SERVER:
msg = gettext_noop("server name cannot be qualified");
break;
case OBJECT_EXTPROTOCOL:
msg = gettext_noop("protocol name cannot be qualified");
break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
msg = NULL; /* placate compiler */
......@@ -617,6 +632,11 @@ get_object_address_unqualified(ObjectType objtype,
address.objectId = get_foreign_server_oid(name, missing_ok);
address.objectSubId = 0;
break;
case OBJECT_EXTPROTOCOL:
address.classId = ExtprotocolRelationId;
address.objectId = get_extprotocol_oid(name, missing_ok);
address.objectSubId = 0;
break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
/* placate compiler, which doesn't know elog won't return */
......@@ -1074,6 +1094,11 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
errmsg("must have CREATEROLE privilege")));
}
break;
case OBJECT_EXTPROTOCOL:
if (!pg_extprotocol_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTPROTOCOL,
NameListToString(objname));
break;
case OBJECT_TSPARSER:
case OBJECT_TSTEMPLATE:
case OBJECT_RESQUEUE:
......
......@@ -182,40 +182,6 @@ ExtProtocolCreate(const char *protocolName,
return protOid;
}
void
ExtProtocolDeleteByOid(Oid protOid)
{
Relation rel;
ScanKeyData skey;
SysScanDesc scan;
HeapTuple tup;
bool found = false;
/*
* Search pg_extprotocol.
*/
rel = heap_open(ExtprotocolRelationId, RowExclusiveLock);
ScanKeyInit(&skey,
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(protOid));
scan = systable_beginscan(rel, ExtprotocolOidIndexId, true,
SnapshotNow, 1, &skey);
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
simple_heap_delete(rel, &tup->t_self);
found = true;
}
systable_endscan(scan);
if (!found)
elog(ERROR, "protocol %u could not be found", protOid);
heap_close(rel, NoLock);
}
/*
* ValidateProtocolFunction -- common code for finding readfn, writefn or validatorfn
*/
......@@ -370,7 +336,7 @@ LookupExtProtocolFunction(const char *prot_name,
* protocol Oid.
*/
Oid
LookupExtProtocolOid(const char *prot_name, bool missing_ok)
get_extprotocol_oid(const char *prot_name, bool missing_ok)
{
Oid protOid = InvalidOid;
Relation rel;
......
......@@ -158,7 +158,7 @@ InsertExtTableEntry(Oid tbloid,
myself.objectSubId = 0;
referenced.classId = ExtprotocolRelationId;
referenced.objectId = LookupExtProtocolOid(protocol, true);
referenced.objectId = get_extprotocol_oid(protocol, true);
referenced.objectSubId = 0;
/*
......
......@@ -231,6 +231,10 @@ does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
name = NameListToString(objname);
args = strVal(linitial(objargs));
break;
case OBJECT_EXTPROTOCOL:
msg = gettext_noop("protocol \"%s\" does not exist, skipping");
name = NameListToString(objname);
break;
default:
elog(ERROR, "unexpected object type (%d)", (int) objtype);
break;
......
......@@ -107,83 +107,42 @@ DefineExtProtocol(List *name, List *parameters, bool trusted)
}
}
/*
* RemoveExtProtocols
* Implements DROP EXTERNAL PROTOCOL
* Drop PROTOCOL by OID. This is the guts of deletion.
* This is called to clean up dependencies.
*/
void
RemoveExtProtocols(DropStmt *drop)
RemoveExtProtocolById(Oid protOid)
{
ObjectAddresses *objects;
ListCell *cell;
Relation rel;
ScanKeyData skey;
SysScanDesc scan;
HeapTuple tup;
bool found = false;
/*
* First we identify all the objects, then we delete them in a single
* performMultipleDeletions() call. This is to avoid unwanted
* DROP RESTRICT errors if one of the objects depends on another.
* Search pg_extprotocol.
*/
objects = new_object_addresses();
foreach(cell, drop->objects)
{
List *names = (List *) lfirst(cell);
char *protocolName;
Oid protocolOid;
ObjectAddress object;
if (list_length(names) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("protocol name may not be qualified")));
protocolName = strVal(linitial(names));
protocolOid = LookupExtProtocolOid(protocolName, drop->missing_ok);
if (!OidIsValid(protocolOid))
{
if (!drop->missing_ok)
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("protocol \"%s\" does not exist",
protocolName)));
}
else
{
if (Gp_role != GP_ROLE_EXECUTE)
ereport(NOTICE,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("protocol \"%s\" does not exist, skipping",
protocolName)));
}
continue;
}
/* Permission check: must own protocol */
if (!pg_extprotocol_ownercheck(protocolOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTPROTOCOL, protocolName);
rel = heap_open(ExtprotocolRelationId, RowExclusiveLock);
object.classId = ExtprotocolRelationId;
object.objectId = protocolOid;
object.objectSubId = 0;
ScanKeyInit(&skey,
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(protOid));
scan = systable_beginscan(rel, ExtprotocolOidIndexId, true,
SnapshotNow, 1, &skey);
add_exact_object_address(&object, objects);
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
simple_heap_delete(rel, &tup->t_self);
found = true;
}
systable_endscan(scan);
performMultipleDeletions(objects, drop->behavior, 0);
free_object_addresses(objects);
}
if (!found)
elog(ERROR, "protocol %u could not be found", protOid);
/*
* Drop PROTOCOL by OID. This is the guts of deletion.
* This is called to clean up dependencies.
*/
void
RemoveExtProtocolById(Oid protOid)
{
ExtProtocolDeleteByOid(protOid);
heap_close(rel, NoLock);
}
/*
......
......@@ -256,7 +256,7 @@ DefineExternalRelation(CreateExternalStmt *createExtStmt)
{
Oid ownerId = GetUserId();
char *protname = uri->customprotocol;
Oid ptcId = LookupExtProtocolOid(protname, false);
Oid ptcId = get_extprotocol_oid(protname, false);
AclResult aclresult;
/* Check we have the right permissions on this protocol */
......
......@@ -912,10 +912,6 @@ standard_ProcessUtility(Node *parsetree,
case OBJECT_FOREIGN_TABLE:
RemoveRelations((DropStmt *) parsetree);
break;
case OBJECT_EXTPROTOCOL:
/* GPDB_92_MERGE_FIXME: Could we move it to RemoveObjects()? */
RemoveExtProtocols(stmt);
break;
default:
RemoveObjects((DropStmt *) parsetree);
break;
......
......@@ -82,16 +82,12 @@ ExtProtocolCreate(const char *protocolName,
List *validatorfuncName,
bool trusted);
extern void
ExtProtocolDeleteByOid(Oid protOid);
extern Oid
LookupExtProtocolFunction(const char *prot_name,
ExtPtcFuncType prot_type,
bool error);
extern Oid
LookupExtProtocolOid(const char *prot_name, bool error_if_missing);
extern Oid get_extprotocol_oid(const char *prot_name, bool error_if_missing);
extern char *
ExtProtocolGetNameByOid(Oid protOid);
......
......@@ -9,10 +9,9 @@
#ifndef EXTPROTOCOLCMDS_H
#define EXTPROTOCOLCMDS_H
#include "nodes/parsenodes.h"
#include "nodes/pg_list.h"
extern void DefineExtProtocol(List *name, List *parameters, bool trusted);
extern void RemoveExtProtocols(DropStmt *dtop);
extern void RemoveExtProtocolById(Oid protOid);
extern void AlterExtProtocolOwner(const char *name, Oid newOwnerId);
extern void RenameExtProtocol(const char *oldname, const char *newname);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册