Make chunks inherit reloptions set on the hypertable

When tables are created with storage parameters (reloptions),
these should be inherited by chunks so that one can set options
such as fillfactor and autovacuum settings on the hypertable.
This change makes chunks inherit the reloptions set on a hypertable
and allows altering options via the ALTER TABLE command.
This commit is contained in:
Erik Nordström 2017-12-14 11:40:24 +01:00 committed by Erik Nordström
parent 4df8f287a6
commit 68faddca24
5 changed files with 134 additions and 0 deletions

View File

@ -9,9 +9,11 @@
#include <access/htup.h>
#include <access/htup_details.h>
#include <access/xact.h>
#include <access/reloptions.h>
#include <nodes/makefuncs.h>
#include <utils/builtins.h>
#include <utils/lsyscache.h>
#include <utils/syscache.h>
#include <utils/hsearch.h>
#include <miscadmin.h>
@ -343,6 +345,29 @@ chunk_add_constraints(Chunk *chunk)
return num_added;
}
static List *
get_reloptions(Oid relid)
{
HeapTuple tuple;
Datum datum;
bool isnull;
List *options;
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", relid);
datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
&isnull);
options = untransformRelOptions(datum);
ReleaseSysCache(tuple);
return options;
}
/*
* Create a chunk's table.
*
@ -376,6 +401,7 @@ chunk_create_table(Chunk *chunk, Hypertable *ht)
.relation = makeRangeVar(NameStr(chunk->fd.schema_name), NameStr(chunk->fd.table_name), 0),
.inhRelations = list_make1(makeRangeVar(NameStr(ht->fd.schema_name), NameStr(ht->fd.table_name), 0)),
.tablespacename = hypertable_select_tablespace(ht, chunk),
.options = get_reloptions(ht->main_table_relid),
};
Oid uid,
saved_uid;

View File

@ -1187,6 +1187,19 @@ process_alter_column_type_end(Hypertable *ht, AlterTableCmd *cmd)
process_utility_set_expect_chunk_modification(false);
}
/*
* Generic function to recurse ALTER TABLE commands to chunks.
*
* Call with foreach_chunk().
*/
static void
process_altertable_chunk(Hypertable *ht, Oid chunk_relid, void *arg)
{
AlterTableCmd *cmd = arg;
AlterTableInternal(chunk_relid, list_make1(cmd), false);
}
static void
process_altertable_end_index(Node *parsetree, CollectedCommand *cmd)
{
@ -1374,6 +1387,13 @@ process_altertable_end_subcmd(Hypertable *ht, Node *parsetree, ObjectAddress *ob
Assert(IsA(cmd->def, ColumnDef));
process_alter_column_type_end(ht, cmd);
break;
case AT_SetRelOptions:
case AT_ResetRelOptions:
case AT_ReplaceRelOptions:
case AT_AddOids:
case AT_DropOids:
foreach_chunk(ht, process_altertable_chunk, cmd);
break;
default:
break;
}

View File

@ -0,0 +1,56 @@
CREATE TABLE reloptions_test(time integer, temp float8, color integer)
WITH (fillfactor=75, oids=true, autovacuum_vacuum_threshold=100);
SELECT create_hypertable('reloptions_test', 'time', chunk_time_interval => 3);
NOTICE: Adding NOT NULL constraint to time column time (NULL time values not allowed)
create_hypertable
-------------------
(1 row)
INSERT INTO reloptions_test VALUES (4, 24.3, 1), (9, 13.3, 2);
-- Show that reloptions are inherited by chunks
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
relname | reloptions | relhasoids
------------------+-------------------------------------------------+------------
_hyper_1_1_chunk | {fillfactor=75,autovacuum_vacuum_threshold=100} | t
_hyper_1_2_chunk | {fillfactor=75,autovacuum_vacuum_threshold=100} | t
(2 rows)
-- Alter reloptions
ALTER TABLE reloptions_test SET (fillfactor=80, parallel_workers=8);
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
relname | reloptions | relhasoids
------------------+--------------------------------------------------------------------+------------
_hyper_1_1_chunk | {autovacuum_vacuum_threshold=100,fillfactor=80,parallel_workers=8} | t
_hyper_1_2_chunk | {autovacuum_vacuum_threshold=100,fillfactor=80,parallel_workers=8} | t
(2 rows)
ALTER TABLE reloptions_test RESET (fillfactor);
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
relname | reloptions | relhasoids
------------------+------------------------------------------------------+------------
_hyper_1_1_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | t
_hyper_1_2_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | t
(2 rows)
ALTER TABLE reloptions_test SET WITHOUT OIDS;
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
relname | reloptions | relhasoids
------------------+------------------------------------------------------+------------
_hyper_1_1_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | f
_hyper_1_2_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | f
(2 rows)
ALTER TABLE reloptions_test SET WITH OIDS;
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
relname | reloptions | relhasoids
------------------+------------------------------------------------------+------------
_hyper_1_1_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | t
_hyper_1_2_chunk | {autovacuum_vacuum_threshold=100,parallel_workers=8} | t
(2 rows)

View File

@ -33,6 +33,7 @@ set(TEST_FILES
plain.sql
reindex.sql
relocate_extension.sql
reloptions.sql
size_utils.sql
sql_query_results_optimized.sql
sql_query_results_unoptimized.sql

31
test/sql/reloptions.sql Normal file
View File

@ -0,0 +1,31 @@
CREATE TABLE reloptions_test(time integer, temp float8, color integer)
WITH (fillfactor=75, oids=true, autovacuum_vacuum_threshold=100);
SELECT create_hypertable('reloptions_test', 'time', chunk_time_interval => 3);
INSERT INTO reloptions_test VALUES (4, 24.3, 1), (9, 13.3, 2);
-- Show that reloptions are inherited by chunks
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
-- Alter reloptions
ALTER TABLE reloptions_test SET (fillfactor=80, parallel_workers=8);
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
ALTER TABLE reloptions_test RESET (fillfactor);
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
ALTER TABLE reloptions_test SET WITHOUT OIDS;
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';
ALTER TABLE reloptions_test SET WITH OIDS;
SELECT relname, reloptions, relhasoids FROM pg_class
WHERE relname ~ '^_hyper.*' AND relkind = 'r';