Tweak heap.c to refuse attempts to create table columns of standalone
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 19 Sep 2002 23:40:56 +0000 (23:40 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 19 Sep 2002 23:40:56 +0000 (23:40 +0000)
composite types.  Add a couple more lsyscache.c routines to support this,
and make use of them in some other places that were doing lookups the
hard way.

src/backend/catalog/dependency.c
src/backend/catalog/heap.c
src/backend/commands/indexcmds.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/cache/lsyscache.c
src/include/utils/lsyscache.h

index 53ad37bd61ad5d748c25740c2ae2a0adb85728b1..67e60e1636827e7265d159127c421b2f257544eb 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.10 2002/09/11 14:48:54 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.11 2002/09/19 23:40:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -552,20 +552,7 @@ doDeletion(const ObjectAddress *object)
        {
                case OCLASS_CLASS:
                        {
-                               HeapTuple       relTup;
-                               char            relKind;
-
-                               /*
-                                * Need the relkind to figure out how to drop.
-                                */
-                               relTup = SearchSysCache(RELOID,
-                                                                         ObjectIdGetDatum(object->objectId),
-                                                                               0, 0, 0);
-                               if (!HeapTupleIsValid(relTup))
-                                       elog(ERROR, "doDeletion: Relation %u does not exist",
-                                                object->objectId);
-                               relKind = ((Form_pg_class) GETSTRUCT(relTup))->relkind;
-                               ReleaseSysCache(relTup);
+                               char            relKind = get_rel_relkind(object->objectId);
 
                                if (relKind == RELKIND_INDEX)
                                {
@@ -1504,6 +1491,10 @@ getRelationDescription(StringInfo buffer, Oid relid)
                        appendStringInfo(buffer, "view %s",
                                                         relname);
                        break;
+               case RELKIND_COMPOSITE_TYPE:
+                       appendStringInfo(buffer, "composite type %s",
+                                                        relname);
+                       break;
                default:
                        /* shouldn't get here */
                        appendStringInfo(buffer, "relation %s",
index 426e81d220ae00cb8b3dbab27e93a1d6f1c2cc8e..3b495b010879aa55a27114925cb6f07edb319358 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.228 2002/09/19 22:48:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.229 2002/09/19 23:40:56 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -384,20 +384,33 @@ CheckAttributeNames(TupleDesc tupdesc, char relkind)
         * Warn user, but don't fail, if column to be created has UNKNOWN type
         * (usually as a result of a 'retrieve into' - jolly)
         *
-        * Refuse any attempt to create a pseudo-type column.
+        * Refuse any attempt to create a pseudo-type column or one that uses
+        * a standalone composite type.  (Eventually we should probably refuse
+        * all references to complex types, but for now there's still some
+        * Berkeley-derived code that thinks it can do this...)
         */
        for (i = 0; i < natts; i++)
        {
                Oid                     att_type = tupdesc->attrs[i]->atttypid;
+               char            att_typtype = get_typtype(att_type);
 
                if (att_type == UNKNOWNOID)
                        elog(WARNING, "Attribute \"%s\" has an unknown type"
                                 "\n\tProceeding with relation creation anyway",
                                 NameStr(tupdesc->attrs[i]->attname));
-               if (get_typtype(att_type) == 'p')
+               if (att_typtype == 'p')
                        elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
                                 NameStr(tupdesc->attrs[i]->attname),
                                 format_type_be(att_type));
+               if (att_typtype == 'c')
+               {
+                       Oid             typrelid = get_typ_typrelid(att_type);
+
+                       if (get_rel_relkind(typrelid) == RELKIND_COMPOSITE_TYPE)
+                               elog(ERROR, "Attribute \"%s\" has composite type %s",
+                                        NameStr(tupdesc->attrs[i]->attname),
+                                        format_type_be(att_type));
+               }
        }
 }
 
index 9660cb61b83e468d5ddb5dab0d0e183f73fbb5ca..88c0b5cdb64bf7028606f7d3354b2ad4336e6049 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.88 2002/09/18 21:35:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.89 2002/09/19 23:40:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -535,21 +535,14 @@ void
 RemoveIndex(RangeVar *relation, DropBehavior behavior)
 {
        Oid                     indOid;
-       HeapTuple       tuple;
+       char            relkind;
        ObjectAddress object;
 
        indOid = RangeVarGetRelid(relation, false);
-       tuple = SearchSysCache(RELOID,
-                                                  ObjectIdGetDatum(indOid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "index \"%s\" does not exist", relation->relname);
-
-       if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
+       relkind = get_rel_relkind(indOid);
+       if (relkind != RELKIND_INDEX)
                elog(ERROR, "relation \"%s\" is of type \"%c\"",
-                relation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
-
-       ReleaseSysCache(tuple);
+                        relation->relname, relkind);
 
        object.classId = RelOid_pg_class;
        object.objectId = indOid;
@@ -616,7 +609,6 @@ void
 ReindexTable(RangeVar *relation, bool force)
 {
        Oid                     heapOid;
-       HeapTuple       tuple;
        char            relkind;
 
        /*
@@ -628,19 +620,12 @@ ReindexTable(RangeVar *relation, bool force)
                elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
 
        heapOid = RangeVarGetRelid(relation, false);
-       tuple = SearchSysCache(RELOID,
-                                                  ObjectIdGetDatum(heapOid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "table \"%s\" does not exist", relation->relname);
-       relkind = ((Form_pg_class) GETSTRUCT(tuple))->relkind;
+       relkind = get_rel_relkind(heapOid);
 
        if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
                elog(ERROR, "relation \"%s\" is of type \"%c\"",
                         relation->relname, relkind);
 
-       ReleaseSysCache(tuple);
-
        if (!reindex_relation(heapOid, force))
                elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname);
 }
index 47f61865fc397af1355ce0e6e89fbddc69c6414c..796eaa05069b07e56d32d9d7324033e32752878c 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.123 2002/09/19 22:48:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.124 2002/09/19 23:40:56 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -2087,24 +2087,14 @@ get_rule_expr(Node *node, deparse_context *context,
                        {
                                FieldSelect *fselect = (FieldSelect *) node;
                                Oid                     argType = exprType(fselect->arg);
-                               HeapTuple       typetup;
-                               Form_pg_type typeStruct;
                                Oid                     typrelid;
                                char       *fieldname;
 
                                /* lookup arg type and get the field name */
-                               typetup = SearchSysCache(TYPEOID,
-                                                                                ObjectIdGetDatum(argType),
-                                                                                0, 0, 0);
-                               if (!HeapTupleIsValid(typetup))
-                                       elog(ERROR, "cache lookup of type %u failed",
-                                                argType);
-                               typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-                               typrelid = typeStruct->typrelid;
+                               typrelid = get_typ_typrelid(argType);
                                if (!OidIsValid(typrelid))
                                        elog(ERROR, "Argument type %s of FieldSelect is not a tuple type",
                                                 format_type_be(argType));
-                               ReleaseSysCache(typetup);
                                fieldname = get_relid_attribute_name(typrelid,
                                                                                                         fselect->fieldnum);
 
index c8a038d8a7d752fd63bbf9df5c049e17d20d2fd5..ae77dacd13a8b25e9cbf2d0e38a8a3d21b315f21 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.84 2002/09/18 21:35:23 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.85 2002/09/19 23:40:56 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -776,6 +776,33 @@ get_rel_type_id(Oid relid)
                return InvalidOid;
 }
 
+/*
+ * get_rel_relkind
+ *
+ *             Returns the relkind associated with a given relation.
+ */
+char
+get_rel_relkind(Oid relid)
+{
+       HeapTuple       tp;
+
+       tp = SearchSysCache(RELOID,
+                                               ObjectIdGetDatum(relid),
+                                               0, 0, 0);
+       if (HeapTupleIsValid(tp))
+       {
+               Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+               char            result;
+
+               result = reltup->relkind;
+               ReleaseSysCache(tp);
+               return result;
+       }
+       else
+               return '\0';
+}
+
+
 /*                             ---------- TYPE CACHE ----------                                                 */
 
 /*
@@ -1153,6 +1180,33 @@ get_typtype(Oid typid)
                return '\0';
 }
 
+/*
+ * get_typ_typrelid
+ *
+ *             Given the type OID, get the typrelid (InvalidOid if not a complex
+ *             type).
+ */
+Oid
+get_typ_typrelid(Oid typid)
+{
+       HeapTuple       tp;
+
+       tp = SearchSysCache(TYPEOID,
+                                               ObjectIdGetDatum(typid),
+                                               0, 0, 0);
+       if (HeapTupleIsValid(tp))
+       {
+               Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+               Oid                     result;
+
+               result = typtup->typrelid;
+               ReleaseSysCache(tp);
+               return result;
+       }
+       else
+               return InvalidOid;
+}
+
 /*
  * getTypeInputInfo
  *
index 5dee7bc0cbb8bdd3b0e2f96c00894ffa58edc117..ff88d30e73d0593ad68b9f1d0f67dd2122a1c352 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.63 2002/09/18 21:35:25 tgl Exp $
+ * $Id: lsyscache.h,v 1.64 2002/09/19 23:40:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,6 +45,7 @@ extern Oid    get_system_catalog_relid(const char *catname);
 extern char *get_rel_name(Oid relid);
 extern Oid     get_rel_namespace(Oid relid);
 extern Oid     get_rel_type_id(Oid relid);
+extern char get_rel_relkind(Oid relid);
 extern bool get_typisdefined(Oid typid);
 extern int16 get_typlen(Oid typid);
 extern bool get_typbyval(Oid typid);
@@ -54,6 +55,7 @@ extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
 extern char get_typstorage(Oid typid);
 extern Node *get_typdefault(Oid typid);
 extern char get_typtype(Oid typid);
+extern Oid     get_typ_typrelid(Oid typid);
 extern void getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem);
 extern bool getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem,
                                  bool *typIsVarlena);