Tweak heap.c to refuse attempts to create table columns of standalone
authorTom Lane
Thu, 19 Sep 2002 23:40:56 +0000 (23:40 +0000)
committerTom Lane
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);