From 8c356eb82c7823cfb195916b5ab321f886781bc0 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko Date: Thu, 3 Aug 2023 14:36:39 +0300 Subject: [PATCH] Support CREATE INDEX ONLY ON main table This PR adds support for CREATE INDEX ONLY ON clause which allows to create index only on the main table excluding chunks. Fix #5908 --- .unreleased/bugfix_5909 | 1 + src/process_utility.c | 11 ++++++++- test/expected/index.out | 55 +++++++++++++++++++++++++++++++++++++++++ test/sql/index.sql | 18 ++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 .unreleased/bugfix_5909 diff --git a/.unreleased/bugfix_5909 b/.unreleased/bugfix_5909 new file mode 100644 index 00000000000..b10042d6a2c --- /dev/null +++ b/.unreleased/bugfix_5909 @@ -0,0 +1 @@ +Implements: #5909 CREATE INDEX ONLY ON hypertable creates index on chunks diff --git a/src/process_utility.c b/src/process_utility.c index 0a24aac1694..5b581251ea7 100644 --- a/src/process_utility.c +++ b/src/process_utility.c @@ -2791,6 +2791,7 @@ process_index_start(ProcessUtilityArgs *args) ts_cagg_permissions_check(ht->main_table_relid, GetUserId()); SWITCH_TO_TS_USER(NameStr(cagg->data.direct_view_schema), uid, saved_uid, sec_ctx); } + /* CREATE INDEX on the root table of the hypertable */ root_table_index = ts_indexing_root_table_create_index(stmt, args->query_string, @@ -2799,6 +2800,7 @@ process_index_start(ProcessUtilityArgs *args) if (cagg) RESTORE_USER(uid, saved_uid, sec_ctx); + /* root_table_index will have 0 objectId if the index already exists * and if_not_exists is true. In that case there is nothing else * to do here. */ @@ -2808,7 +2810,13 @@ process_index_start(ProcessUtilityArgs *args) return DDL_DONE; } Assert(OidIsValid(root_table_index.objectId)); - info.obj.objectId = root_table_index.objectId; + + /* support ONLY ON clause, index on root table already created */ + if (!stmt->relation->inh) + { + ts_cache_release(hcache); + return DDL_DONE; + } /* CREATE INDEX on the chunks, unless this is a distributed hypertable */ if (hypertable_is_distributed(ht)) @@ -2817,6 +2825,7 @@ process_index_start(ProcessUtilityArgs *args) return DDL_DONE; } + info.obj.objectId = root_table_index.objectId; /* collect information required for per chunk index creation */ main_table_relation = table_open(ht->main_table_relid, AccessShareLock); main_table_desc = RelationGetDescr(main_table_relation); diff --git a/test/expected/index.out b/test/expected/index.out index 6265494fbb8..866637a65e5 100644 --- a/test/expected/index.out +++ b/test/expected/index.out @@ -726,3 +726,58 @@ SELECT table_name FROM create_hypertable('i3056', 'date_created'); ALTER TABLE i3056 DROP COLUMN c; INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); +-- #5908 test CREATE INDEX ON ONLY main table +CREATE TABLE test(time timestamptz, temp float); +SELECT create_hypertable('test', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +-------------------- + (15,public,test,t) +(1 row) + +INSERT INTO test (time,temp) VALUES + (generate_series(TIMESTAMP '2019-08-01', TIMESTAMP '2019-08-10', INTERVAL '10 minutes'), ROUND(RANDOM()*10)::float); +SELECT * FROM show_chunks('test'); + show_chunks +------------------------------------------ + _timescaledb_internal._hyper_15_21_chunk + _timescaledb_internal._hyper_15_22_chunk +(2 rows) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +--------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_15_21_chunk_test_time_idx | {time} | | f | f | f | +(1 row) + +-- create index per chunk +CREATE INDEX _hyper_15_21_chunk_test_temp_idx ON _timescaledb_internal._hyper_15_21_chunk(temp); +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +--------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_15_21_chunk_test_temp_idx | {temp} | | f | f | f | + _timescaledb_internal._hyper_15_21_chunk_test_time_idx | {time} | | f | f | f | +(2 rows) + +SELECT * FROM test.show_indexes('test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------+---------+------+--------+---------+-----------+------------ + test_time_idx | {time} | | f | f | f | +(1 row) + +-- create index only on main table +CREATE INDEX test_temp_idx ON ONLY test (time); +SELECT * FROM test.show_indexes('test'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +---------------+---------+------+--------+---------+-----------+------------ + test_temp_idx | {time} | | f | f | f | + test_time_idx | {time} | | f | f | f | +(2 rows) + +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk'); + Index | Columns | Expr | Unique | Primary | Exclusion | Tablespace +--------------------------------------------------------+---------+------+--------+---------+-----------+------------ + _timescaledb_internal._hyper_15_21_chunk_test_temp_idx | {temp} | | f | f | f | + _timescaledb_internal._hyper_15_21_chunk_test_time_idx | {time} | | f | f | f | +(2 rows) + diff --git a/test/sql/index.sql b/test/sql/index.sql index 3f2450502e3..d325254e99d 100644 --- a/test/sql/index.sql +++ b/test/sql/index.sql @@ -342,4 +342,22 @@ SELECT table_name FROM create_hypertable('i3056', 'date_created'); ALTER TABLE i3056 DROP COLUMN c; INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); +-- #5908 test CREATE INDEX ON ONLY main table +CREATE TABLE test(time timestamptz, temp float); +SELECT create_hypertable('test', 'time'); +INSERT INTO test (time,temp) VALUES + (generate_series(TIMESTAMP '2019-08-01', TIMESTAMP '2019-08-10', INTERVAL '10 minutes'), ROUND(RANDOM()*10)::float); +SELECT * FROM show_chunks('test'); +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk'); + +-- create index per chunk +CREATE INDEX _hyper_15_21_chunk_test_temp_idx ON _timescaledb_internal._hyper_15_21_chunk(temp); +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk'); +SELECT * FROM test.show_indexes('test'); + +-- create index only on main table +CREATE INDEX test_temp_idx ON ONLY test (time); + +SELECT * FROM test.show_indexes('test'); +SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_15_21_chunk');