diff options
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r-- | src/backend/commands/typecmds.c | 259 |
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 |