aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r--src/backend/commands/typecmds.c259
1 files changed, 149 insertions, 110 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 60ab3aaf12f..67e2ae22c68 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -101,14 +101,14 @@ static void checkEnumOwner(HeapTuple tup);
static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
Oid baseTypeOid,
int typMod, Constraint *constr,
- char *domainName);
+ char *domainName, ObjectAddress *constrAddr);
/*
* DefineType
* Registers a new base type.
*/
-Oid
+ObjectAddress
DefineType(List *names, List *parameters)
{
char *typeName;
@@ -160,6 +160,7 @@ DefineType(List *names, List *parameters)
Oid typoid;
Oid resulttype;
ListCell *pl;
+ ObjectAddress address;
/*
* As of Postgres 8.4, we require superuser privilege to create a base
@@ -213,7 +214,7 @@ DefineType(List *names, List *parameters)
*/
if (!OidIsValid(typoid))
{
- typoid = TypeShellMake(typeName, typeNamespace, GetUserId());
+ address = TypeShellMake(typeName, typeNamespace, GetUserId());
/* Make new shell type visible for modification below */
CommandCounterIncrement();
@@ -222,7 +223,7 @@ DefineType(List *names, List *parameters)
* creating the shell type was all we're supposed to do.
*/
if (parameters == NIL)
- return InvalidOid;
+ return address;
}
else
{
@@ -595,7 +596,7 @@ DefineType(List *names, List *parameters)
* types) in ArrayType and in composite types in DatumTupleFields. This
* oid must be preserved by binary upgrades.
*/
- typoid =
+ address =
TypeCreate(InvalidOid, /* no predetermined type OID */
typeName, /* type name */
typeNamespace, /* namespace */
@@ -670,7 +671,7 @@ DefineType(List *names, List *parameters)
pfree(array_type);
- return typoid;
+ return address;
}
/*
@@ -716,7 +717,7 @@ RemoveTypeById(Oid typeOid)
* DefineDomain
* Registers a new domain.
*/
-Oid
+ObjectAddress
DefineDomain(CreateDomainStmt *stmt)
{
char *domainName;
@@ -746,12 +747,12 @@ DefineDomain(CreateDomainStmt *stmt)
List *schema = stmt->constraints;
ListCell *listptr;
Oid basetypeoid;
- Oid domainoid;
Oid old_type_oid;
Oid domaincoll;
Form_pg_type baseType;
int32 basetypeMod;
Oid baseColl;
+ ObjectAddress address;
/* Convert list of names to a name and namespace */
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
@@ -1021,7 +1022,7 @@ DefineDomain(CreateDomainStmt *stmt)
/*
* Have TypeCreate do all the real work.
*/
- domainoid =
+ address =
TypeCreate(InvalidOid, /* no predetermined type OID */
domainName, /* type name */
domainNamespace, /* namespace */
@@ -1066,9 +1067,9 @@ DefineDomain(CreateDomainStmt *stmt)
switch (constr->contype)
{
case CONSTR_CHECK:
- domainAddConstraint(domainoid, domainNamespace,
+ domainAddConstraint(address.objectId, domainNamespace,
basetypeoid, basetypeMod,
- constr, domainName);
+ constr, domainName, NULL);
break;
/* Other constraint types were fully processed above */
@@ -1086,7 +1087,7 @@ DefineDomain(CreateDomainStmt *stmt)
*/
ReleaseSysCache(typeTup);
- return domainoid;
+ return address;
}
@@ -1094,16 +1095,16 @@ DefineDomain(CreateDomainStmt *stmt)
* DefineEnum
* Registers a new enum.
*/
-Oid
+ObjectAddress
DefineEnum(CreateEnumStmt *stmt)
{
char *enumName;
char *enumArrayName;
Oid enumNamespace;
- Oid enumTypeOid;
AclResult aclresult;
Oid old_type_oid;
Oid enumArrayOid;
+ ObjectAddress enumTypeAddr;
/* Convert list of names to a name and namespace */
enumNamespace = QualifiedNameGetCreationNamespace(stmt->typeName,
@@ -1133,7 +1134,7 @@ DefineEnum(CreateEnumStmt *stmt)
enumArrayOid = AssignTypeArrayOid();
/* Create the pg_type entry */
- enumTypeOid =
+ enumTypeAddr =
TypeCreate(InvalidOid, /* no predetermined type OID */
enumName, /* type name */
enumNamespace, /* namespace */
@@ -1167,7 +1168,7 @@ DefineEnum(CreateEnumStmt *stmt)
InvalidOid); /* type's collation */
/* Enter the enum's values into pg_enum */
- EnumValuesCreate(enumTypeOid, stmt->vals);
+ EnumValuesCreate(enumTypeAddr.objectId, stmt->vals);
/*
* Create the array type that goes with it.
@@ -1192,7 +1193,7 @@ DefineEnum(CreateEnumStmt *stmt)
InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */
F_ARRAY_TYPANALYZE, /* analyze procedure */
- enumTypeOid, /* element type ID */
+ enumTypeAddr.objectId, /* element type ID */
true, /* yes this is an array type */
InvalidOid, /* no further array type */
InvalidOid, /* base type ID */
@@ -1208,19 +1209,20 @@ DefineEnum(CreateEnumStmt *stmt)
pfree(enumArrayName);
- return enumTypeOid;
+ return enumTypeAddr;
}
/*
* AlterEnum
* Adds a new label to an existing enum.
*/
-Oid
+ObjectAddress
AlterEnum(AlterEnumStmt *stmt, bool isTopLevel)
{
Oid enum_type_oid;
TypeName *typename;
HeapTuple tup;
+ ObjectAddress address;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(stmt->typeName);
@@ -1259,9 +1261,11 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel)
InvokeObjectPostAlterHook(TypeRelationId, enum_type_oid, 0);
+ ObjectAddressSet(address, TypeRelationId, enum_type_oid);
+
ReleaseSysCache(tup);
- return enum_type_oid;
+ return address;
}
@@ -1293,7 +1297,7 @@ checkEnumOwner(HeapTuple tup)
* DefineRange
* Registers a new range type.
*/
-Oid
+ObjectAddress
DefineRange(CreateRangeStmt *stmt)
{
char *typeName;
@@ -1316,6 +1320,7 @@ DefineRange(CreateRangeStmt *stmt)
char alignment;
AclResult aclresult;
ListCell *lc;
+ ObjectAddress address;
/* Convert list of names to a name and namespace */
typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName,
@@ -1354,7 +1359,8 @@ DefineRange(CreateRangeStmt *stmt)
*/
if (!OidIsValid(typoid))
{
- typoid = TypeShellMake(typeName, typeNamespace, GetUserId());
+ address = TypeShellMake(typeName, typeNamespace, GetUserId());
+ typoid = address.objectId;
/* Make new shell type visible for modification below */
CommandCounterIncrement();
}
@@ -1467,7 +1473,7 @@ DefineRange(CreateRangeStmt *stmt)
rangeArrayOid = AssignTypeArrayOid();
/* Create the pg_type entry */
- typoid =
+ address =
TypeCreate(InvalidOid, /* no predetermined type OID */
typeName, /* type name */
typeNamespace, /* namespace */
@@ -1499,6 +1505,7 @@ DefineRange(CreateRangeStmt *stmt)
0, /* Array dimensions of typbasetype */
false, /* Type NOT NULL */
InvalidOid); /* type's collation (ranges never have one) */
+ typoid = address.objectId;
/* Create the entry in pg_range */
RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass,
@@ -1546,7 +1553,7 @@ DefineRange(CreateRangeStmt *stmt)
/* And create the constructor functions for this range type */
makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype);
- return typoid;
+ return address;
}
/*
@@ -1582,45 +1589,40 @@ makeRangeConstructors(const char *name, Oid namespace,
for (i = 0; i < lengthof(prosrc); i++)
{
oidvector *constructorArgTypesVector;
- Oid procOid;
constructorArgTypesVector = buildoidvector(constructorArgTypes,
pronargs[i]);
- procOid = ProcedureCreate(name, /* name: same as range type */
- namespace, /* namespace */
- false, /* replace */
- false, /* returns set */
- rangeOid, /* return type */
- BOOTSTRAP_SUPERUSERID, /* proowner */
- INTERNALlanguageId, /* language */
- F_FMGR_INTERNAL_VALIDATOR, /* language validator */
- prosrc[i], /* prosrc */
- NULL, /* probin */
- false, /* isAgg */
- false, /* isWindowFunc */
- false, /* security_definer */
- false, /* leakproof */
- false, /* isStrict */
- PROVOLATILE_IMMUTABLE, /* volatility */
- constructorArgTypesVector, /* parameterTypes */
- PointerGetDatum(NULL), /* allParameterTypes */
- PointerGetDatum(NULL), /* parameterModes */
- PointerGetDatum(NULL), /* parameterNames */
- NIL, /* parameterDefaults */
- PointerGetDatum(NULL), /* proconfig */
- 1.0, /* procost */
- 0.0); /* prorows */
+ myself = ProcedureCreate(name, /* name: same as range type */
+ namespace, /* namespace */
+ false, /* replace */
+ false, /* returns set */
+ rangeOid, /* return type */
+ BOOTSTRAP_SUPERUSERID, /* proowner */
+ INTERNALlanguageId, /* language */
+ F_FMGR_INTERNAL_VALIDATOR, /* language validator */
+ prosrc[i], /* prosrc */
+ NULL, /* probin */
+ false, /* isAgg */
+ false, /* isWindowFunc */
+ false, /* security_definer */
+ false, /* leakproof */
+ false, /* isStrict */
+ PROVOLATILE_IMMUTABLE, /* volatility */
+ constructorArgTypesVector, /* parameterTypes */
+ PointerGetDatum(NULL), /* allParameterTypes */
+ PointerGetDatum(NULL), /* parameterModes */
+ PointerGetDatum(NULL), /* parameterNames */
+ NIL, /* parameterDefaults */
+ PointerGetDatum(NULL), /* proconfig */
+ 1.0, /* procost */
+ 0.0); /* prorows */
/*
* Make the constructors internally-dependent on the range type so
* that they go away silently when the type is dropped. Note that
* pg_dump depends on this choice to avoid dumping the constructors.
*/
- myself.classId = ProcedureRelationId;
- myself.objectId = procOid;
- myself.objectSubId = 0;
-
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
}
}
@@ -2059,17 +2061,16 @@ AssignTypeArrayOid(void)
* If the relation already exists, then 'DefineRelation' will abort
* the xact...
*
- * DefineCompositeType returns relid for use when creating
- * an implicit composite type during function creation
+ * Return type is the new type's object address.
*-------------------------------------------------------------------
*/
-Oid
+ObjectAddress
DefineCompositeType(RangeVar *typevar, List *coldeflist)
{
CreateStmt *createStmt = makeNode(CreateStmt);
Oid old_type_oid;
Oid typeNamespace;
- Oid relid;
+ ObjectAddress address;
/*
* now set the parameters for keys/inheritance etc. All of these are
@@ -2108,17 +2109,19 @@ DefineCompositeType(RangeVar *typevar, List *coldeflist)
/*
* Finally create the relation. This also creates the type.
*/
- relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid);
- Assert(relid != InvalidOid);
- return relid;
+ DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid, &address);
+
+ return address;
}
/*
* AlterDomainDefault
*
* Routine implementing ALTER DOMAIN SET/DROP DEFAULT statements.
+ *
+ * Returns ObjectAddress of the modified domain.
*/
-Oid
+ObjectAddress
AlterDomainDefault(List *names, Node *defaultRaw)
{
TypeName *typename;
@@ -2133,6 +2136,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
bool new_record_repl[Natts_pg_type];
HeapTuple newtuple;
Form_pg_type typTup;
+ ObjectAddress address;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -2242,19 +2246,23 @@ AlterDomainDefault(List *names, Node *defaultRaw)
InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0);
+ ObjectAddressSet(address, TypeRelationId, domainoid);
+
/* Clean up */
heap_close(rel, NoLock);
heap_freetuple(newtuple);
- return domainoid;
+ return address;
}
/*
* AlterDomainNotNull
*
* Routine implementing ALTER DOMAIN SET/DROP NOT NULL statements.
+ *
+ * Returns ObjectAddress of the modified domain.
*/
-Oid
+ObjectAddress
AlterDomainNotNull(List *names, bool notNull)
{
TypeName *typename;
@@ -2262,6 +2270,7 @@ AlterDomainNotNull(List *names, bool notNull)
Relation typrel;
HeapTuple tup;
Form_pg_type typTup;
+ ObjectAddress address = InvalidObjectAddress;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -2282,7 +2291,7 @@ AlterDomainNotNull(List *names, bool notNull)
if (typTup->typnotnull == notNull)
{
heap_close(typrel, RowExclusiveLock);
- return InvalidOid;
+ return address;
}
/* Adding a NOT NULL constraint requires checking existing columns */
@@ -2356,11 +2365,13 @@ AlterDomainNotNull(List *names, bool notNull)
InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0);
+ ObjectAddressSet(address, TypeRelationId, domainoid);
+
/* Clean up */
heap_freetuple(tup);
heap_close(typrel, RowExclusiveLock);
- return domainoid;
+ return address;
}
/*
@@ -2368,7 +2379,7 @@ AlterDomainNotNull(List *names, bool notNull)
*
* Implements the ALTER DOMAIN DROP CONSTRAINT statement
*/
-Oid
+ObjectAddress
AlterDomainDropConstraint(List *names, const char *constrName,
DropBehavior behavior, bool missing_ok)
{
@@ -2381,6 +2392,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
ScanKeyData key[1];
HeapTuple contup;
bool found = false;
+ ObjectAddress address = InvalidObjectAddress;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -2427,6 +2439,9 @@ AlterDomainDropConstraint(List *names, const char *constrName,
found = true;
}
}
+
+ ObjectAddressSet(address, TypeRelationId, domainoid);
+
/* Clean up after the scan */
systable_endscan(conscan);
heap_close(conrel, RowExclusiveLock);
@@ -2446,7 +2461,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
constrName, TypeNameToString(typename))));
}
- return domainoid;
+ return address;
}
/*
@@ -2454,8 +2469,9 @@ AlterDomainDropConstraint(List *names, const char *constrName,
*
* Implements the ALTER DOMAIN .. ADD CONSTRAINT statement.
*/
-Oid
-AlterDomainAddConstraint(List *names, Node *newConstraint)
+ObjectAddress
+AlterDomainAddConstraint(List *names, Node *newConstraint,
+ ObjectAddress *constrAddr)
{
TypeName *typename;
Oid domainoid;
@@ -2464,6 +2480,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
Form_pg_type typTup;
Constraint *constr;
char *ccbin;
+ ObjectAddress address;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -2539,7 +2556,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
ccbin = domainAddConstraint(domainoid, typTup->typnamespace,
typTup->typbasetype, typTup->typtypmod,
- constr, NameStr(typTup->typname));
+ constr, NameStr(typTup->typname), constrAddr);
/*
* If requested to validate the constraint, test all values stored in the
@@ -2548,10 +2565,12 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
if (!constr->skip_validation)
validateDomainConstraint(domainoid, ccbin);
+ ObjectAddressSet(address, TypeRelationId, domainoid);
+
/* Clean up */
heap_close(typrel, RowExclusiveLock);
- return domainoid;
+ return address;
}
/*
@@ -2559,7 +2578,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
*
* Implements the ALTER DOMAIN .. VALIDATE CONSTRAINT statement.
*/
-Oid
+ObjectAddress
AlterDomainValidateConstraint(List *names, char *constrName)
{
TypeName *typename;
@@ -2577,6 +2596,7 @@ AlterDomainValidateConstraint(List *names, char *constrName)
HeapTuple tuple;
HeapTuple copyTuple;
ScanKeyData key;
+ ObjectAddress address;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -2647,6 +2667,8 @@ AlterDomainValidateConstraint(List *names, char *constrName)
InvokeObjectPostAlterHook(ConstraintRelationId,
HeapTupleGetOid(copyTuple), 0);
+ ObjectAddressSet(address, TypeRelationId, domainoid);
+
heap_freetuple(copyTuple);
systable_endscan(scan);
@@ -2656,7 +2678,7 @@ AlterDomainValidateConstraint(List *names, char *constrName)
ReleaseSysCache(tup);
- return domainoid;
+ return address;
}
static void
@@ -2953,13 +2975,14 @@ checkDomainOwner(HeapTuple tup)
static char *
domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
int typMod, Constraint *constr,
- char *domainName)
+ char *domainName, ObjectAddress *constrAddr)
{
Node *expr;
char *ccsrc;
char *ccbin;
ParseState *pstate;
CoerceToDomainValue *domVal;
+ Oid ccoid;
/*
* Assign or validate constraint name
@@ -3038,34 +3061,37 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
/*
* Store the constraint in pg_constraint
*/
- CreateConstraintEntry(constr->conname, /* Constraint Name */
- domainNamespace, /* namespace */
- CONSTRAINT_CHECK, /* Constraint Type */
- false, /* Is Deferrable */
- false, /* Is Deferred */
- !constr->skip_validation, /* Is Validated */
- InvalidOid, /* not a relation constraint */
- NULL,
- 0,
- domainOid, /* domain constraint */
- InvalidOid, /* no associated index */
- InvalidOid, /* Foreign key fields */
- NULL,
- NULL,
- NULL,
- NULL,
- 0,
- ' ',
- ' ',
- ' ',
- NULL, /* not an exclusion constraint */
- expr, /* Tree form of check constraint */
- ccbin, /* Binary form of check constraint */
- ccsrc, /* Source form of check constraint */
- true, /* is local */
- 0, /* inhcount */
- false, /* connoinherit */
- false); /* is_internal */
+ ccoid =
+ CreateConstraintEntry(constr->conname, /* Constraint Name */
+ domainNamespace, /* namespace */
+ CONSTRAINT_CHECK, /* Constraint Type */
+ false, /* Is Deferrable */
+ false, /* Is Deferred */
+ !constr->skip_validation, /* Is Validated */
+ InvalidOid, /* not a relation constraint */
+ NULL,
+ 0,
+ domainOid, /* domain constraint */
+ InvalidOid, /* no associated index */
+ InvalidOid, /* Foreign key fields */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ ' ',
+ ' ',
+ ' ',
+ NULL, /* not an exclusion constraint */
+ expr, /* Tree form of check constraint */
+ ccbin, /* Binary form of check constraint */
+ ccsrc, /* Source form of check constraint */
+ true, /* is local */
+ 0, /* inhcount */
+ false, /* connoinherit */
+ false); /* is_internal */
+ if (constrAddr)
+ ObjectAddressSet(*constrAddr, ConstraintRelationId, ccoid);
/*
* Return the compiled constraint expression so the calling routine can
@@ -3078,7 +3104,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
/*
* Execute ALTER TYPE RENAME
*/
-Oid
+ObjectAddress
RenameType(RenameStmt *stmt)
{
List *names = stmt->object;
@@ -3088,6 +3114,7 @@ RenameType(RenameStmt *stmt)
Relation rel;
HeapTuple tup;
Form_pg_type typTup;
+ ObjectAddress address;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -3145,16 +3172,17 @@ RenameType(RenameStmt *stmt)
RenameTypeInternal(typeOid, newTypeName,
typTup->typnamespace);
+ ObjectAddressSet(address, TypeRelationId, typeOid);
/* Clean up */
heap_close(rel, RowExclusiveLock);
- return typeOid;
+ return address;
}
/*
* Change the owner of a type.
*/
-Oid
+ObjectAddress
AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
{
TypeName *typename;
@@ -3164,6 +3192,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
HeapTuple newtup;
Form_pg_type typTup;
AclResult aclresult;
+ ObjectAddress address;
rel = heap_open(TypeRelationId, RowExclusiveLock);
@@ -3293,10 +3322,12 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
}
}
+ ObjectAddressSet(address, TypeRelationId, typeOid);
+
/* Clean up */
heap_close(rel, RowExclusiveLock);
- return typeOid;
+ return address;
}
/*
@@ -3376,13 +3407,16 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
/*
* Execute ALTER TYPE SET SCHEMA
*/
-Oid
-AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype)
+ObjectAddress
+AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
+ Oid *oldschema)
{
TypeName *typename;
Oid typeOid;
Oid nspOid;
+ Oid oldNspOid;
ObjectAddresses *objsMoved;
+ ObjectAddress myself;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names);
@@ -3399,10 +3433,15 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype)
nspOid = LookupCreationNamespace(newschema);
objsMoved = new_object_addresses();
- AlterTypeNamespace_oid(typeOid, nspOid, objsMoved);
+ oldNspOid = AlterTypeNamespace_oid(typeOid, nspOid, objsMoved);
free_object_addresses(objsMoved);
- return typeOid;
+ if (oldschema)
+ *oldschema = oldNspOid;
+
+ ObjectAddressSet(myself, TypeRelationId, typeOid);
+
+ return myself;
}
Oid