//.........这里部分代码省略.........
}
snprintf(aoauxiliary_relname, sizeof(aoauxiliary_relname),
"%s_%u", auxiliaryNamePrefix, relOid);
snprintf(aoauxiliary_idxname, sizeof(aoauxiliary_idxname),
"%s_%u_index", auxiliaryNamePrefix, relOid);
/*
* We place auxiliary relation in the pg_aoseg namespace
* even if its master relation is a temp table. There cannot be
* any naming collision, and the auxiliary relation will be
* destroyed when its master is, so there is no need to handle
* the aovisimap relation as temp.
*/
aoauxiliary_relid = heap_create_with_catalog(aoauxiliary_relname,
PG_AOSEGMENT_NAMESPACE,
rel->rd_rel->reltablespace,
aoauxiliaryOid,
rel->rd_rel->relowner,
tupledesc,
/* relam */ InvalidOid,
relkind,
RELSTORAGE_HEAP,
shared_relation,
true,
/* bufferPoolBulkLoad */ false,
0,
ONCOMMIT_NOOP,
NULL, /* GP Policy */
(Datum) 0,
true,
/* valid_opts */ false,
aoauxiliaryComptypeOid,
/* persistentTid */ NULL,
/* persistentSerialNum */ NULL);
/* Make this table visible, else index creation will fail */
CommandCounterIncrement();
aoauxiliary_idxid = index_create(aoauxiliaryOid,
aoauxiliary_idxname,
aoauxiliaryIndexOid,
indexInfo,
BTREE_AM_OID,
rel->rd_rel->reltablespace,
classObjectId, coloptions, (Datum) 0,
true, false, (Oid *) NULL, true, false,
false, NULL);
/* Unlock target table -- no one can see it */
UnlockRelationOid(aoauxiliaryOid, ShareLock);
/* Unlock the index -- no one can see it anyway */
UnlockRelationOid(aoauxiliaryIndexOid, AccessExclusiveLock);
/*
* Store the auxiliary table's OID in the parent relation's pg_appendonly row.
* TODO (How to generalize this?)
*/
switch (relkind)
{
case RELKIND_AOVISIMAP:
UpdateAppendOnlyEntryAuxOids(relOid, InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
aoauxiliary_relid, aoauxiliary_idxid);
break;
case RELKIND_AOBLOCKDIR:
UpdateAppendOnlyEntryAuxOids(relOid, InvalidOid, InvalidOid,
aoauxiliary_relid, aoauxiliary_idxid,
InvalidOid, InvalidOid);
break;
case RELKIND_AOSEGMENTS:
UpdateAppendOnlyEntryAuxOids(relOid,
aoauxiliary_relid, aoauxiliary_idxid,
InvalidOid, InvalidOid,
InvalidOid, InvalidOid);
break;
default:
elog(ERROR, "unsupported auxiliary relkind '%c'", relkind);
}
/*
* Register dependency from the auxiliary table to the master, so that the
* aoseg table will be deleted if the master is.
*/
baseobject.classId = RelationRelationId;
baseobject.objectId = relOid;
baseobject.objectSubId = 0;
aoauxiliaryobject.classId = RelationRelationId;
aoauxiliaryobject.objectId = aoauxiliaryOid;
aoauxiliaryobject.objectSubId = 0;
recordDependencyOn(&aoauxiliaryobject, &baseobject, DEPENDENCY_INTERNAL);
/*
* Make changes visible
*/
CommandCounterIncrement();
return true;
}
/*
* GenerateTypeDependencies: build the dependencies needed for a type
*
* If rebuild is true, we remove existing dependencies and rebuild them
* from scratch. This is needed for ALTER TYPE, and also when replacing
* a shell type. We don't remove an existing extension dependency, though.
* (That means an extension can't absorb a shell type created in another
* extension, nor ALTER a type created by another extension. Also, if it
* replaces a free-standing shell type or ALTERs a free-standing type,
* that type will become a member of the extension.)
*/
void
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId,
Oid relationOid, /* only for relation rowtypes */
char relationKind, /* ditto */
Oid owner,
Oid inputProcedure,
Oid outputProcedure,
Oid receiveProcedure,
Oid sendProcedure,
Oid typmodinProcedure,
Oid typmodoutProcedure,
Oid analyzeProcedure,
Oid elementType,
bool isImplicitArray,
Oid baseType,
Oid typeCollation,
Node *defaultExpr,
bool rebuild)
{
ObjectAddress myself,
referenced;
/* If rebuild, first flush old dependencies, except extension deps */
if (rebuild)
{
deleteDependencyRecordsFor(TypeRelationId, typeObjectId, true);
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId, 0);
}
myself.classId = TypeRelationId;
myself.objectId = typeObjectId;
myself.objectSubId = 0;
/*
* Make dependencies on namespace, owner, extension.
*
* For a relation rowtype (that's not a composite type), we should skip
* these because we'll depend on them indirectly through the pg_class
* entry. Likewise, skip for implicit arrays since we'll depend on them
* through the element type.
*/
if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) &&
!isImplicitArray)
{
referenced.classId = NamespaceRelationId;
referenced.objectId = typeNamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
recordDependencyOnCurrentExtension(&myself, rebuild);
}
/* Normal dependencies on the I/O functions */
if (OidIsValid(inputProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = inputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(outputProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = outputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(receiveProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = receiveProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(sendProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = sendProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(typmodinProcedure))
//.........这里部分代码省略.........
//.........这里部分代码省略.........
CStringGetDatum((char *) conSrc));
else
nulls[Anum_pg_constraint_consrc - 1] = true;
tup = heap_form_tuple(RelationGetDescr(conDesc), values, nulls);
conOid = simple_heap_insert(conDesc, tup);
/* update catalog indexes */
CatalogUpdateIndexes(conDesc, tup);
conobject.classId = ConstraintRelationId;
conobject.objectId = conOid;
conobject.objectSubId = 0;
heap_close(conDesc, RowExclusiveLock);
if (OidIsValid(relId))
{
/*
* Register auto dependency from constraint to owning relation, or to
* specific column(s) if any are mentioned.
*/
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = relId;
if (constraintNKeys > 0)
{
for (i = 0; i < constraintNKeys; i++)
{
relobject.objectSubId = constraintKey[i];
recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);
}
}
else
{
relobject.objectSubId = 0;
recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);
}
}
if (OidIsValid(domainId))
{
/*
* Register auto dependency from constraint to owning domain
*/
ObjectAddress domobject;
domobject.classId = TypeRelationId;
domobject.objectId = domainId;
domobject.objectSubId = 0;
recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO);
}
if (OidIsValid(foreignRelId))
{
/*
* Register normal dependency from constraint to foreign relation, or
* to specific column(s) if any are mentioned.
*/
ObjectAddress relobject;
开发者ID:50wu,项目名称:gpdb,代码行数:66,代码来源:pg_constraint.c
示例6: create_toast_table
//.........这里部分代码省略.........
* NOTE: the normal TOAST access routines could actually function with a
* single-column index on chunk_id only. However, the slice access
* routines use both columns for faster access to an individual chunk. In
* addition, we want it to be unique as a check against the possibility of
* duplicate TOAST chunk OIDs. The index might also be a little more
* efficient this way, since btree isn't all that happy with large numbers
* of equal keys.
*/
indexInfo = makeNode(IndexInfo);
indexInfo->ii_NumIndexAttrs = 2;
indexInfo->ii_NumIndexKeyAttrs = 2;
indexInfo->ii_IndexAttrNumbers[0] = 1;
indexInfo->ii_IndexAttrNumbers[1] = 2;
indexInfo->ii_Expressions = NIL;
indexInfo->ii_ExpressionsState = NIL;
indexInfo->ii_Predicate = NIL;
indexInfo->ii_PredicateState = NULL;
indexInfo->ii_ExclusionOps = NULL;
indexInfo->ii_ExclusionProcs = NULL;
indexInfo->ii_ExclusionStrats = NULL;
indexInfo->ii_Unique = true;
indexInfo->ii_ReadyForInserts = true;
indexInfo->ii_Concurrent = false;
indexInfo->ii_BrokenHotChain = false;
indexInfo->ii_ParallelWorkers = 0;
indexInfo->ii_Am = BTREE_AM_OID;
indexInfo->ii_AmCache = NULL;
indexInfo->ii_Context = CurrentMemoryContext;
collationObjectId[0] = InvalidOid;
collationObjectId[1] = InvalidOid;
classObjectId[0] = OID_BTREE_OPS_OID;
classObjectId[1] = INT4_BTREE_OPS_OID;
coloptions[0] = 0;
coloptions[1] = 0;
index_create(toast_rel, toast_idxname, toastIndexOid, InvalidOid,
InvalidOid, InvalidOid,
indexInfo,
list_make2("chunk_id", "chunk_seq"),
BTREE_AM_OID,
rel->rd_rel->reltablespace,
collationObjectId, classObjectId, coloptions, (Datum) 0,
INDEX_CREATE_IS_PRIMARY, 0, true, true, NULL);
table_close(toast_rel, NoLock);
/*
* Store the toast table's OID in the parent relation's pg_class row
*/
class_rel = table_open(RelationRelationId, RowExclusiveLock);
reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
if (!HeapTupleIsValid(reltup))
elog(ERROR, "cache lookup failed for relation %u", relOid);
((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
if (!IsBootstrapProcessingMode())
{
/* normal case, use a transactional update */
CatalogTupleUpdate(class_rel, &reltup->t_self, reltup);
}
else
{
/* While bootstrapping, we cannot UPDATE, so overwrite in-place */
heap_inplace_update(class_rel, reltup);
}
heap_freetuple(reltup);
table_close(class_rel, RowExclusiveLock);
/*
* Register dependency from the toast table to the master, so that the
* toast table will be deleted if the master is. Skip this in bootstrap
* mode.
*/
if (!IsBootstrapProcessingMode())
{
baseobject.classId = RelationRelationId;
baseobject.objectId = relOid;
baseobject.objectSubId = 0;
toastobject.classId = RelationRelationId;
toastobject.objectId = toast_relid;
toastobject.objectSubId = 0;
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
}
/*
* Make changes visible
*/
CommandCounterIncrement();
return true;
}
//.........这里部分代码省略.........
/* Update the tuples in pg_class */
simple_heap_update(relRelation, &reltup1->t_self, reltup1);
simple_heap_update(relRelation, &reltup2->t_self, reltup2);
/* Keep system catalogs current */
CatalogIndexInsert(indstate, reltup1);
CatalogIndexInsert(indstate, reltup2);
#else
CatalogTupleUpdateWithInfo(relRelation, &reltup1->t_self, reltup1, indstate);
CatalogTupleUpdateWithInfo(relRelation, &reltup2->t_self, reltup2, indstate);
#endif
CatalogCloseIndexes(indstate);
/*
* If we have toast tables associated with the relations being swapped,
* change their dependency links to re-associate them with their new
* owning relations. Otherwise the wrong one will get dropped ...
*
* NOTE: it is possible that only one table has a toast table; this can
* happen in CLUSTER if there were dropped columns in the old table, and
* in ALTER TABLE when adding or changing type of columns.
*
* NOTE: at present, a TOAST table's only dependency is the one on its
* owning table. If more are ever created, we'd need to use something
* more selective than deleteDependencyRecordsFor() to get rid of only the
* link we want.
*/
if (relform1->reltoastrelid || relform2->reltoastrelid)
{
ObjectAddress baseobject,
toastobject;
long count;
/* Delete old dependencies */
if (relform1->reltoastrelid)
{
count = deleteDependencyRecordsFor(RelationRelationId,
relform1->reltoastrelid,
false);
if (count != 1)
elog(ERROR, "expected one dependency record for TOAST table, found %ld",
count);
}
if (relform2->reltoastrelid)
{
count = deleteDependencyRecordsFor(RelationRelationId,
relform2->reltoastrelid,
false);
if (count != 1)
elog(ERROR, "expected one dependency record for TOAST table, found %ld",
count);
}
/* Register new dependencies */
baseobject.classId = RelationRelationId;
baseobject.objectSubId = 0;
toastobject.classId = RelationRelationId;
toastobject.objectSubId = 0;
if (relform1->reltoastrelid)
{
baseobject.objectId = r1;
toastobject.objectId = relform1->reltoastrelid;
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
}
if (relform2->reltoastrelid)
{
baseobject.objectId = r2;
toastobject.objectId = relform2->reltoastrelid;
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
}
}
/*
* Blow away the old relcache entries now. We need this kluge because
* relcache.c keeps a link to the smgr relation for the physical file, and
* that will be out of date as soon as we do CommandCounterIncrement.
* Whichever of the rels is the second to be cleared during cache
* invalidation will have a dangling reference to an already-deleted smgr
* relation. Rather than trying to avoid this by ordering operations just
* so, it's easiest to not have the relcache entries there at all.
* (Fortunately, since one of the entries is local in our transaction,
* it's sufficient to clear out our own relcache this way; the problem
* cannot arise for other backends when they see our update on the
* non-local relation.)
*/
RelationForgetRelation(r1);
RelationForgetRelation(r2);
/* Clean up. */
heap_freetuple(reltup1);
heap_freetuple(reltup2);
heap_close(relRelation, RowExclusiveLock);
}
开发者ID:reorg,项目名称:pg_repack,代码行数:101,代码来源:repack.c
示例9: InsertRule
//.........这里部分代码省略.........
/*
* Ready to store new pg_rewrite tuple
*/
/*
* Check to see if we are replacing an existing tuple
*/
pcqCtx = caql_beginscan(
NULL,
cql("SELECT * FROM pg_rewrite "
" WHERE ev_class = :1 "
" AND rulename = :2 "
" FOR UPDATE ",
ObjectIdGetDatum(eventrel_oid),
CStringGetDatum(rulname)));
oldtup = caql_getnext(pcqCtx);
if (HeapTupleIsValid(oldtup))
{
if (!replace)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("rule \"%s\" for relation \"%s\" already exists",
rulname, get_rel_name(eventrel_oid))));
/*
* When replacing, we don't need to replace every attribute
*/
MemSet(replaces, false, sizeof(replaces));
replaces[Anum_pg_rewrite_ev_attr - 1] = true;
replaces[Anum_pg_rewrite_ev_type - 1] = true;
replaces[Anum_pg_rewrite_is_instead - 1] = true;
replaces[Anum_pg_rewrite_ev_qual - 1] = true;
replaces[Anum_pg_rewrite_ev_action - 1] = true;
tup = caql_modify_current(pcqCtx,
values, nulls, replaces);
caql_update_current(pcqCtx, tup);
/* and Update indexes (implicit) */
rewriteObjectId = HeapTupleGetOid(tup);
is_update = true;
}
else
{
tup = caql_form_tuple(pcqCtx, values, nulls);
if (OidIsValid(ruleOid))
HeapTupleSetOid(tup, ruleOid);
rewriteObjectId = caql_insert(pcqCtx, tup);
/* and Update indexes (implicit) */
}
heap_freetuple(tup);
/* If replacing, get rid of old dependencies and make new ones */
if (is_update)
deleteDependencyRecordsFor(RewriteRelationId, rewriteObjectId);
/*
* Install dependency on rule's relation to ensure it will go away on
* relation deletion. If the rule is ON SELECT, make the dependency
* implicit --- this prevents deleting a view's SELECT rule. Other kinds
* of rules can be AUTO.
*/
myself.classId = RewriteRelationId;
myself.objectId = rewriteObjectId;
myself.objectSubId = 0;
referenced.classId = RelationRelationId;
referenced.objectId = eventrel_oid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced,
(evtype == CMD_SELECT) ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
/*
* Also install dependencies on objects referenced in action and qual.
*/
recordDependencyOnExpr(&myself, (Node *) action, NIL,
DEPENDENCY_NORMAL);
if (event_qual != NULL)
{
/* Find query containing OLD/NEW rtable entries */
Query *qry = (Query *) linitial(action);
qry = getInsertSelectQuery(qry, NULL);
recordDependencyOnExpr(&myself, event_qual, qry->rtable,
DEPENDENCY_NORMAL);
}
caql_endscan(pcqCtx);
return rewriteObjectId;
}
//.........这里部分代码省略.........
TupleDescInitEntry(tupdesc, (AttrNumber) 4,
"minipage",
VARBITOID,
-1, 0);
/*
* We don't want any toast columns here.
*/
tupdesc->attrs[0]->attstorage = 'p';
tupdesc->attrs[1]->attstorage = 'p';
tupdesc->attrs[2]->attstorage = 'p';
tupdesc->attrs[2]->attstorage = 'p';
/*
* We place aoblkdir relation in the pg_aoseg namespace
* even if its master relation is a temp table. There cannot be
* any naming collision, and the aoblkdir relation will be
* destroyed when its master is, so there is no need to handle
* the aoblkdir relation as temp.
*/
aoblkdir_relid = heap_create_with_catalog(aoblkdir_relname,
PG_AOSEGMENT_NAMESPACE,
tablespaceOid,
aoblkdirOid,
rel->rd_rel->relowner,
tupdesc,
/* relam */ InvalidOid,
RELKIND_AOBLOCKDIR,
RELSTORAGE_HEAP,
shared_relation,
true,
/* bufferPoolBulkLoad */ false,
0,
ONCOMMIT_NOOP,
NULL, /* GP Policy */
(Datum) 0,
true,
comptypeOid,
/* persistentTid */ NULL,
/* persistentSerialNum */ NULL);
/* Make this table visible, else index creation will fail */
CommandCounterIncrement();
/*
* Create index on segno, first_row_no.
*/
indexInfo = makeNode(IndexInfo);
indexInfo->ii_NumIndexAttrs = 3;
indexInfo->ii_KeyAttrNumbers[0] = 1;
indexInfo->ii_KeyAttrNumbers[1] = 2;
indexInfo->ii_KeyAttrNumbers[2] = 3;
indexInfo->ii_Expressions = NIL;
indexInfo->ii_ExpressionsState = NIL;
indexInfo->ii_Predicate = NIL;
indexInfo->ii_PredicateState = NIL;
indexInfo->ii_Unique = false;
indexInfo->ii_Concurrent = false;
classObjectId[0] = INT4_BTREE_OPS_OID;
classObjectId[1] = INT4_BTREE_OPS_OID;
classObjectId[2] = INT8_BTREE_OPS_OID;
aoblkdir_idxid = index_create(aoblkdirOid, aoblkdir_idxname, aoblkdirIndexOid,
indexInfo,
BTREE_AM_OID,
tablespaceOid,
classObjectId, (Datum) 0,
true, false, (Oid *) NULL, true, false, false, NULL);
/* Unlock target table -- no one can see it */
UnlockRelationOid(aoblkdirOid, ShareLock);
/* Unlock the index -- no one can see it anyway */
UnlockRelationOid(aoblkdirIndexOid, AccessExclusiveLock);
/*
* Store the aoblkdir table's OID in the parent relation's pg_appendonly row.
*/
UpdateAppendOnlyEntryAuxOids(relOid, InvalidOid, InvalidOid,
aoblkdir_relid, aoblkdir_idxid);
/*
* Register dependency from the aoseg table to the master, so that the
* aoseg table will be deleted if the master is.
*/
baseobject.classId = RelationRelationId;
baseobject.objectId = relOid;
baseobject.objectSubId = 0;
aoblkdirobject.classId = RelationRelationId;
aoblkdirobject.objectId = aoblkdirOid;
aoblkdirobject.objectSubId = 0;
recordDependencyOn(&aoblkdirobject, &baseobject, DEPENDENCY_INTERNAL);
/*
* Make changes visible
*/
CommandCounterIncrement();
return true;
}
/*
* GenerateTypeDependencies: build the dependencies needed for a type
*
* If rebuild is true, we remove existing dependencies and rebuild them
* from scratch. This is needed for ALTER TYPE, and also when replacing
* a shell type.
*/
void
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog types */
char relationKind, /* ditto */
Oid owner,
Oid inputProcedure,
Oid outputProcedure,
Oid receiveProcedure,
Oid sendProcedure,
Oid analyzeProcedure,
Oid elementType,
Oid baseType,
Node *defaultExpr,
bool rebuild)
{
ObjectAddress myself,
referenced;
if (rebuild)
{
deleteDependencyRecordsFor(TypeRelationId, typeObjectId);
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId);
}
myself.classId = TypeRelationId;
myself.objectId = typeObjectId;
myself.objectSubId = 0;
/* dependency on namespace */
/* skip for relation rowtype, since we have indirect dependency */
if (!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE)
{
referenced.classId = NamespaceRelationId;
referenced.objectId = typeNamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
}
/* Normal dependencies on the I/O functions */
if (OidIsValid(inputProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = inputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(outputProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = outputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(receiveProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = receiveProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(sendProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = sendProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(analyzeProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = analyzeProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/*
* If the type is a rowtype for a relation, mark it as internally
* dependent on the relation, *unless* it is a stand-alone composite type
* relation. For the latter case, we have to reverse the dependency.
*
* In the former case, this allows the type to be auto-dropped when the
* relation is, and not otherwise. And in the latter, of course we get the
* opposite effect.
*/
if (OidIsValid(relationOid))
{
//.........这里部分代码省略.........
开发者ID:ricky-wu,项目名称:gpdb,代码行数:101,代码来源:pg_type.c
示例14: ExtProtocolCreate
//.........这里部分代码省略.........
strcasecmp(protocolName, "gpfdists") == 0)
{
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("protocol \"%s\" already exists",
protocolName),
errhint("pick a different protocol name")));
}
rel = heap_open(ExtprotocolRelationId, RowExclusiveLock);
/* make sure there is no existing protocol of same name */
ScanKeyInit(&skey,
Anum_pg_extprotocol_ptcname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(protocolName));
scan = systable_beginscan(rel, ExtprotocolPtcnameIndexId, true,
SnapshotNow, 1, &skey);
tup = systable_getnext(scan);
if (HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("protocol \"%s\" already exists",
protocolName)));
systable_endscan(scan);
/*
* function checks: if supplied, check existence and correct signature in the catalog
*/
if (readfuncName)
readfn = ValidateProtocolFunction(readfuncName, EXTPTC_FUNC_READER);
if (writefuncName)
writefn = ValidateProtocolFunction(writefuncName, EXTPTC_FUNC_WRITER);
if (validatorfuncName)
validatorfn = ValidateProtocolFunction(validatorfuncName, EXTPTC_FUNC_VALIDATOR);
/*
* Everything looks okay. Try to create the pg_extprotocol entry for the
* protocol. (This could fail if there's already a conflicting entry.)
*/
/* initialize nulls and values */
for (i = 0; i < Natts_pg_extprotocol; i++)
{
nulls[i] = false;
values[i] = (Datum) 0;
}
namestrcpy(&prtname, protocolName);
values[Anum_pg_extprotocol_ptcname - 1] = NameGetDatum(&prtname);
values[Anum_pg_extprotocol_ptcreadfn - 1] = ObjectIdGetDatum(readfn);
values[Anum_pg_extprotocol_ptcwritefn - 1] = ObjectIdGetDatum(writefn);
values[Anum_pg_extprotocol_ptcvalidatorfn - 1] = ObjectIdGetDatum(validatorfn);
values[Anum_pg_extprotocol_ptcowner - 1] = ObjectIdGetDatum(ownerId);
values[Anum_pg_extprotocol_ptctrusted - 1] = BoolGetDatum(trusted);
nulls[Anum_pg_extprotocol_ptcacl - 1] = true;
tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
/* insert a new tuple */
protOid = simple_heap_insert(rel, tup);
CatalogUpdateIndexes(rel, tup);
heap_close(rel, RowExclusiveLock);
/*
* Create dependencies for the protocol
*/
myself.classId = ExtprotocolRelationId;
myself.objectId = protOid;
myself.objectSubId = 0;
/* Depends on read function, if any */
if (OidIsValid(readfn))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = readfn;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Depends on write function, if any */
if (OidIsValid(writefn))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = writefn;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* dependency on owner */
recordDependencyOnOwner(ExtprotocolRelationId, protOid, GetUserId());
/* dependency on extension */
recordDependencyOnCurrentExtension(&myself, false);
return protOid;
}
请发表评论