mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 01:53:41 +08:00
Block most DDL on hypertable with compression
Block most DDL commands on hypertables with compression enabled. This restriction will be relaxed over time. The only alter table commands currently allowed are: Add/Remove index, Set storage options, clustering index, set statistics and set tablespace. We also disallow reseting compression options.
This commit is contained in:
parent
91a73c3e17
commit
a399a57af9
@ -74,6 +74,7 @@ static ProcessUtility_hook_type prev_ProcessUtility_hook;
|
||||
|
||||
static bool expect_chunk_modification = false;
|
||||
static bool process_altertable_set_options(AlterTableCmd *cmd, Hypertable *ht);
|
||||
static bool process_altertable_reset_options(AlterTableCmd *cmd, Hypertable *ht);
|
||||
|
||||
/* Call the default ProcessUtility and handle PostgreSQL version differences */
|
||||
static void
|
||||
@ -196,6 +197,59 @@ check_continuous_agg_alter_table_allowed(Hypertable *ht, AlterTableStmt *stmt)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_alter_table_allowed_on_ht_with_compression(Hypertable *ht, AlterTableStmt *stmt)
|
||||
{
|
||||
ListCell *lc;
|
||||
if (ht->fd.compressed_hypertable_id == INVALID_HYPERTABLE_ID)
|
||||
return;
|
||||
|
||||
/* only allow if all commands are allowed */
|
||||
foreach (lc, stmt->cmds)
|
||||
{
|
||||
AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lc);
|
||||
|
||||
switch (cmd->subtype)
|
||||
{
|
||||
/*
|
||||
* ALLOWED:
|
||||
*/
|
||||
case AT_AddIndex:
|
||||
case AT_ReAddIndex:
|
||||
case AT_ResetRelOptions:
|
||||
case AT_ReplaceRelOptions:
|
||||
case AT_SetRelOptions:
|
||||
case AT_ClusterOn:
|
||||
case AT_DropCluster:
|
||||
/* allow now, improve later */
|
||||
case AT_SetStatistics: /* pass statistics down to compressed? */
|
||||
case AT_SetTableSpace: /* pass down to compressed as well */
|
||||
/* allowed on materialization tables */
|
||||
continue;
|
||||
/*
|
||||
* BLOCKED:
|
||||
*/
|
||||
/* should be implemented later */
|
||||
case AT_ChangeOwner:
|
||||
/* definitely block */
|
||||
case AT_AddOids:
|
||||
case AT_DropOids:
|
||||
case AT_AddOidsRecurse:
|
||||
case AT_EnableRowSecurity:
|
||||
case AT_DisableRowSecurity:
|
||||
case AT_ForceRowSecurity:
|
||||
case AT_NoForceRowSecurity:
|
||||
default:
|
||||
/* blocked by default */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("operation not supported on hypertables that have compression "
|
||||
"enabled")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
relation_not_only(RangeVar *rv)
|
||||
{
|
||||
@ -2266,6 +2320,7 @@ process_altertable_start_table(ProcessUtilityArgs *args)
|
||||
{
|
||||
ts_hypertable_permissions_check_by_id(ht->fd.id);
|
||||
check_continuous_agg_alter_table_allowed(ht, stmt);
|
||||
check_alter_table_allowed_on_ht_with_compression(ht, stmt);
|
||||
relation_not_only(stmt->relation);
|
||||
process_add_hypertable(args, ht);
|
||||
}
|
||||
@ -2362,7 +2417,10 @@ process_altertable_start_table(ProcessUtilityArgs *args)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AT_ResetRelOptions:
|
||||
case AT_ReplaceRelOptions:
|
||||
process_altertable_reset_options(cmd, ht);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2805,6 +2863,25 @@ process_altertable_set_options(AlterTableCmd *cmd, Hypertable *ht)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_altertable_reset_options(AlterTableCmd *cmd, Hypertable *ht)
|
||||
{
|
||||
List *pg_options = NIL, *compress_options = NIL;
|
||||
List *inpdef = NIL;
|
||||
/* is this a compress table stmt */
|
||||
Assert(IsA(cmd->def, List));
|
||||
inpdef = (List *) cmd->def;
|
||||
ts_with_clause_filter(inpdef, &compress_options, &pg_options);
|
||||
if (compress_options)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("compression options cannot be reset")));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_viewstmt(ProcessUtilityArgs *args)
|
||||
{
|
||||
|
@ -38,11 +38,8 @@ NOTICE: adding not-null constraint to column "Time"
|
||||
|
||||
INSERT INTO test1 SELECT t, gen_rand_minstd(), gen_rand_minstd(), gen_rand_minstd()::text FROM generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-28 1:00', '1 hour') t;
|
||||
ALTER TABLE test1 set (timescaledb.compress, timescaledb.compress_segmentby = '', timescaledb.compress_orderby = '"Time" DESC');
|
||||
--
|
||||
-- DROP CHUNKS
|
||||
--
|
||||
SELECT COUNT(*) AS count_compressed
|
||||
FROM
|
||||
FROM
|
||||
(
|
||||
SELECT compress_chunk(chunk.schema_name|| '.' || chunk.table_name)
|
||||
FROM _timescaledb_catalog.chunk chunk
|
||||
@ -55,6 +52,17 @@ AS sub;
|
||||
27
|
||||
(1 row)
|
||||
|
||||
--make sure allowed ddl still work
|
||||
ALTER TABLE test1 CLUSTER ON "test1_Time_idx";
|
||||
ALTER TABLE test1 SET WITHOUT CLUSTER;
|
||||
CREATE INDEX new_index ON test1(b);
|
||||
DROP INDEX new_index;
|
||||
ALTER TABLE test1 SET (fillfactor=100);
|
||||
ALTER TABLE test1 RESET (fillfactor);
|
||||
ALTER TABLE test1 ALTER COLUMN b SET STATISTICS 10;
|
||||
--
|
||||
-- DROP CHUNKS
|
||||
--
|
||||
SELECT count(*) as count_chunks_uncompressed
|
||||
FROM _timescaledb_catalog.chunk chunk
|
||||
INNER JOIN _timescaledb_catalog.hypertable hypertable ON (chunk.hypertable_id = hypertable.id)
|
||||
|
@ -137,6 +137,17 @@ ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, p'
|
||||
ERROR: invalid order by column type: could not identify an less-than operator for type point
|
||||
--should succeed
|
||||
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, b');
|
||||
--ddl on ht with compression
|
||||
ALTER TABLE foo ADD COLUMN new_column INT;
|
||||
ERROR: operation not supported on hypertables that have compression enabled
|
||||
ALTER TABLE foo DROP COLUMN a;
|
||||
ERROR: operation not supported on hypertables that have compression enabled
|
||||
ALTER TABLE foo DROP COLUMN t;
|
||||
ERROR: operation not supported on hypertables that have compression enabled
|
||||
ALTER TABLE foo ALTER COLUMN t SET NOT NULL;
|
||||
ERROR: operation not supported on hypertables that have compression enabled
|
||||
ALTER TABLE foo RESET (timescaledb.compress);
|
||||
ERROR: compression options cannot be reset
|
||||
--note that the time column "a" should not be added to the end of the order by list again (should appear first)
|
||||
select hc.* from _timescaledb_catalog.hypertable_compression hc inner join _timescaledb_catalog.hypertable h on (h.id = hc.hypertable_id) where h.table_name = 'foo' order by attname;
|
||||
hypertable_id | attname | compression_algorithm_id | segmentby_column_index | orderby_column_index | orderby_asc | orderby_nullsfirst
|
||||
|
@ -14,11 +14,9 @@ INSERT INTO test1 SELECT t, gen_rand_minstd(), gen_rand_minstd(), gen_rand_mins
|
||||
|
||||
ALTER TABLE test1 set (timescaledb.compress, timescaledb.compress_segmentby = '', timescaledb.compress_orderby = '"Time" DESC');
|
||||
|
||||
--
|
||||
-- DROP CHUNKS
|
||||
--
|
||||
|
||||
SELECT COUNT(*) AS count_compressed
|
||||
FROM
|
||||
FROM
|
||||
(
|
||||
SELECT compress_chunk(chunk.schema_name|| '.' || chunk.table_name)
|
||||
FROM _timescaledb_catalog.chunk chunk
|
||||
@ -28,6 +26,19 @@ WHERE hypertable.table_name like 'test1' and chunk.compressed_chunk_id IS NULL O
|
||||
AS sub;
|
||||
|
||||
|
||||
--make sure allowed ddl still work
|
||||
ALTER TABLE test1 CLUSTER ON "test1_Time_idx";
|
||||
ALTER TABLE test1 SET WITHOUT CLUSTER;
|
||||
CREATE INDEX new_index ON test1(b);
|
||||
DROP INDEX new_index;
|
||||
ALTER TABLE test1 SET (fillfactor=100);
|
||||
ALTER TABLE test1 RESET (fillfactor);
|
||||
ALTER TABLE test1 ALTER COLUMN b SET STATISTICS 10;
|
||||
|
||||
|
||||
--
|
||||
-- DROP CHUNKS
|
||||
--
|
||||
SELECT count(*) as count_chunks_uncompressed
|
||||
FROM _timescaledb_catalog.chunk chunk
|
||||
INNER JOIN _timescaledb_catalog.hypertable hypertable ON (chunk.hypertable_id = hypertable.id)
|
||||
|
@ -77,6 +77,14 @@ ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, p'
|
||||
|
||||
--should succeed
|
||||
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, b');
|
||||
|
||||
--ddl on ht with compression
|
||||
ALTER TABLE foo ADD COLUMN new_column INT;
|
||||
ALTER TABLE foo DROP COLUMN a;
|
||||
ALTER TABLE foo DROP COLUMN t;
|
||||
ALTER TABLE foo ALTER COLUMN t SET NOT NULL;
|
||||
ALTER TABLE foo RESET (timescaledb.compress);
|
||||
|
||||
--note that the time column "a" should not be added to the end of the order by list again (should appear first)
|
||||
select hc.* from _timescaledb_catalog.hypertable_compression hc inner join _timescaledb_catalog.hypertable h on (h.id = hc.hypertable_id) where h.table_name = 'foo' order by attname;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user