]> granicus.if.org Git - postgresql/commitdiff
Fix incorrect Assert; install a more trustworthy check on whether
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 22 Apr 2002 21:46:11 +0000 (21:46 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 22 Apr 2002 21:46:11 +0000 (21:46 +0000)
ALTER COLUMN SET STORAGE should be allowed.

src/backend/commands/tablecmds.c

index 84e1ae40a5e218ade058335f5b306f997ce49e65..49170afd5cb1bed1862fcaa44c55daa868d06d62 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.5 2002/04/19 23:13:54 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.6 2002/04/22 21:46:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -771,10 +771,10 @@ AlterTableAlterColumnFlags(Oid myrelid,
 {
        Relation        rel;
        int                     newtarget = 1;
-       char        newstorage = 'x';
-       char        *storagemode;
+       char        newstorage = 'p';
        Relation        attrelation;
        HeapTuple       tuple;
+       Form_pg_attribute attrtuple;
 
        rel = heap_open(myrelid, AccessExclusiveLock);
 
@@ -813,9 +813,11 @@ AlterTableAlterColumnFlags(Oid myrelid,
        else if (*flagType == 'M')
        {
                /* STORAGE */
-               Assert(IsA(flagValue, Value));
+               char        *storagemode;
 
+               Assert(IsA(flagValue, String));
                storagemode = strVal(flagValue);
+
                if (strcasecmp(storagemode, "plain") == 0)
                        newstorage = 'p';
                else if (strcasecmp(storagemode, "external") == 0)
@@ -872,26 +874,30 @@ AlterTableAlterColumnFlags(Oid myrelid,
        if (!HeapTupleIsValid(tuple))
                elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
                         RelationGetRelationName(rel), colName);
+       attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
 
-       if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0)
+       if (attrtuple->attnum < 0)
                elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"",
                         colName);
        /*
         * Now change the appropriate field
         */
        if (*flagType == 'S')
-               ((Form_pg_attribute) GETSTRUCT(tuple))->attstattarget = newtarget;
-       else
+               attrtuple->attstattarget = newtarget;
+       else if (*flagType == 'M')
        {
-               if ((newstorage == 'p') ||
-                       (((Form_pg_attribute) GETSTRUCT(tuple))->attlen == -1))
-                       ((Form_pg_attribute) GETSTRUCT(tuple))->attstorage = newstorage;
+               /*
+                * safety check: do not allow toasted storage modes unless column
+                * datatype is TOAST-aware.  We assume the datatype's typstorage
+                * will be 'p' if and only if it ain't TOAST-aware.
+                */
+               if (newstorage == 'p' || get_typstorage(attrtuple->atttypid) != 'p')
+                       attrtuple->attstorage = newstorage;
                else
-               {
-                       elog(ERROR,
-                                "ALTER TABLE: Fixed-length columns can only have storage \"plain\"");
-               }
+                       elog(ERROR, "ALTER TABLE: Column datatype %s can only have storage \"plain\"",
+                                format_type_be(attrtuple->atttypid));
        }
+
        simple_heap_update(attrelation, &tuple->t_self, tuple);
 
        /* keep system catalog indices current */