Commit c94e6942 authored by Robert Haas's avatar Robert Haas

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
parent f49bcd4e
......@@ -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>
......
......@@ -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,12 +1025,8 @@ 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));
for (i = 0, j = 0; relOpts[i]; i++)
......@@ -1041,6 +1038,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
j++;
}
}
}
/* Done if no options */
if (PointerIsValid(DatumGetPointer(options)))
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201703292
#define CATALOG_VERSION_NO 201703311
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment