Repair bug noticed by Deepak Bhole: a shell type should have a dependency

on its namespace, so that it will go away if the schema is dropped.
This commit is contained in:
Tom Lane 2003-01-08 21:40:39 +00:00
parent fe7f8f2b91
commit 51d2e3bd6e
3 changed files with 71 additions and 43 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.85 2002/12/06 05:00:10 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.86 2003/01/08 21:40:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -105,6 +105,21 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
CatalogUpdateIndexes(pg_type_desc, tup); CatalogUpdateIndexes(pg_type_desc, tup);
/*
* Create dependencies. We can/must skip this in bootstrap mode.
*/
if (!IsBootstrapProcessingMode())
GenerateTypeDependencies(typeNamespace,
typoid,
InvalidOid,
0,
InvalidOid,
InvalidOid,
InvalidOid,
InvalidOid,
NULL,
false);
/* /*
* clean up and return the type-oid * clean up and return the type-oid
*/ */
@ -129,7 +144,7 @@ Oid
TypeCreate(const char *typeName, TypeCreate(const char *typeName,
Oid typeNamespace, Oid typeNamespace,
Oid assignedTypeOid, Oid assignedTypeOid,
Oid relationOid, /* only for 'c'atalog typeType */ Oid relationOid, /* only for 'c'atalog types */
char relationKind, /* ditto */ char relationKind, /* ditto */
int16 internalSize, int16 internalSize,
char typeType, char typeType,
@ -149,6 +164,7 @@ TypeCreate(const char *typeName,
{ {
Relation pg_type_desc; Relation pg_type_desc;
Oid typeObjectId; Oid typeObjectId;
bool rebuildDeps = false;
HeapTuple tup; HeapTuple tup;
char nulls[Natts_pg_type]; char nulls[Natts_pg_type];
char replaces[Natts_pg_type]; char replaces[Natts_pg_type];
@ -268,6 +284,8 @@ TypeCreate(const char *typeName,
simple_heap_update(pg_type_desc, &tup->t_self, tup); simple_heap_update(pg_type_desc, &tup->t_self, tup);
typeObjectId = HeapTupleGetOid(tup); typeObjectId = HeapTupleGetOid(tup);
rebuildDeps = true; /* get rid of shell type's dependencies */
} }
else else
{ {
@ -290,7 +308,6 @@ TypeCreate(const char *typeName,
* Create dependencies. We can/must skip this in bootstrap mode. * Create dependencies. We can/must skip this in bootstrap mode.
*/ */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
{
GenerateTypeDependencies(typeNamespace, GenerateTypeDependencies(typeNamespace,
typeObjectId, typeObjectId,
relationOid, relationOid,
@ -299,9 +316,10 @@ TypeCreate(const char *typeName,
outputProcedure, outputProcedure,
elementType, elementType,
baseType, baseType,
defaultTypeBin, (defaultTypeBin ?
false); stringToNode(defaultTypeBin) :
} (void *) NULL),
rebuildDeps);
/* /*
* finish up * finish up
@ -311,26 +329,30 @@ TypeCreate(const char *typeName,
return typeObjectId; return typeObjectId;
} }
/*
* 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.
*
* NOTE: a shell type will have a dependency to its namespace, and no others.
*/
void void
GenerateTypeDependencies(Oid typeNamespace, GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId, Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog typeType */ Oid relationOid, /* only for 'c'atalog types */
char relationKind, char relationKind, /* ditto */
Oid inputProcedure, Oid inputProcedure,
Oid outputProcedure, Oid outputProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
char *defaultTypeBin, /* cooked rep */ Node *defaultExpr,
bool rebuild) bool rebuild)
{ {
ObjectAddress myself, ObjectAddress myself,
referenced; referenced;
/*
* If true, we need to remove all current dependencies that the type
* holds, and rebuild them from scratch. This allows us to easily
* implement alter type, and alter domain statements.
*/
if (rebuild) if (rebuild)
deleteDependencyRecordsFor(RelOid_pg_type, deleteDependencyRecordsFor(RelOid_pg_type,
typeObjectId); typeObjectId);
@ -350,15 +372,21 @@ GenerateTypeDependencies(Oid typeNamespace,
} }
/* Normal dependencies on the I/O functions */ /* Normal dependencies on the I/O functions */
if (OidIsValid(inputProcedure))
{
referenced.classId = RelOid_pg_proc; referenced.classId = RelOid_pg_proc;
referenced.objectId = inputProcedure; referenced.objectId = inputProcedure;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(outputProcedure))
{
referenced.classId = RelOid_pg_proc; referenced.classId = RelOid_pg_proc;
referenced.objectId = outputProcedure; referenced.objectId = outputProcedure;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* /*
* If the type is a rowtype for a relation, mark it as internally * If the type is a rowtype for a relation, mark it as internally
@ -406,10 +434,9 @@ GenerateTypeDependencies(Oid typeNamespace,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
/* Dependency on the default expression */ /* Normal dependency on the default expression. */
if (defaultTypeBin) if (defaultExpr)
recordDependencyOnExpr(&myself, stringToNode(defaultTypeBin), recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
NIL, DEPENDENCY_NORMAL);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.27 2003/01/06 00:31:44 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.28 2003/01/08 21:40:39 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -1012,12 +1012,12 @@ AlterDomainDefault(List *names, Node *defaultRaw)
GenerateTypeDependencies(typTup->typnamespace, GenerateTypeDependencies(typTup->typnamespace,
domainoid, domainoid,
typTup->typrelid, typTup->typrelid,
InvalidOid, 0, /* relation kind is n/a */
typTup->typinput, typTup->typinput,
typTup->typoutput, typTup->typoutput,
typTup->typelem, typTup->typelem,
typTup->typbasetype, typTup->typbasetype,
nodeToString(defaultExpr), defaultExpr,
true); /* Rebuild is true */ true); /* Rebuild is true */
/* Clean up */ /* Clean up */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_type.h,v 1.137 2002/12/06 05:00:31 momjian Exp $ * $Id: pg_type.h,v 1.138 2003/01/08 21:40:39 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -19,6 +19,8 @@
#ifndef PG_TYPE_H #ifndef PG_TYPE_H
#define PG_TYPE_H #define PG_TYPE_H
#include "nodes/nodes.h"
/* ---------------- /* ----------------
* postgres.h contains the system type definitions and the * postgres.h contains the system type definitions and the
* CATALOG(), BOOTSTRAP and DATA() sugar words so this file * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
@ -558,21 +560,20 @@ extern Oid TypeCreate(const char *typeName,
int32 typNDims, int32 typNDims,
bool typeNotNull); bool typeNotNull);
extern void extern void GenerateTypeDependencies(Oid typeNamespace,
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId, Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog typeType */ Oid relationOid,
char relationKind, char relationKind,
Oid inputProcedure, Oid inputProcedure,
Oid outputProcedure, Oid outputProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
char *defaultTypeBin, /* cooked rep */ Node *defaultExpr,
bool rebuild); bool rebuild);
extern void TypeRename(const char *oldTypeName, Oid typeNamespace, extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
const char *newTypeName); const char *newTypeName);
extern char *makeArrayTypeName(const char *typeName); extern char *makeArrayTypeName(const char *typeName);
#endif /* PG_TYPE_H */ #endif /* PG_TYPE_H */