-- 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');
    create_hypertable    
-------------------------
 (1,public,index_test,t)

-- 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         | 

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);
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');
    create_hypertable    
-------------------------
 (3,public,index_test,t)

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         | 

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         | 

-- 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         | 

-- 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         | 

-- 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

-- 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

-- No pre-existing UNIQUE index, so partitioning on two columns should work
SELECT create_hypertable('index_test', 'time', 'device', 2);
    create_hypertable    
-------------------------
 (4,public,index_test,t)

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         | 

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         | 

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         | 

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         | 

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         | 

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         | 

-- 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 DESC, temp);
CREATE INDEX a_hypertable_index_with_a_very_very_long_name_that_truncates_2 ON index_test (time DESC, temp DESC);
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         | 

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         | 

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         | 

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

\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         | 

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

-- 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         | 

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         | 

-- Constraints are added to chunk_constraint table.
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

DROP TABLE index_test;
-- 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');
    create_hypertable    
-------------------------
 (5,public,index_test,t)

-- 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

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

-- 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

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

-- 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, buffers off, 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)

SELECT * FROM index_expr_test WHERE meta ->> 'field' = 'value1';
             time             | temp |        meta         
------------------------------+------+---------------------
 Fri Jan 20 09:00:01 2017 PST | 17.5 | {"field": "value1"}

-- 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');
    create_hypertable    
-------------------------
 (6,public,index_test,t)

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;
\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');
  table_name   
---------------
 idx_expr_test

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');
  table_name   
---------------
 idx_expr_test

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');
     table_name     
--------------------
 idx_predicate_test

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');
    table_name     
-------------------
 idx_tableref_test

-- 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

-- 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);
WARNING:  column type "timestamp without time zone" used for "time" does not follow best practices
     create_hypertable      
----------------------------
 (12,public,reindex_test,t)

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

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 | 

-- 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 on hypertables is not supported
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

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

CREATE TABLE ht_dropped(time timestamptz, d0 int, d1 int, c0 int, c1 int, c2 int);
SELECT create_hypertable('ht_dropped','time');
    create_hypertable     
--------------------------
 (13,public,ht_dropped,t)

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         | 

-- #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

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');
 create_hypertable  
--------------------
 (15,public,test,t)

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

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         | 

-- 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         | 

SELECT * FROM test.show_indexes('test');
     Index     | Columns | Expr | Unique | Primary | Exclusion | Tablespace 
---------------+---------+------+--------+---------+-----------+------------
 test_time_idx | {time}  |      | f      | f       | f         | 

-- 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         | 

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         | 

