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
This commit is contained in:
parent
f49bcd4ef3
commit
c94e6942ce
@ -1038,6 +1038,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
|||||||
If a table parameter value is set and the
|
If a table parameter value is set and the
|
||||||
equivalent <literal>toast.</literal> parameter is not, the TOAST table
|
equivalent <literal>toast.</literal> parameter is not, the TOAST table
|
||||||
will use the table's parameter value.
|
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>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
@ -1000,7 +1000,8 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
|
|||||||
* array; this is so that the caller can easily locate the default values.
|
* 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
|
* 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
|
* 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
|
* 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,
|
parseRelOptions(Datum options, bool validate, relopt_kind kind,
|
||||||
int *numrelopts)
|
int *numrelopts)
|
||||||
{
|
{
|
||||||
relopt_value *reloptions;
|
relopt_value *reloptions = NULL;
|
||||||
int numoptions = 0;
|
int numoptions = 0;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
@ -1024,21 +1025,18 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
|
|||||||
if (relOpts[i]->kinds & kind)
|
if (relOpts[i]->kinds & kind)
|
||||||
numoptions++;
|
numoptions++;
|
||||||
|
|
||||||
if (numoptions == 0)
|
if (numoptions > 0)
|
||||||
{
|
{
|
||||||
*numrelopts = 0;
|
reloptions = palloc(numoptions * sizeof(relopt_value));
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
reloptions = palloc(numoptions * sizeof(relopt_value));
|
for (i = 0, j = 0; relOpts[i]; i++)
|
||||||
|
|
||||||
for (i = 0, j = 0; relOpts[i]; i++)
|
|
||||||
{
|
|
||||||
if (relOpts[i]->kinds & kind)
|
|
||||||
{
|
{
|
||||||
reloptions[j].gen = relOpts[i];
|
if (relOpts[i]->kinds & kind)
|
||||||
reloptions[j].isset = false;
|
{
|
||||||
j++;
|
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;
|
return (bytea *) rdopts;
|
||||||
case RELKIND_RELATION:
|
case RELKIND_RELATION:
|
||||||
case RELKIND_MATVIEW:
|
case RELKIND_MATVIEW:
|
||||||
case RELKIND_PARTITIONED_TABLE:
|
|
||||||
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
|
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
|
||||||
|
case RELKIND_PARTITIONED_TABLE:
|
||||||
|
return default_reloptions(reloptions, validate,
|
||||||
|
RELOPT_KIND_PARTITIONED);
|
||||||
default:
|
default:
|
||||||
/* other relkinds are not supported */
|
/* other relkinds are not supported */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -293,6 +293,7 @@ heap_create(const char *relname,
|
|||||||
case RELKIND_VIEW:
|
case RELKIND_VIEW:
|
||||||
case RELKIND_COMPOSITE_TYPE:
|
case RELKIND_COMPOSITE_TYPE:
|
||||||
case RELKIND_FOREIGN_TABLE:
|
case RELKIND_FOREIGN_TABLE:
|
||||||
|
case RELKIND_PARTITIONED_TABLE:
|
||||||
create_storage = false;
|
create_storage = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1347,14 +1348,13 @@ heap_create_with_catalog(const char *relname,
|
|||||||
if (oncommit != ONCOMMIT_NOOP)
|
if (oncommit != ONCOMMIT_NOOP)
|
||||||
register_on_commit_action(relid, oncommit);
|
register_on_commit_action(relid, oncommit);
|
||||||
|
|
||||||
if (relpersistence == RELPERSISTENCE_UNLOGGED)
|
/*
|
||||||
{
|
* Unlogged objects need an init fork, except for partitioned tables which
|
||||||
Assert(relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW ||
|
* have no storage at all.
|
||||||
relkind == RELKIND_TOASTVALUE ||
|
*/
|
||||||
relkind == RELKIND_PARTITIONED_TABLE);
|
if (relpersistence == RELPERSISTENCE_UNLOGGED &&
|
||||||
|
relkind != RELKIND_PARTITIONED_TABLE)
|
||||||
heap_create_init_fork(new_rel_desc);
|
heap_create_init_fork(new_rel_desc);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ok, the relation has been cataloged, so close our relations and return
|
* ok, the relation has been cataloged, so close our relations and return
|
||||||
@ -1378,6 +1378,9 @@ heap_create_with_catalog(const char *relname,
|
|||||||
void
|
void
|
||||||
heap_create_init_fork(Relation rel)
|
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);
|
RelationOpenSmgr(rel);
|
||||||
smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
|
smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
|
||||||
log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
|
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 &&
|
if (rel->rd_rel->relkind != RELKIND_VIEW &&
|
||||||
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
|
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);
|
RelationDropStorage(rel);
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,9 @@ typedef enum relopt_kind
|
|||||||
RELOPT_KIND_SPGIST = (1 << 8),
|
RELOPT_KIND_SPGIST = (1 << 8),
|
||||||
RELOPT_KIND_VIEW = (1 << 9),
|
RELOPT_KIND_VIEW = (1 << 9),
|
||||||
RELOPT_KIND_BRIN = (1 << 10),
|
RELOPT_KIND_BRIN = (1 << 10),
|
||||||
|
RELOPT_KIND_PARTITIONED = (1 << 11),
|
||||||
/* if you add a new kind, make sure you update "last_default" too */
|
/* 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 */
|
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
|
||||||
RELOPT_KIND_MAX = (1 << 30)
|
RELOPT_KIND_MAX = (1 << 30)
|
||||||
} relopt_kind;
|
} relopt_kind;
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201703292
|
#define CATALOG_VERSION_NO 201703311
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user