From c94e6942cefe7d20c5feed856e27f672734b1e2b Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 31 Mar 2017 16:28:30 -0400 Subject: [PATCH] Don't allocate storage for partitioned tables. 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 | 2 ++ src/backend/access/common/reloptions.c | 30 +++++++++++++------------- src/backend/catalog/heap.c | 20 ++++++++++------- src/include/access/reloptions.h | 3 ++- src/include/catalog/catversion.h | 2 +- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 283d53e203..e1ec14e1c1 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1038,6 +1038,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI If a table parameter value is set and the equivalent toast. 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. diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 72e12532ab..de7507aa68 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -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; diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index eee5e2f6ca..1cbe7f907f 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -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); } diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index 861977a608..91b2cd7bb2 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -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; diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index bee5711da8..d067b757b0 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201703292 +#define CATALOG_VERSION_NO 201703311 #endif -- 2.40.0