From 20fd4214375be19aa15a5eb95f1a54a007dc8690 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko Date: Mon, 19 Apr 2021 13:20:01 +0300 Subject: [PATCH] Fix crash while using REINDEX TABLE CONCURRENTLY CONCURRENTLY option of the REINDEX TABLE is not supported and leads to a crash when using with hypertable. Block it and print the error message. Fix #3122 --- CHANGELOG.md | 1 + src/process_utility.c | 7 +- test/expected/{index.out => index-11.out} | 3 + test/expected/index-12.out | 727 ++++++++++++++++++++++ test/expected/index-13.out | 727 ++++++++++++++++++++++ test/sql/CMakeLists.txt | 9 +- test/sql/{index.sql => index.sql.in} | 4 + 7 files changed, 1474 insertions(+), 4 deletions(-) rename test/expected/{index.out => index-11.out} (99%) create mode 100644 test/expected/index-12.out create mode 100644 test/expected/index-13.out rename test/sql/{index.sql => index.sql.in} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c37ffee8eb..20bbc36c6d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ accidentally triggering the load of a previous DB version.** * #3101 Use commit date in get_git_commit() * #3104 Fix use after free in add_reorder_policy * #3106 Fix use after free in chunk_api_get_chunk_stats +* #3123 Fix crash while using REINDEX TABLE CONCURRENTLY ## 2.2.0 (2021-04-13) diff --git a/src/process_utility.c b/src/process_utility.c index 91ebe3ae190..56dac424f8d 100644 --- a/src/process_utility.c +++ b/src/process_utility.c @@ -1478,13 +1478,18 @@ process_reindex(ProcessUtilityArgs *args) { PreventCommandDuringRecovery("REINDEX"); ts_hypertable_permissions_check_by_id(ht->fd.id); - +#if PG12_GE + if (stmt->concurrent) + ereport(ERROR, + (errmsg("concurrent index creation on hypertables is not supported"))); +#endif if (foreach_chunk(ht, reindex_chunk, args) >= 0) result = DDL_DONE; add_hypertable_to_process_args(args, ht); } break; + case REINDEX_OBJECT_INDEX: ht = ts_hypertable_cache_get_entry(hcache, IndexGetRelation(relid, true), diff --git a/test/expected/index.out b/test/expected/index-11.out similarity index 99% rename from test/expected/index.out rename to test/expected/index-11.out index 7d1ac4c96e4..f662fc10f80 100644 --- a/test/expected/index.out +++ b/test/expected/index-11.out @@ -595,6 +595,9 @@ INFO: index "_hyper_12_15_chunk_reindex_test_time_unique_idx" was reindexed INFO: index "16_7_reindex_test_pkey" was reindexed INFO: index "_hyper_12_16_chunk_reindex_test_time_unique_idx" was reindexed \set ON_ERROR_STOP 0 +-- REINDEX TABLE CONCURRENTLY is not supported on PG11 (but blocked on PG12+) +REINDEX TABLE CONCURRENTLY reindex_test; +ERROR: syntax error at or near "CONCURRENTLY" at character 15 -- this one currently doesn't recurse to chunks and instead gives an -- error REINDEX (VERBOSE) INDEX reindex_test_time_unique_idx; diff --git a/test/expected/index-12.out b/test/expected/index-12.out new file mode 100644 index 00000000000..256cb9f3130 --- /dev/null +++ b/test/expected/index-12.out @@ -0,0 +1,727 @@ +-- This file and its contents are licensed under the Apache License 2.0. +-- Please see the included NOTICE for copyright information and +-- LICENSE-APACHE for a copy of the license. +CREATE TABLE index_test(time timestamptz, temp float); +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (1,public,index_test,t) +(1 row) + +-- Default indexes created +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------------+---------+------+--------+---------+-----------+------------ + index_test_time_idx | {time} | | f | f | f | +(1 row) + +DROP TABLE index_test; +CREATE TABLE index_test(time timestamptz, device integer, temp float); +-- Create index before create_hypertable() +CREATE UNIQUE INDEX index_test_time_idx ON index_test (time); +\set ON_ERROR_STOP 0 +-- Creating a hypertable from a table with an index that doesn't cover +-- all partitioning columns should fail +SELECT create_hypertable('index_test', 'time', 'device', 2); +NOTICE: adding not-null constraint to column "time" +ERROR: cannot create a unique index without the column "device" (used in partitioning) +\set ON_ERROR_STOP 1 +-- Partitioning on only time should work +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (3,public,index_test,t) +(1 row) + +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 1, 17.5); +-- Check that index is also created on chunk +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------------+---------+------+--------+---------+-----------+------------ + index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_1_chunk | _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 1 | _hyper_3_1_chunk_index_test_time_idx | 3 | index_test_time_idx +(1 row) + +-- Create another chunk +INSERT INTO index_test VALUES ('2017-05-20T09:00:01', 3, 17.5); +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_1_chunk | _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx | {time} | | t | f | f | + _timescaledb_internal._hyper_3_2_chunk | _timescaledb_internal._hyper_3_2_chunk_index_test_time_idx | {time} | | t | f | f | +(2 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 1 | _hyper_3_1_chunk_index_test_time_idx | 3 | index_test_time_idx + 2 | _hyper_3_2_chunk_index_test_time_idx | 3 | index_test_time_idx +(2 rows) + +-- Delete the index on only one chunk +DROP INDEX _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx; +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_2_chunk | _timescaledb_internal._hyper_3_2_chunk_index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 2 | _hyper_3_2_chunk_index_test_time_idx | 3 | index_test_time_idx +(1 row) + +-- Recreate table with new partitioning +DROP TABLE index_test; +CREATE TABLE index_test(id serial, time timestamptz, device integer, temp float); +SELECT * FROM test.show_columns('index_test'); + Column | Type | NotNull +--------+--------------------------+--------- + id | integer | t + time | timestamp with time zone | f + device | integer | f + temp | double precision | f +(4 rows) + +-- Test that we can handle difference in attnos across hypertable and +-- chunks by dropping the ID column +ALTER TABLE index_test DROP COLUMN id; +SELECT * FROM test.show_columns('index_test'); + Column | Type | NotNull +--------+--------------------------+--------- + time | timestamp with time zone | f + device | integer | f + temp | double precision | f +(3 rows) + +-- No pre-existing UNIQUE index, so partitioning on two columns should work +SELECT create_hypertable('index_test', 'time', 'device', 2); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (4,public,index_test,t) +(1 row) + +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 1, 17.5); +\set ON_ERROR_STOP 0 +-- Create unique index without all partitioning columns should fail +CREATE UNIQUE INDEX index_test_time_device_idx ON index_test (time); +ERROR: cannot create a unique index without the column "device" (used in partitioning) +\set ON_ERROR_STOP 1 +CREATE UNIQUE INDEX index_test_time_device_idx ON index_test (time, device); +-- Regular index need not cover all partitioning columns +CREATE INDEX ON index_test (time, temp); +-- Create another chunk +INSERT INTO index_test VALUES ('2017-04-20T09:00:01', 1, 17.5); +-- New index should have been recursed to chunks +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_idx | {time,device} | | t | f | f | + index_test_time_idx | {time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 3 | _hyper_4_3_chunk_index_test_time_idx | 4 | index_test_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 4 | _hyper_4_4_chunk_index_test_time_idx | 4 | index_test_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +ALTER INDEX index_test_time_idx RENAME TO index_test_time_idx2; +-- Metadata and index should have changed name +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_idx | {time,device} | | t | f | f | + index_test_time_idx2 | {time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx2 | {time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx2 | {time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 3 | _hyper_4_3_chunk_index_test_time_idx2 | 4 | index_test_time_idx2 + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 4 | _hyper_4_4_chunk_index_test_time_idx2 | 4 | index_test_time_idx2 + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +DROP INDEX index_test_time_idx2; +DROP INDEX index_test_time_device_idx; +-- Index should have been dropped +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(2 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(4 rows) + +-- Create index with long name to see how this is handled on chunks +CREATE INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates ON index_test (time, temp); +CREATE INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates_2 ON index_test (time, temp); +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + a_hypertable_index_with_a_very_very_long_name_that_truncates | {time,temp} | | f | f | f | + a_hypertable_index_with_a_very_very_long_name_that_truncates_2 | {time,temp} | | f | f | f | + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+---------------------------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_a_hypertable_index_with_a_very_very_long_name_ | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_a_hypertable_index_with_a_very_very_long_nam_1 | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_a_hypertable_index_with_a_very_very_long_name_ | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_a_hypertable_index_with_a_very_very_long_nam_1 | {time,temp} | | f | f | f | +(8 rows) + +DROP INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates; +DROP INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates_2; +\set ON_ERROR_STOP 0 +-- Create index CONCURRENTLY +CREATE UNIQUE INDEX CONCURRENTLY index_test_time_device_idx ON index_test (time, device); +ERROR: hypertables do not support concurrent index creation +\set ON_ERROR_STOP 1 +-- Test tablespaces. Chunk indexes should end up in same tablespace as +-- main index. +\c :TEST_DBNAME :ROLE_SUPERUSER +SET client_min_messages = ERROR; +DROP TABLESPACE IF EXISTS tablespace1; +DROP TABLESPACE IF EXISTS tablespace2; +SET client_min_messages = NOTICE; +CREATE TABLESPACE tablespace1 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE1_PATH; +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +CREATE INDEX index_test_time_idx ON index_test (time) TABLESPACE tablespace1; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace1 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 +(6 rows) + +\c :TEST_DBNAME :ROLE_SUPERUSER +CREATE TABLESPACE tablespace2 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE2_PATH; +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +ALTER INDEX index_test_time_idx SET TABLESPACE tablespace2; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace2 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 +(6 rows) + +-- Add constraint index +ALTER TABLE index_test ADD UNIQUE (time, device); +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_key | {time,device} | | t | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace2 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal."3_1_index_test_time_device_key" | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal."4_2_index_test_time_device_key" | {time,device} | | t | f | f | +(8 rows) + +-- Constraint indexes are added to chunk_index table. +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | 3_1_index_test_time_device_key | 4 | index_test_time_device_key + 4 | 4_2_index_test_time_device_key | 4 | index_test_time_device_key + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_idx | 4 | index_test_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_idx | 4 | index_test_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_constraint; + chunk_id | dimension_slice_id | constraint_name | hypertable_constraint_name +----------+--------------------+--------------------------------+---------------------------- + 3 | 3 | constraint_3 | + 3 | 4 | constraint_4 | + 4 | 5 | constraint_5 | + 4 | 4 | constraint_4 | + 3 | | 3_1_index_test_time_device_key | index_test_time_device_key + 4 | | 4_2_index_test_time_device_key | index_test_time_device_key +(6 rows) + +DROP TABLE index_test; +-- Metadata removed +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+------------+---------------+----------------------- +(0 rows) + +-- Create table in a tablespace +CREATE TABLE index_test(time timestamptz, temp float, device int) TABLESPACE tablespace1; +-- Default indexes should be in the table's tablespace +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (5,public,index_test,t) +(1 row) + +-- Explicitly defining an index tablespace should work and propagate +-- to chunks +CREATE INDEX ON index_test (time, device) TABLESPACE tablespace2; +-- New indexes without explicit tablespaces should use the default +-- tablespace +CREATE INDEX ON index_test (device); +-- Create chunk +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 17.5); +-- Check that the tablespaces of chunk indexes match the tablespace of +-- the main index +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_idx | {device} | | f | f | f | + index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + index_test_time_idx | {time} | | f | f | f | tablespace1 +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {device} | | f | f | f | tablespace1 +(3 rows) + +-- Creating a new index should propagate to existing chunks, including +-- the given tablespace +CREATE INDEX ON index_test (time, temp) TABLESPACE tablespace2; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_idx | {device} | | f | f | f | + index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + index_test_time_idx | {time} | | f | f | f | tablespace1 + index_test_time_temp_idx | {time,temp} | | f | f | f | tablespace2 +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {device} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | tablespace2 +(4 rows) + +-- Cleanup +DROP TABLE index_test CASCADE; +\c :TEST_DBNAME :ROLE_SUPERUSER +DROP TABLESPACE tablespace1; +DROP TABLESPACE tablespace2; +-- Test expression indexes +CREATE TABLE index_expr_test(id serial, time timestamptz, temp float, meta jsonb); +-- Screw up the attribute numbers +ALTER TABLE index_expr_test DROP COLUMN id; +CREATE INDEX ON index_expr_test ((meta ->> 'field')) ; +INSERT INTO index_expr_test VALUES ('2017-01-20T09:00:01', 17.5, '{"field": "value1"}'); +INSERT INTO index_expr_test VALUES ('2017-01-20T09:00:01', 17.5, '{"field": "value2"}'); +EXPLAIN (verbose, costs off) +SELECT * FROM index_expr_test WHERE meta ->> 'field' = 'value1'; + QUERY PLAN +--------------------------------------------------------------------------- + Index Scan using index_expr_test_expr_idx on public.index_expr_test + Output: "time", temp, meta + Index Cond: ((index_expr_test.meta ->> 'field'::text) = 'value1'::text) +(3 rows) + +SELECT * FROM index_expr_test WHERE meta ->> 'field' = 'value1'; + time | temp | meta +------------------------------+------+--------------------- + Fri Jan 20 09:00:01 2017 PST | 17.5 | {"field": "value1"} +(1 row) + +-- Test INDEX DROP error for multiple objects +CREATE TABLE index_test(time timestamptz, temp float); +CREATE UNIQUE INDEX index_test_idx ON index_test (time, temp); +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (6,public,index_test,t) +(1 row) + +CREATE TABLE index_test_2(time timestamptz, temp float); +CREATE UNIQUE INDEX index_test_2_idx ON index_test_2 (time, temp); +\set ON_ERROR_STOP 0 +DROP INDEX index_test_idx, index_test_2_idx; +ERROR: cannot drop a hypertable index along with other objects +\set ON_ERROR_STOP 1 +-- test expression index with dropped columns +CREATE TABLE idx_expr_test(filler int, time timestamptz, meta text); +SELECT table_name FROM create_hypertable('idx_expr_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +--------------- + idx_expr_test +(1 row) + +ALTER TABLE idx_expr_test DROP COLUMN filler; +CREATE INDEX tag_idx ON idx_expr_test(('foo'||meta)); +INSERT INTO idx_expr_test(time, meta) VALUES ('2000-01-01', 'bar'); +DROP TABLE idx_expr_test CASCADE; +-- test multicolumn expression index with dropped columns +CREATE TABLE idx_expr_test(filler int, time timestamptz, t1 text, t2 text, t3 text); +SELECT table_name FROM create_hypertable('idx_expr_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +--------------- + idx_expr_test +(1 row) + +ALTER TABLE idx_expr_test DROP COLUMN filler; +CREATE INDEX tag_idx ON idx_expr_test((t1||t2||t3)); +INSERT INTO idx_expr_test(time, t1, t2, t3) VALUES ('2000-01-01', 'foo', 'bar', 'baz'); +DROP TABLE idx_expr_test CASCADE; +-- test index with predicate and dropped columns +CREATE TABLE idx_predicate_test(filler int, time timestamptz); +SELECT table_name FROM create_hypertable('idx_predicate_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +-------------------- + idx_predicate_test +(1 row) + +ALTER TABLE idx_predicate_test DROP COLUMN filler; +ALTER TABLE idx_predicate_test ADD COLUMN b1 bool; +CREATE INDEX idx_predicate_test_b1 ON idx_predicate_test(b1) WHERE b1=true; +INSERT INTO idx_predicate_test VALUES ('2000-01-01',true); +DROP TABLE idx_predicate_test; +-- test index with table references +CREATE TABLE idx_tableref_test(time timestamptz); +SELECT table_name FROM create_hypertable('idx_tableref_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +------------------- + idx_tableref_test +(1 row) + +-- we use security definer to prevent function inlining +CREATE OR REPLACE FUNCTION tableref_func(t idx_tableref_test) RETURNS timestamptz LANGUAGE SQL IMMUTABLE SECURITY DEFINER AS $f$ SELECT t.time; $f$; +-- try creating index with no existing chunks +CREATE INDEX tableref_idx ON idx_tableref_test(tableref_func(idx_tableref_test)); +-- insert data to trigger chunk creation +INSERT INTO idx_tableref_test SELECT '2000-01-01'; +DROP INDEX tableref_idx; +-- try creating index on hypertable with existing chunks +CREATE INDEX tableref_idx ON idx_tableref_test(tableref_func(idx_tableref_test)); +-- test index creation with if not exists +CREATE TABLE idx_exists(time timestamptz NOT NULL); +SELECT table_name FROM create_hypertable('idx_exists', 'time'); + table_name +------------ + idx_exists +(1 row) + +-- should be skipped since this index was already created by create_hypertable +CREATE INDEX IF NOT EXISTS idx_exists_time_idx ON idx_exists(time DESC); +NOTICE: relation "idx_exists_time_idx" already exists, skipping +-- should create index +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +-- should be skipped since it was created in previous command +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +NOTICE: relation "idx_exists_time_asc_idx" already exists, skipping +DROP INDEX idx_exists_time_asc_idx; +INSERT INTO idx_exists VALUES ('2000-01-01'),('2001-01-01'); +-- should create index +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +-- should be skipped since it was created in previous command +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +NOTICE: relation "idx_exists_time_asc_idx" already exists, skipping +-- test reindex +CREATE TABLE reindex_test(time timestamp, temp float, PRIMARY KEY(time, temp)); +CREATE UNIQUE INDEX reindex_test_time_unique_idx ON reindex_test(time); +-- create hypertable with three chunks +SELECT create_hypertable('reindex_test', 'time', chunk_time_interval => 2628000000000); + create_hypertable +---------------------------- + (12,public,reindex_test,t) +(1 row) + +INSERT INTO reindex_test VALUES ('2017-01-20T09:00:01', 17.5), + ('2017-01-21T09:00:01', 19.1), + ('2017-04-20T09:00:01', 89.5), + ('2017-04-21T09:00:01', 17.1), + ('2017-06-20T09:00:01', 18.5), + ('2017-06-21T09:00:01', 11.0); +SELECT * FROM test.show_columns('reindex_test'); + Column | Type | NotNull +--------+-----------------------------+--------- + time | timestamp without time zone | t + temp | double precision | t +(2 rows) + +SELECT * FROM test.show_subtables('reindex_test'); + Child | Tablespace +------------------------------------------+------------ + _timescaledb_internal._hyper_12_12_chunk | + _timescaledb_internal._hyper_12_13_chunk | + _timescaledb_internal._hyper_12_14_chunk | + _timescaledb_internal._hyper_12_15_chunk | + _timescaledb_internal._hyper_12_16_chunk | +(5 rows) + +-- show reindexing +REINDEX (VERBOSE) TABLE reindex_test; +INFO: index "12_3_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_12_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "13_4_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_13_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "14_5_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_14_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "15_6_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_15_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "16_7_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_16_chunk_reindex_test_time_unique_idx" was reindexed +\set ON_ERROR_STOP 0 +-- REINDEX TABLE CONCURRENTLY is not supported on PG11 (but blocked on PG12+) +REINDEX TABLE CONCURRENTLY reindex_test; +ERROR: concurrent index creation on hypertables is not supported +-- this one currently doesn't recurse to chunks and instead gives an +-- error +REINDEX (VERBOSE) INDEX reindex_test_time_unique_idx; +ERROR: reindexing of a specific index on a hypertable is unsupported +\set ON_ERROR_STOP 1 +-- show reindexing on a normal table +CREATE TABLE reindex_norm(time timestamp, temp float); +CREATE UNIQUE INDEX reindex_norm_time_unique_idx ON reindex_norm(time); +INSERT INTO reindex_norm VALUES ('2017-01-20T09:00:01', 17.5), + ('2017-01-21T09:00:01', 19.1), + ('2017-04-20T09:00:01', 89.5), + ('2017-04-21T09:00:01', 17.1), + ('2017-06-20T09:00:01', 18.5), + ('2017-06-21T09:00:01', 11.0); +REINDEX (VERBOSE) TABLE reindex_norm; +INFO: index "reindex_norm_time_unique_idx" was reindexed +REINDEX (VERBOSE) INDEX reindex_norm_time_unique_idx; +INFO: index "reindex_norm_time_unique_idx" was reindexed +SELECT * FROM test.show_constraintsp('_timescaledb_internal._hyper_12%'); + Table | Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated +------------------------------------------+------------------------+------+-------------+------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+----------- + _timescaledb_internal._hyper_12_12_chunk | 12_3_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."12_3_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_12_chunk | constraint_13 | c | {time} | - | (("time" >= 'Thu Jan 19 10:00:00 2017'::timestamp without time zone) AND ("time" < 'Sat Feb 18 20:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_13_chunk | 13_4_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."13_4_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_13_chunk | constraint_14 | c | {time} | - | (("time" >= 'Tue Mar 21 06:00:00 2017'::timestamp without time zone) AND ("time" < 'Thu Apr 20 16:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_14_chunk | 14_5_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."14_5_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_14_chunk | constraint_15 | c | {time} | - | (("time" >= 'Thu Apr 20 16:00:00 2017'::timestamp without time zone) AND ("time" < 'Sun May 21 02:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_15_chunk | 15_6_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."15_6_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_15_chunk | constraint_16 | c | {time} | - | (("time" >= 'Sun May 21 02:00:00 2017'::timestamp without time zone) AND ("time" < 'Tue Jun 20 12:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_16_chunk | 16_7_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."16_7_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_16_chunk | constraint_17 | c | {time} | - | (("time" >= 'Tue Jun 20 12:00:00 2017'::timestamp without time zone) AND ("time" < 'Thu Jul 20 22:00:00 2017'::timestamp without time zone)) | f | f | t +(10 rows) + +SELECT * FROM reindex_norm; + time | temp +--------------------------+------ + Fri Jan 20 09:00:01 2017 | 17.5 + Sat Jan 21 09:00:01 2017 | 19.1 + Thu Apr 20 09:00:01 2017 | 89.5 + Fri Apr 21 09:00:01 2017 | 17.1 + Tue Jun 20 09:00:01 2017 | 18.5 + Wed Jun 21 09:00:01 2017 | 11 +(6 rows) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(2 rows) + +SELECT chunk_index_clone::regclass::text +FROM _timescaledb_internal.chunk_index_clone('_timescaledb_internal."12_3_reindex_test_pkey"'::regclass); + chunk_index_clone +----------------------------------------------------------------- + _timescaledb_internal._hyper_12_12_chunk_12_3_reindex_test_pkey +(1 row) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_12_3_reindex_test_pkey | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(3 rows) + +SELECT * FROM _timescaledb_internal.chunk_index_replace('_timescaledb_internal."12_3_reindex_test_pkey"'::regclass, '_timescaledb_internal."_hyper_12_12_chunk_12_3_reindex_test_pkey"'::regclass); + chunk_index_replace +--------------------- + +(1 row) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(2 rows) + +CREATE TABLE ht_dropped(time timestamptz, d0 int, d1 int, c0 int, c1 int, c2 int); +SELECT create_hypertable('ht_dropped','time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +-------------------------- + (13,public,ht_dropped,t) +(1 row) + +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2000-01-01',1,2,3; +ALTER TABLE ht_dropped DROP COLUMN d0; +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2001-01-01',1,2,3; +ALTER TABLE ht_dropped DROP COLUMN d1; +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2002-01-01',1,2,3; +CREATE INDEX ON ht_dropped(c0,c1,c2) WHERE c1 IS NOT NULL; +CREATE INDEX ON ht_dropped(c0,c1,c2) WITH(timescaledb.transaction_per_chunk) WHERE c2 IS NOT NULL; +SELECT + oid::TEXT AS "Chunk", + i.* +FROM + (SELECT tableoid::REGCLASS FROM ht_dropped GROUP BY tableoid) ch (oid) + LEFT JOIN LATERAL ( SELECT * FROM test.show_indexes (ch.oid)) i ON TRUE +ORDER BY + 1, 2; + Chunk | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +------------------------------------------+-------------------------------------------------------------------+------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | +(9 rows) + +-- #3056 check chunk index column name mapping +CREATE TABLE i3056(c int, order_number int NOT NULL, date_created timestamptz NOT NULL); +CREATE INDEX ON i3056(order_number) INCLUDE(order_number); +CREATE INDEX ON i3056(date_created, (order_number % 5)) INCLUDE(order_number); +SELECT table_name FROM create_hypertable('i3056', 'date_created'); + table_name +------------ + i3056 +(1 row) + +ALTER TABLE i3056 DROP COLUMN c; +INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); diff --git a/test/expected/index-13.out b/test/expected/index-13.out new file mode 100644 index 00000000000..256cb9f3130 --- /dev/null +++ b/test/expected/index-13.out @@ -0,0 +1,727 @@ +-- This file and its contents are licensed under the Apache License 2.0. +-- Please see the included NOTICE for copyright information and +-- LICENSE-APACHE for a copy of the license. +CREATE TABLE index_test(time timestamptz, temp float); +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (1,public,index_test,t) +(1 row) + +-- Default indexes created +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------------+---------+------+--------+---------+-----------+------------ + index_test_time_idx | {time} | | f | f | f | +(1 row) + +DROP TABLE index_test; +CREATE TABLE index_test(time timestamptz, device integer, temp float); +-- Create index before create_hypertable() +CREATE UNIQUE INDEX index_test_time_idx ON index_test (time); +\set ON_ERROR_STOP 0 +-- Creating a hypertable from a table with an index that doesn't cover +-- all partitioning columns should fail +SELECT create_hypertable('index_test', 'time', 'device', 2); +NOTICE: adding not-null constraint to column "time" +ERROR: cannot create a unique index without the column "device" (used in partitioning) +\set ON_ERROR_STOP 1 +-- Partitioning on only time should work +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (3,public,index_test,t) +(1 row) + +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 1, 17.5); +-- Check that index is also created on chunk +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------------+---------+------+--------+---------+-----------+------------ + index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_1_chunk | _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 1 | _hyper_3_1_chunk_index_test_time_idx | 3 | index_test_time_idx +(1 row) + +-- Create another chunk +INSERT INTO index_test VALUES ('2017-05-20T09:00:01', 3, 17.5); +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_1_chunk | _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx | {time} | | t | f | f | + _timescaledb_internal._hyper_3_2_chunk | _timescaledb_internal._hyper_3_2_chunk_index_test_time_idx | {time} | | t | f | f | +(2 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 1 | _hyper_3_1_chunk_index_test_time_idx | 3 | index_test_time_idx + 2 | _hyper_3_2_chunk_index_test_time_idx | 3 | index_test_time_idx +(2 rows) + +-- Delete the index on only one chunk +DROP INDEX _timescaledb_internal._hyper_3_1_chunk_index_test_time_idx; +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+------------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_3_2_chunk | _timescaledb_internal._hyper_3_2_chunk_index_test_time_idx | {time} | | t | f | f | +(1 row) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+--------------------------------------+---------------+----------------------- + 2 | _hyper_3_2_chunk_index_test_time_idx | 3 | index_test_time_idx +(1 row) + +-- Recreate table with new partitioning +DROP TABLE index_test; +CREATE TABLE index_test(id serial, time timestamptz, device integer, temp float); +SELECT * FROM test.show_columns('index_test'); + Column | Type | NotNull +--------+--------------------------+--------- + id | integer | t + time | timestamp with time zone | f + device | integer | f + temp | double precision | f +(4 rows) + +-- Test that we can handle difference in attnos across hypertable and +-- chunks by dropping the ID column +ALTER TABLE index_test DROP COLUMN id; +SELECT * FROM test.show_columns('index_test'); + Column | Type | NotNull +--------+--------------------------+--------- + time | timestamp with time zone | f + device | integer | f + temp | double precision | f +(3 rows) + +-- No pre-existing UNIQUE index, so partitioning on two columns should work +SELECT create_hypertable('index_test', 'time', 'device', 2); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (4,public,index_test,t) +(1 row) + +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 1, 17.5); +\set ON_ERROR_STOP 0 +-- Create unique index without all partitioning columns should fail +CREATE UNIQUE INDEX index_test_time_device_idx ON index_test (time); +ERROR: cannot create a unique index without the column "device" (used in partitioning) +\set ON_ERROR_STOP 1 +CREATE UNIQUE INDEX index_test_time_device_idx ON index_test (time, device); +-- Regular index need not cover all partitioning columns +CREATE INDEX ON index_test (time, temp); +-- Create another chunk +INSERT INTO index_test VALUES ('2017-04-20T09:00:01', 1, 17.5); +-- New index should have been recursed to chunks +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_idx | {time,device} | | t | f | f | + index_test_time_idx | {time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 3 | _hyper_4_3_chunk_index_test_time_idx | 4 | index_test_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 4 | _hyper_4_4_chunk_index_test_time_idx | 4 | index_test_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +ALTER INDEX index_test_time_idx RENAME TO index_test_time_idx2; +-- Metadata and index should have changed name +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_idx | {time,device} | | t | f | f | + index_test_time_idx2 | {time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx2 | {time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx2 | {time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_device_idx | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 3 | _hyper_4_3_chunk_index_test_time_idx2 | 4 | index_test_time_idx2 + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_device_idx | 4 | index_test_time_device_idx + 4 | _hyper_4_4_chunk_index_test_time_idx2 | 4 | index_test_time_idx2 + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +DROP INDEX index_test_time_idx2; +DROP INDEX index_test_time_device_idx; +-- Index should have been dropped +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------ + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(2 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(4 rows) + +-- Create index with long name to see how this is handled on chunks +CREATE INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates ON index_test (time, temp); +CREATE INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates_2 ON index_test (time, temp); +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + a_hypertable_index_with_a_very_very_long_name_that_truncates | {time,temp} | | f | f | f | + a_hypertable_index_with_a_very_very_long_name_that_truncates_2 | {time,temp} | | f | f | f | + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+---------------------------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_a_hypertable_index_with_a_very_very_long_name_ | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_a_hypertable_index_with_a_very_very_long_nam_1 | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_a_hypertable_index_with_a_very_very_long_name_ | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_a_hypertable_index_with_a_very_very_long_nam_1 | {time,temp} | | f | f | f | +(8 rows) + +DROP INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates; +DROP INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates_2; +\set ON_ERROR_STOP 0 +-- Create index CONCURRENTLY +CREATE UNIQUE INDEX CONCURRENTLY index_test_time_device_idx ON index_test (time, device); +ERROR: hypertables do not support concurrent index creation +\set ON_ERROR_STOP 1 +-- Test tablespaces. Chunk indexes should end up in same tablespace as +-- main index. +\c :TEST_DBNAME :ROLE_SUPERUSER +SET client_min_messages = ERROR; +DROP TABLESPACE IF EXISTS tablespace1; +DROP TABLESPACE IF EXISTS tablespace2; +SET client_min_messages = NOTICE; +CREATE TABLESPACE tablespace1 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE1_PATH; +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +CREATE INDEX index_test_time_idx ON index_test (time) TABLESPACE tablespace1; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace1 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 +(6 rows) + +\c :TEST_DBNAME :ROLE_SUPERUSER +CREATE TABLESPACE tablespace2 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE2_PATH; +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +ALTER INDEX index_test_time_idx SET TABLESPACE tablespace2; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace2 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 +(6 rows) + +-- Add constraint index +ALTER TABLE index_test ADD UNIQUE (time, device); +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_time_idx | {device,time} | | f | f | f | + index_test_time_device_key | {time,device} | | t | f | f | + index_test_time_idx | {time} | | f | f | f | tablespace2 + index_test_time_temp_idx | {time,temp} | | f | f | f | +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal._hyper_4_3_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_3_chunk | _timescaledb_internal."3_1_index_test_time_device_key" | {time,device} | | t | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_device_time_idx | {device,time} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal._hyper_4_4_chunk_index_test_time_idx | {time} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_4_4_chunk | _timescaledb_internal."4_2_index_test_time_device_key" | {time,device} | | t | f | f | +(8 rows) + +-- Constraint indexes are added to chunk_index table. +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+---------------------------------------------+---------------+---------------------------- + 3 | 3_1_index_test_time_device_key | 4 | index_test_time_device_key + 4 | 4_2_index_test_time_device_key | 4 | index_test_time_device_key + 3 | _hyper_4_3_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 3 | _hyper_4_3_chunk_index_test_time_idx | 4 | index_test_time_idx + 3 | _hyper_4_3_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx + 4 | _hyper_4_4_chunk_index_test_device_time_idx | 4 | index_test_device_time_idx + 4 | _hyper_4_4_chunk_index_test_time_idx | 4 | index_test_time_idx + 4 | _hyper_4_4_chunk_index_test_time_temp_idx | 4 | index_test_time_temp_idx +(8 rows) + +SELECT * FROM _timescaledb_catalog.chunk_constraint; + chunk_id | dimension_slice_id | constraint_name | hypertable_constraint_name +----------+--------------------+--------------------------------+---------------------------- + 3 | 3 | constraint_3 | + 3 | 4 | constraint_4 | + 4 | 5 | constraint_5 | + 4 | 4 | constraint_4 | + 3 | | 3_1_index_test_time_device_key | index_test_time_device_key + 4 | | 4_2_index_test_time_device_key | index_test_time_device_key +(6 rows) + +DROP TABLE index_test; +-- Metadata removed +SELECT * FROM _timescaledb_catalog.chunk_index ORDER BY index_name, hypertable_index_name; + chunk_id | index_name | hypertable_id | hypertable_index_name +----------+------------+---------------+----------------------- +(0 rows) + +-- Create table in a tablespace +CREATE TABLE index_test(time timestamptz, temp float, device int) TABLESPACE tablespace1; +-- Default indexes should be in the table's tablespace +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (5,public,index_test,t) +(1 row) + +-- Explicitly defining an index tablespace should work and propagate +-- to chunks +CREATE INDEX ON index_test (time, device) TABLESPACE tablespace2; +-- New indexes without explicit tablespaces should use the default +-- tablespace +CREATE INDEX ON index_test (device); +-- Create chunk +INSERT INTO index_test VALUES ('2017-01-20T09:00:01', 17.5); +-- Check that the tablespaces of chunk indexes match the tablespace of +-- the main index +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_idx | {device} | | f | f | f | + index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + index_test_time_idx | {time} | | f | f | f | tablespace1 +(3 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {device} | | f | f | f | tablespace1 +(3 rows) + +-- Creating a new index should propagate to existing chunks, including +-- the given tablespace +CREATE INDEX ON index_test (time, temp) TABLESPACE tablespace2; +SELECT * FROM test.show_indexes('index_test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------+---------------+------+--------+---------+-----------+------------- + index_test_device_idx | {device} | | f | f | f | + index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + index_test_time_idx | {time} | | f | f | f | tablespace1 + index_test_time_temp_idx | {time,temp} | | f | f | f | tablespace2 +(4 rows) + +SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk'); + Table | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +----------------------------------------+-------------------------------------------------------------------+---------------+------+--------+---------+-----------+------------- + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,device} | | f | f | f | tablespace2 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {device} | | f | f | f | tablespace1 + _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_temp_idx | {time,temp} | | f | f | f | tablespace2 +(4 rows) + +-- Cleanup +DROP TABLE index_test CASCADE; +\c :TEST_DBNAME :ROLE_SUPERUSER +DROP TABLESPACE tablespace1; +DROP TABLESPACE tablespace2; +-- Test expression indexes +CREATE TABLE index_expr_test(id serial, time timestamptz, temp float, meta jsonb); +-- Screw up the attribute numbers +ALTER TABLE index_expr_test DROP COLUMN id; +CREATE INDEX ON index_expr_test ((meta ->> 'field')) ; +INSERT INTO index_expr_test VALUES ('2017-01-20T09:00:01', 17.5, '{"field": "value1"}'); +INSERT INTO index_expr_test VALUES ('2017-01-20T09:00:01', 17.5, '{"field": "value2"}'); +EXPLAIN (verbose, costs off) +SELECT * FROM index_expr_test WHERE meta ->> 'field' = 'value1'; + QUERY PLAN +--------------------------------------------------------------------------- + Index Scan using index_expr_test_expr_idx on public.index_expr_test + Output: "time", temp, meta + Index Cond: ((index_expr_test.meta ->> 'field'::text) = 'value1'::text) +(3 rows) + +SELECT * FROM index_expr_test WHERE meta ->> 'field' = 'value1'; + time | temp | meta +------------------------------+------+--------------------- + Fri Jan 20 09:00:01 2017 PST | 17.5 | {"field": "value1"} +(1 row) + +-- Test INDEX DROP error for multiple objects +CREATE TABLE index_test(time timestamptz, temp float); +CREATE UNIQUE INDEX index_test_idx ON index_test (time, temp); +SELECT create_hypertable('index_test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (6,public,index_test,t) +(1 row) + +CREATE TABLE index_test_2(time timestamptz, temp float); +CREATE UNIQUE INDEX index_test_2_idx ON index_test_2 (time, temp); +\set ON_ERROR_STOP 0 +DROP INDEX index_test_idx, index_test_2_idx; +ERROR: cannot drop a hypertable index along with other objects +\set ON_ERROR_STOP 1 +-- test expression index with dropped columns +CREATE TABLE idx_expr_test(filler int, time timestamptz, meta text); +SELECT table_name FROM create_hypertable('idx_expr_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +--------------- + idx_expr_test +(1 row) + +ALTER TABLE idx_expr_test DROP COLUMN filler; +CREATE INDEX tag_idx ON idx_expr_test(('foo'||meta)); +INSERT INTO idx_expr_test(time, meta) VALUES ('2000-01-01', 'bar'); +DROP TABLE idx_expr_test CASCADE; +-- test multicolumn expression index with dropped columns +CREATE TABLE idx_expr_test(filler int, time timestamptz, t1 text, t2 text, t3 text); +SELECT table_name FROM create_hypertable('idx_expr_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +--------------- + idx_expr_test +(1 row) + +ALTER TABLE idx_expr_test DROP COLUMN filler; +CREATE INDEX tag_idx ON idx_expr_test((t1||t2||t3)); +INSERT INTO idx_expr_test(time, t1, t2, t3) VALUES ('2000-01-01', 'foo', 'bar', 'baz'); +DROP TABLE idx_expr_test CASCADE; +-- test index with predicate and dropped columns +CREATE TABLE idx_predicate_test(filler int, time timestamptz); +SELECT table_name FROM create_hypertable('idx_predicate_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +-------------------- + idx_predicate_test +(1 row) + +ALTER TABLE idx_predicate_test DROP COLUMN filler; +ALTER TABLE idx_predicate_test ADD COLUMN b1 bool; +CREATE INDEX idx_predicate_test_b1 ON idx_predicate_test(b1) WHERE b1=true; +INSERT INTO idx_predicate_test VALUES ('2000-01-01',true); +DROP TABLE idx_predicate_test; +-- test index with table references +CREATE TABLE idx_tableref_test(time timestamptz); +SELECT table_name FROM create_hypertable('idx_tableref_test', 'time'); +NOTICE: adding not-null constraint to column "time" + table_name +------------------- + idx_tableref_test +(1 row) + +-- we use security definer to prevent function inlining +CREATE OR REPLACE FUNCTION tableref_func(t idx_tableref_test) RETURNS timestamptz LANGUAGE SQL IMMUTABLE SECURITY DEFINER AS $f$ SELECT t.time; $f$; +-- try creating index with no existing chunks +CREATE INDEX tableref_idx ON idx_tableref_test(tableref_func(idx_tableref_test)); +-- insert data to trigger chunk creation +INSERT INTO idx_tableref_test SELECT '2000-01-01'; +DROP INDEX tableref_idx; +-- try creating index on hypertable with existing chunks +CREATE INDEX tableref_idx ON idx_tableref_test(tableref_func(idx_tableref_test)); +-- test index creation with if not exists +CREATE TABLE idx_exists(time timestamptz NOT NULL); +SELECT table_name FROM create_hypertable('idx_exists', 'time'); + table_name +------------ + idx_exists +(1 row) + +-- should be skipped since this index was already created by create_hypertable +CREATE INDEX IF NOT EXISTS idx_exists_time_idx ON idx_exists(time DESC); +NOTICE: relation "idx_exists_time_idx" already exists, skipping +-- should create index +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +-- should be skipped since it was created in previous command +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +NOTICE: relation "idx_exists_time_asc_idx" already exists, skipping +DROP INDEX idx_exists_time_asc_idx; +INSERT INTO idx_exists VALUES ('2000-01-01'),('2001-01-01'); +-- should create index +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +-- should be skipped since it was created in previous command +CREATE INDEX IF NOT EXISTS idx_exists_time_asc_idx ON idx_exists(time ASC); +NOTICE: relation "idx_exists_time_asc_idx" already exists, skipping +-- test reindex +CREATE TABLE reindex_test(time timestamp, temp float, PRIMARY KEY(time, temp)); +CREATE UNIQUE INDEX reindex_test_time_unique_idx ON reindex_test(time); +-- create hypertable with three chunks +SELECT create_hypertable('reindex_test', 'time', chunk_time_interval => 2628000000000); + create_hypertable +---------------------------- + (12,public,reindex_test,t) +(1 row) + +INSERT INTO reindex_test VALUES ('2017-01-20T09:00:01', 17.5), + ('2017-01-21T09:00:01', 19.1), + ('2017-04-20T09:00:01', 89.5), + ('2017-04-21T09:00:01', 17.1), + ('2017-06-20T09:00:01', 18.5), + ('2017-06-21T09:00:01', 11.0); +SELECT * FROM test.show_columns('reindex_test'); + Column | Type | NotNull +--------+-----------------------------+--------- + time | timestamp without time zone | t + temp | double precision | t +(2 rows) + +SELECT * FROM test.show_subtables('reindex_test'); + Child | Tablespace +------------------------------------------+------------ + _timescaledb_internal._hyper_12_12_chunk | + _timescaledb_internal._hyper_12_13_chunk | + _timescaledb_internal._hyper_12_14_chunk | + _timescaledb_internal._hyper_12_15_chunk | + _timescaledb_internal._hyper_12_16_chunk | +(5 rows) + +-- show reindexing +REINDEX (VERBOSE) TABLE reindex_test; +INFO: index "12_3_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_12_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "13_4_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_13_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "14_5_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_14_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "15_6_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_15_chunk_reindex_test_time_unique_idx" was reindexed +INFO: index "16_7_reindex_test_pkey" was reindexed +INFO: index "_hyper_12_16_chunk_reindex_test_time_unique_idx" was reindexed +\set ON_ERROR_STOP 0 +-- REINDEX TABLE CONCURRENTLY is not supported on PG11 (but blocked on PG12+) +REINDEX TABLE CONCURRENTLY reindex_test; +ERROR: concurrent index creation on hypertables is not supported +-- this one currently doesn't recurse to chunks and instead gives an +-- error +REINDEX (VERBOSE) INDEX reindex_test_time_unique_idx; +ERROR: reindexing of a specific index on a hypertable is unsupported +\set ON_ERROR_STOP 1 +-- show reindexing on a normal table +CREATE TABLE reindex_norm(time timestamp, temp float); +CREATE UNIQUE INDEX reindex_norm_time_unique_idx ON reindex_norm(time); +INSERT INTO reindex_norm VALUES ('2017-01-20T09:00:01', 17.5), + ('2017-01-21T09:00:01', 19.1), + ('2017-04-20T09:00:01', 89.5), + ('2017-04-21T09:00:01', 17.1), + ('2017-06-20T09:00:01', 18.5), + ('2017-06-21T09:00:01', 11.0); +REINDEX (VERBOSE) TABLE reindex_norm; +INFO: index "reindex_norm_time_unique_idx" was reindexed +REINDEX (VERBOSE) INDEX reindex_norm_time_unique_idx; +INFO: index "reindex_norm_time_unique_idx" was reindexed +SELECT * FROM test.show_constraintsp('_timescaledb_internal._hyper_12%'); + Table | Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated +------------------------------------------+------------------------+------+-------------+------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+----------- + _timescaledb_internal._hyper_12_12_chunk | 12_3_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."12_3_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_12_chunk | constraint_13 | c | {time} | - | (("time" >= 'Thu Jan 19 10:00:00 2017'::timestamp without time zone) AND ("time" < 'Sat Feb 18 20:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_13_chunk | 13_4_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."13_4_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_13_chunk | constraint_14 | c | {time} | - | (("time" >= 'Tue Mar 21 06:00:00 2017'::timestamp without time zone) AND ("time" < 'Thu Apr 20 16:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_14_chunk | 14_5_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."14_5_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_14_chunk | constraint_15 | c | {time} | - | (("time" >= 'Thu Apr 20 16:00:00 2017'::timestamp without time zone) AND ("time" < 'Sun May 21 02:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_15_chunk | 15_6_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."15_6_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_15_chunk | constraint_16 | c | {time} | - | (("time" >= 'Sun May 21 02:00:00 2017'::timestamp without time zone) AND ("time" < 'Tue Jun 20 12:00:00 2017'::timestamp without time zone)) | f | f | t + _timescaledb_internal._hyper_12_16_chunk | 16_7_reindex_test_pkey | p | {time,temp} | _timescaledb_internal."16_7_reindex_test_pkey" | | f | f | t + _timescaledb_internal._hyper_12_16_chunk | constraint_17 | c | {time} | - | (("time" >= 'Tue Jun 20 12:00:00 2017'::timestamp without time zone) AND ("time" < 'Thu Jul 20 22:00:00 2017'::timestamp without time zone)) | f | f | t +(10 rows) + +SELECT * FROM reindex_norm; + time | temp +--------------------------+------ + Fri Jan 20 09:00:01 2017 | 17.5 + Sat Jan 21 09:00:01 2017 | 19.1 + Thu Apr 20 09:00:01 2017 | 89.5 + Fri Apr 21 09:00:01 2017 | 17.1 + Tue Jun 20 09:00:01 2017 | 18.5 + Wed Jun 21 09:00:01 2017 | 11 +(6 rows) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(2 rows) + +SELECT chunk_index_clone::regclass::text +FROM _timescaledb_internal.chunk_index_clone('_timescaledb_internal."12_3_reindex_test_pkey"'::regclass); + chunk_index_clone +----------------------------------------------------------------- + _timescaledb_internal._hyper_12_12_chunk_12_3_reindex_test_pkey +(1 row) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_12_3_reindex_test_pkey | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(3 rows) + +SELECT * FROM _timescaledb_internal.chunk_index_replace('_timescaledb_internal."12_3_reindex_test_pkey"'::regclass, '_timescaledb_internal."_hyper_12_12_chunk_12_3_reindex_test_pkey"'::regclass); + chunk_index_replace +--------------------- + +(1 row) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_12_12_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +-----------------------------------------------------------------------+-------------+------+--------+---------+-----------+------------ + _timescaledb_internal."12_3_reindex_test_pkey" | {time,temp} | | t | t | f | + _timescaledb_internal._hyper_12_12_chunk_reindex_test_time_unique_idx | {time} | | t | f | f | +(2 rows) + +CREATE TABLE ht_dropped(time timestamptz, d0 int, d1 int, c0 int, c1 int, c2 int); +SELECT create_hypertable('ht_dropped','time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +-------------------------- + (13,public,ht_dropped,t) +(1 row) + +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2000-01-01',1,2,3; +ALTER TABLE ht_dropped DROP COLUMN d0; +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2001-01-01',1,2,3; +ALTER TABLE ht_dropped DROP COLUMN d1; +INSERT INTO ht_dropped(time,c0,c1,c2) SELECT '2002-01-01',1,2,3; +CREATE INDEX ON ht_dropped(c0,c1,c2) WHERE c1 IS NOT NULL; +CREATE INDEX ON ht_dropped(c0,c1,c2) WITH(timescaledb.transaction_per_chunk) WHERE c2 IS NOT NULL; +SELECT + oid::TEXT AS "Chunk", + i.* +FROM + (SELECT tableoid::REGCLASS FROM ht_dropped GROUP BY tableoid) ch (oid) + LEFT JOIN LATERAL ( SELECT * FROM test.show_indexes (ch.oid)) i ON TRUE +ORDER BY + 1, 2; + Chunk | Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +------------------------------------------+-------------------------------------------------------------------+------------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_17_chunk | _timescaledb_internal._hyper_13_17_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_18_chunk | _timescaledb_internal._hyper_13_18_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_time_idx | {time} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_c0_c1_c2_idx | {c0,c1,c2} | | f | f | f | + _timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f | +(9 rows) + +-- #3056 check chunk index column name mapping +CREATE TABLE i3056(c int, order_number int NOT NULL, date_created timestamptz NOT NULL); +CREATE INDEX ON i3056(order_number) INCLUDE(order_number); +CREATE INDEX ON i3056(date_created, (order_number % 5)) INCLUDE(order_number); +SELECT table_name FROM create_hypertable('i3056', 'date_created'); + table_name +------------ + i3056 +(1 row) + +ALTER TABLE i3056 DROP COLUMN c; +INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); diff --git a/test/sql/CMakeLists.txt b/test/sql/CMakeLists.txt index 297e5e6e2dd..bb5034cf905 100644 --- a/test/sql/CMakeLists.txt +++ b/test/sql/CMakeLists.txt @@ -20,7 +20,6 @@ set(TEST_FILES grant_hypertable.sql hash.sql histogram_test.sql - index.sql insert_many.sql insert_single.sql join.sql @@ -66,6 +65,7 @@ set(TEST_TEMPLATES sort_optimization.sql.in sql_query.sql.in update.sql.in + index.sql.in ) # tests that fail or are unreliable when run in parallel @@ -74,8 +74,11 @@ set(SOLO_TESTS alter alternate_users bgw_launcher - chunk_utils.sql - index + chunk_utils + index-11 + index-12 + index-13 + loader loader net pg_dump_unprivileged diff --git a/test/sql/index.sql b/test/sql/index.sql.in similarity index 99% rename from test/sql/index.sql rename to test/sql/index.sql.in index 3b92cb62e23..494e79d763a 100644 --- a/test/sql/index.sql +++ b/test/sql/index.sql.in @@ -280,6 +280,10 @@ SELECT * FROM test.show_subtables('reindex_test'); REINDEX (VERBOSE) TABLE reindex_test; \set ON_ERROR_STOP 0 + +-- REINDEX TABLE CONCURRENTLY is not supported on PG11 (but blocked on PG12+) +REINDEX TABLE CONCURRENTLY reindex_test; + -- this one currently doesn't recurse to chunks and instead gives an -- error REINDEX (VERBOSE) INDEX reindex_test_time_unique_idx;