]> granicus.if.org Git - postgresql/commitdiff
Don't allocate storage for partitioned tables.
authorRobert Haas <rhaas@postgresql.org>
Fri, 31 Mar 2017 20:28:30 +0000 (16:28 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 31 Mar 2017 20:28:51 +0000 (16:28 -0400)
Also, don't allow setting reloptions on them, since that would have no
effect given the lack of storage.  The patch does this by introducing
a new reloption kind for which there are currently no reloptions -- we
might have some in the future -- so it adjusts parseRelOptions to
handle that case correctly.

Bumped catversion.  System catalogs that contained reloptions for
partitioned tables are no longer valid; plus, there are now fewer
physical files on disk, which is not technically a catalog change but
still a good reason to re-initdb.

Amit Langote, reviewed by Maksim Milyutin and Kyotaro Horiguchi and
revised a bit by me.

Discussion: http://postgr.es/m/20170331.173326.212311140.horiguchi.kyotaro@lab.ntt.co.jp

doc/src/sgml/ref/create_table.sgml
src/backend/access/common/reloptions.c
src/backend/catalog/heap.c
src/include/access/reloptions.h
src/include/catalog/catversion.h

index 283d53e203cef9bdee35be4a35ff0890a852817b..e1ec14e1c1bfe94cf0d895d624ab3db7d2eaa15a 100644 (file)
@@ -1038,6 +1038,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
     If a table parameter value is set and the
     equivalent <literal>toast.</literal> parameter is not, the TOAST table
     will use the table's parameter value.
+    Specifying these parameters for partitioned tables is not supported,
+    but you may specify them for individual leaf partitions.
    </para>
 
    <variablelist>
index 72e12532ab2934b9e6995f5a41f1600ea5fdf547..de7507aa68038cbead21d657acb67b0a238538bf 100644 (file)
@@ -1000,7 +1000,8 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
  * array; this is so that the caller can easily locate the default values.
  *
  * If there are no options of the given kind, numrelopts is set to 0 and NULL
- * is returned.
+ * is returned (unless options are illegally supplied despite none being
+ * defined, in which case an error occurs).
  *
  * Note: values of type int, bool and real are allocated as part of the
  * returned array.  Values of type string are allocated separately and must
@@ -1010,7 +1011,7 @@ relopt_value *
 parseRelOptions(Datum options, bool validate, relopt_kind kind,
                                int *numrelopts)
 {
-       relopt_value *reloptions;
+       relopt_value *reloptions = NULL;
        int                     numoptions = 0;
        int                     i;
        int                     j;
@@ -1024,21 +1025,18 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
                if (relOpts[i]->kinds & kind)
                        numoptions++;
 
-       if (numoptions == 0)
+       if (numoptions > 0)
        {
-               *numrelopts = 0;
-               return NULL;
-       }
+               reloptions = palloc(numoptions * sizeof(relopt_value));
 
-       reloptions = palloc(numoptions * sizeof(relopt_value));
-
-       for (i = 0, j = 0; relOpts[i]; i++)
-       {
-               if (relOpts[i]->kinds & kind)
+               for (i = 0, j = 0; relOpts[i]; i++)
                {
-                       reloptions[j].gen = relOpts[i];
-                       reloptions[j].isset = false;
-                       j++;
+                       if (relOpts[i]->kinds & kind)
+                       {
+                               reloptions[j].gen = relOpts[i];
+                               reloptions[j].isset = false;
+                               j++;
+                       }
                }
        }
 
@@ -1418,8 +1416,10 @@ heap_reloptions(char relkind, Datum reloptions, bool validate)
                        return (bytea *) rdopts;
                case RELKIND_RELATION:
                case RELKIND_MATVIEW:
-               case RELKIND_PARTITIONED_TABLE:
                        return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
+               case RELKIND_PARTITIONED_TABLE:
+                       return default_reloptions(reloptions, validate,
+                                                                         RELOPT_KIND_PARTITIONED);
                default:
                        /* other relkinds are not supported */
                        return NULL;
index eee5e2f6caf378ca94f9f2f6b80786148a0b2bde..1cbe7f907ff3bab34b912cda288328f2ebffb9ab 100644 (file)
@@ -293,6 +293,7 @@ heap_create(const char *relname,
                case RELKIND_VIEW:
                case RELKIND_COMPOSITE_TYPE:
                case RELKIND_FOREIGN_TABLE:
+               case RELKIND_PARTITIONED_TABLE:
                        create_storage = false;
 
                        /*
@@ -1347,14 +1348,13 @@ heap_create_with_catalog(const char *relname,
        if (oncommit != ONCOMMIT_NOOP)
                register_on_commit_action(relid, oncommit);
 
-       if (relpersistence == RELPERSISTENCE_UNLOGGED)
-       {
-               Assert(relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW ||
-                          relkind == RELKIND_TOASTVALUE ||
-                          relkind == RELKIND_PARTITIONED_TABLE);
-
+       /*
+        * Unlogged objects need an init fork, except for partitioned tables which
+        * have no storage at all.
+        */
+       if (relpersistence == RELPERSISTENCE_UNLOGGED &&
+               relkind != RELKIND_PARTITIONED_TABLE)
                heap_create_init_fork(new_rel_desc);
-       }
 
        /*
         * ok, the relation has been cataloged, so close our relations and return
@@ -1378,6 +1378,9 @@ heap_create_with_catalog(const char *relname,
 void
 heap_create_init_fork(Relation rel)
 {
+       Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
+                  rel->rd_rel->relkind == RELKIND_MATVIEW ||
+                  rel->rd_rel->relkind == RELKIND_TOASTVALUE);
        RelationOpenSmgr(rel);
        smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
        log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
@@ -1824,7 +1827,8 @@ heap_drop_with_catalog(Oid relid)
         */
        if (rel->rd_rel->relkind != RELKIND_VIEW &&
                rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
-               rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
+               rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
+               rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
        {
                RelationDropStorage(rel);
        }
index 861977a608327e64ecb6ec8e052021b7ea860793..91b2cd7bb2faa436821af06211a68459877c40f8 100644 (file)
@@ -48,8 +48,9 @@ typedef enum relopt_kind
        RELOPT_KIND_SPGIST = (1 << 8),
        RELOPT_KIND_VIEW = (1 << 9),
        RELOPT_KIND_BRIN = (1 << 10),
+       RELOPT_KIND_PARTITIONED = (1 << 11),
        /* if you add a new kind, make sure you update "last_default" too */
-       RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_BRIN,
+       RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED,
        /* some compilers treat enums as signed ints, so we can't use 1 << 31 */
        RELOPT_KIND_MAX = (1 << 30)
 } relopt_kind;
index bee5711da8815b7c0f53c0349f00d9a895f6945e..d067b757b0f9c09649fe741f2dc7684ff41ed14d 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201703292
+#define CATALOG_VERSION_NO     201703311
 
 #endif