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
This commit is contained in:
Dmitry Simonenko 2023-08-03 14:36:39 +03:00 committed by Dmitry Simonenko
parent 52ed394d4d
commit 2863daf3df
4 changed files with 84 additions and 1 deletions

1
.unreleased/bugfix_5909 Normal file
View File

@ -0,0 +1 @@
Implements: #5909 CREATE INDEX ONLY ON hypertable creates index on chunks

View File

@ -2791,6 +2791,7 @@ process_index_start(ProcessUtilityArgs *args)
ts_cagg_permissions_check(ht->main_table_relid, GetUserId()); ts_cagg_permissions_check(ht->main_table_relid, GetUserId());
SWITCH_TO_TS_USER(NameStr(cagg->data.direct_view_schema), uid, saved_uid, sec_ctx); SWITCH_TO_TS_USER(NameStr(cagg->data.direct_view_schema), uid, saved_uid, sec_ctx);
} }
/* CREATE INDEX on the root table of the hypertable */ /* CREATE INDEX on the root table of the hypertable */
root_table_index = ts_indexing_root_table_create_index(stmt, root_table_index = ts_indexing_root_table_create_index(stmt,
args->query_string, args->query_string,
@ -2799,6 +2800,7 @@ process_index_start(ProcessUtilityArgs *args)
if (cagg) if (cagg)
RESTORE_USER(uid, saved_uid, sec_ctx); RESTORE_USER(uid, saved_uid, sec_ctx);
/* root_table_index will have 0 objectId if the index already exists /* 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 * and if_not_exists is true. In that case there is nothing else
* to do here. */ * to do here. */
@ -2808,7 +2810,13 @@ process_index_start(ProcessUtilityArgs *args)
return DDL_DONE; return DDL_DONE;
} }
Assert(OidIsValid(root_table_index.objectId)); 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 */ /* CREATE INDEX on the chunks, unless this is a distributed hypertable */
if (hypertable_is_distributed(ht)) if (hypertable_is_distributed(ht))
@ -2817,6 +2825,7 @@ process_index_start(ProcessUtilityArgs *args)
return DDL_DONE; return DDL_DONE;
} }
info.obj.objectId = root_table_index.objectId;
/* collect information required for per chunk index creation */ /* collect information required for per chunk index creation */
main_table_relation = table_open(ht->main_table_relid, AccessShareLock); main_table_relation = table_open(ht->main_table_relid, AccessShareLock);
main_table_desc = RelationGetDescr(main_table_relation); main_table_desc = RelationGetDescr(main_table_relation);

View File

@ -726,3 +726,58 @@ SELECT table_name FROM create_hypertable('i3056', 'date_created');
ALTER TABLE i3056 DROP COLUMN c; ALTER TABLE i3056 DROP COLUMN c;
INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); 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)

View File

@ -342,4 +342,22 @@ SELECT table_name FROM create_hypertable('i3056', 'date_created');
ALTER TABLE i3056 DROP COLUMN c; ALTER TABLE i3056 DROP COLUMN c;
INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01'); 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');