-- 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.
\set TEST_DBNAME_EXTRA :TEST_DBNAME _extra
\o /dev/null
\ir include/insert_two_partitions.sql
-- 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 PUBLIC."two_Partitions" (
  "timeCustom" BIGINT NOT NULL,
  device_id TEXT NOT NULL,
  series_0 DOUBLE PRECISION NULL,
  series_1 DOUBLE PRECISION NULL,
  series_2 DOUBLE PRECISION NULL,
  series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."two_Partitions" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."two_Partitions" ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."two_Partitions" ("timeCustom" DESC NULLS LAST, series_1)  WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."two_Partitions" ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."two_Partitions" ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
CREATE INDEX ON PUBLIC."two_Partitions" ("timeCustom" DESC NULLS LAST, device_id);
SELECT * FROM create_hypertable('"public"."two_Partitions"'::regclass, 'timeCustom'::name, 'device_id'::name, associated_schema_name=>'_timescaledb_internal'::text, number_partitions => 2, chunk_time_interval=>_timescaledb_functions.interval_to_usec('1 month'));
\set QUIET off
BEGIN;
\COPY public."two_Partitions" FROM 'data/ds1_dev1_1.tsv' NULL AS '';
COMMIT;
INSERT INTO public."two_Partitions"("timeCustom", device_id, series_0, series_1) VALUES
(1257987600000000000, 'dev1', 1.5, 1),
(1257987600000000000, 'dev1', 1.5, 2),
(1257894000000000000, 'dev2', 1.5, 1),
(1257894002000000000, 'dev1', 2.5, 3);
INSERT INTO "two_Partitions"("timeCustom", device_id, series_0, series_1) VALUES
(1257894000000000000, 'dev2', 1.5, 2);
\set QUIET on
\o
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE OR REPLACE FUNCTION bgw_wait(database TEXT, timeout INT, raise_error BOOLEAN DEFAULT TRUE)
RETURNS VOID
AS :MODULE_PATHNAME, 'ts_bgw_wait'
LANGUAGE C VOLATILE;
CREATE SCHEMA test_schema AUTHORIZATION :ROLE_DEFAULT_PERM_USER;
\c :TEST_DBNAME
ALTER TABLE PUBLIC."two_Partitions" SET SCHEMA "test_schema";
-- Test that we can restore constraints
ALTER TABLE "test_schema"."two_Partitions"
ADD CONSTRAINT timeCustom_device_id_series_2_key
UNIQUE ("timeCustom", device_id, series_2);
-- Test that we can restore triggers
CREATE OR REPLACE FUNCTION test_trigger()
    RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
BEGIN
    RETURN NEW;
END
$BODY$;
-- Test that a custom chunk sizing function is restored
CREATE OR REPLACE FUNCTION custom_calculate_chunk_interval(
        dimension_id INTEGER,
        dimension_coord BIGINT,
        chunk_target_size BIGINT
)
    RETURNS BIGINT LANGUAGE PLPGSQL AS
$BODY$
DECLARE
BEGIN
    RETURN -1;
END
$BODY$;
SELECT * FROM set_adaptive_chunking('"test_schema"."two_Partitions"', '1 MB', 'custom_calculate_chunk_interval');
WARNING:  target chunk size for adaptive chunking is less than 10 MB
        chunk_sizing_func        | chunk_target_size 
---------------------------------+-------------------
 custom_calculate_chunk_interval |           1048576

-- Chunk sizing func set
SELECT * FROM _timescaledb_catalog.hypertable;
 id | schema_name |   table_name   | associated_schema_name | associated_table_prefix | num_dimensions | chunk_sizing_func_schema |     chunk_sizing_func_name      | chunk_target_size | compression_state | compressed_hypertable_id | status 
----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+---------------------------------+-------------------+-------------------+--------------------------+--------
  1 | test_schema | two_Partitions | _timescaledb_internal  | _hyper_1                |              2 | public                   | custom_calculate_chunk_interval |           1048576 |                 0 |                          |      0

SELECT proname, pronamespace, pronargs
FROM pg_proc WHERE proname = 'custom_calculate_chunk_interval';
             proname             | pronamespace | pronargs 
---------------------------------+--------------+----------
 custom_calculate_chunk_interval |         2200 |        3

CREATE TRIGGER restore_trigger BEFORE INSERT ON "test_schema"."two_Partitions"
FOR EACH ROW EXECUTE FUNCTION test_trigger();
-- Save the number of dependent objects so we can make sure we have the same number later
SELECT count(*) as num_dependent_objects
  FROM pg_depend
 WHERE refclassid = 'pg_extension'::regclass
     AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb')
\gset
SELECT * FROM test.show_columns('"test_schema"."two_Partitions"');
   Column    |       Type       | NotNull 
-------------+------------------+---------
 timeCustom  | bigint           | t
 device_id   | text             | t
 series_0    | double precision | f
 series_1    | double precision | f
 series_2    | double precision | f
 series_bool | boolean          | f

SELECT * FROM test.show_columns('_timescaledb_internal._hyper_1_1_chunk');
   Column    |       Type       | NotNull 
-------------+------------------+---------
 timeCustom  | bigint           | t
 device_id   | text             | t
 series_0    | double precision | f
 series_1    | double precision | f
 series_2    | double precision | f
 series_bool | boolean          | f

SELECT * FROM test.show_indexes('"test_schema"."two_Partitions"');
                          Index                          |             Columns             | Expr | Unique | Primary | Exclusion | Tablespace 
---------------------------------------------------------+---------------------------------+------+--------+---------+-----------+------------
 test_schema.timecustom_device_id_series_2_key           | {timeCustom,device_id,series_2} |      | t      | f       | f         | 
 test_schema."two_Partitions_device_id_timeCustom_idx"   | {device_id,timeCustom}          |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_device_id_idx"   | {timeCustom,device_id}          |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_idx"             | {timeCustom}                    |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_0_idx"    | {timeCustom,series_0}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_1_idx"    | {timeCustom,series_1}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_2_idx"    | {timeCustom,series_2}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_bool_idx" | {timeCustom,series_bool}        |      | f      | f       | f         | 

SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_1_1_chunk');
                                       Index                                        |             Columns             | Expr | Unique | Primary | Exclusion | Tablespace 
------------------------------------------------------------------------------------+---------------------------------+------+--------+---------+-----------+------------
 _timescaledb_internal."1_1_timecustom_device_id_series_2_key"                      | {timeCustom,device_id,series_2} |      | t      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_device_id_timeCustom_idx"   | {device_id,timeCustom}          |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_device_id_idx"   | {timeCustom,device_id}          |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_idx"             | {timeCustom}                    |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_0_idx"    | {timeCustom,series_0}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_1_idx"    | {timeCustom,series_1}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_2_idx"    | {timeCustom,series_2}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" | {timeCustom,series_bool}        |      | f      | f       | f         | 

SELECT * FROM test.show_constraints('"test_schema"."two_Partitions"');
            Constraint             | Type |             Columns             |                     Index                     | Expr | Deferrable | Deferred | Validated 
-----------------------------------+------+---------------------------------+-----------------------------------------------+------+------------+----------+-----------
 timecustom_device_id_series_2_key | u    | {timeCustom,device_id,series_2} | test_schema.timecustom_device_id_series_2_key |      | f          | f        | t

SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_1_1_chunk');
              Constraint               | Type |             Columns             |                             Index                             |                                                 Expr                                                 | Deferrable | Deferred | Validated 
---------------------------------------+------+---------------------------------+---------------------------------------------------------------+------------------------------------------------------------------------------------------------------+------------+----------+-----------
 1_1_timecustom_device_id_series_2_key | u    | {timeCustom,device_id,series_2} | _timescaledb_internal."1_1_timecustom_device_id_series_2_key" |                                                                                                      | f          | f        | t
 constraint_1                          | c    | {timeCustom}                    | -                                                             | (("timeCustom" >= '1257892416000000000'::bigint) AND ("timeCustom" < '1257895008000000000'::bigint)) | f          | f        | t
 constraint_2                          | c    | {device_id}                     | -                                                             | (_timescaledb_functions.get_partition_hash(device_id) >= 1073741823)                                 | f          | f        | t

SELECT * FROM test.show_triggers('"test_schema"."two_Partitions"');
     Trigger     | Type |   Function   
-----------------+------+--------------
 restore_trigger |    7 | test_trigger

SELECT * FROM test.show_triggers('_timescaledb_internal._hyper_1_1_chunk');
     Trigger     | Type |   Function   
-----------------+------+--------------
 restore_trigger |    7 | test_trigger

SELECT * FROM "test_schema"."two_Partitions" ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257894000000000000 | dev1      |      1.5 |        1 |        2 | t
 1257894000000000000 | dev1      |      1.5 |        2 |          | 
 1257894000000000000 | dev2      |      1.5 |        1 |          | 
 1257894000000000000 | dev2      |      1.5 |        2 |          | 
 1257894000000001000 | dev1      |      2.5 |        3 |          | 
 1257894001000000000 | dev1      |      3.5 |        4 |          | 
 1257894002000000000 | dev1      |      2.5 |        3 |          | 
 1257894002000000000 | dev1      |      5.5 |        6 |          | t
 1257894002000000000 | dev1      |      5.5 |        7 |          | f
 1257897600000000000 | dev1      |      4.5 |        5 |          | f
 1257987600000000000 | dev1      |      1.5 |        1 |          | 
 1257987600000000000 | dev1      |      1.5 |        2 |          | 

SELECT * FROM _timescaledb_internal._hyper_1_1_chunk ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257894000000000000 | dev1      |      1.5 |        1 |        2 | t
 1257894000000000000 | dev1      |      1.5 |        2 |          | 
 1257894000000001000 | dev1      |      2.5 |        3 |          | 
 1257894001000000000 | dev1      |      3.5 |        4 |          | 
 1257894002000000000 | dev1      |      2.5 |        3 |          | 
 1257894002000000000 | dev1      |      5.5 |        6 |          | t
 1257894002000000000 | dev1      |      5.5 |        7 |          | f

SELECT * FROM _timescaledb_internal._hyper_1_2_chunk ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257897600000000000 | dev1      |      4.5 |        5 |          | f

-- Show all constraints
SELECT * FROM _timescaledb_catalog.chunk_constraint;
 chunk_id | dimension_slice_id |            constraint_name            |    hypertable_constraint_name     
----------+--------------------+---------------------------------------+-----------------------------------
        1 |                  1 | constraint_1                          | 
        1 |                  2 | constraint_2                          | 
        2 |                  3 | constraint_3                          | 
        2 |                  2 | constraint_2                          | 
        3 |                  4 | constraint_4                          | 
        3 |                  2 | constraint_2                          | 
        4 |                  1 | constraint_1                          | 
        4 |                  5 | constraint_5                          | 
        1 |                    | 1_1_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        2 |                    | 2_2_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        3 |                    | 3_3_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        4 |                    | 4_4_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key

INSERT INTO _timescaledb_catalog.metadata VALUES ('exported_uuid', 'original_uuid', true);
INSERT INTO _timescaledb_catalog.metadata VALUES ('metadata_test', 'FOO', false);
\c postgres :ROLE_SUPERUSER
-- We shell out to a script in order to grab the correct hostname from the
-- environmental variables that originally called this psql command. Sadly
-- vars passed to psql do not work in \! commands so we can't do it that way.
\! utils/pg_dump_aux_dump.sh dump/pg_dump.sql
\c :TEST_DBNAME
SET client_min_messages = ERROR;
CREATE EXTENSION timescaledb CASCADE;
--create a exported uuid before restoring (mocks telemetry running before restore)
INSERT INTO _timescaledb_catalog.metadata VALUES ('exported_uuid', 'new_db_uuid', true);
-- disable background jobs
UPDATE _timescaledb_catalog.bgw_job SET scheduled = false;
RESET client_min_messages;
SELECT timescaledb_pre_restore();
 timescaledb_pre_restore 
-------------------------
 t

SHOW timescaledb.restoring;
 timescaledb.restoring 
-----------------------
 on

-- reconnect and check GUC value in new session
\c
SHOW timescaledb.restoring;
 timescaledb.restoring 
-----------------------
 on

\! utils/pg_dump_aux_restore.sh dump/pg_dump.sql
-- Now run our post-restore function.
SELECT timescaledb_post_restore();
 timescaledb_post_restore 
--------------------------
 t

SHOW timescaledb.restoring;
 timescaledb.restoring 
-----------------------
 off

-- timescaledb_post_restore restarts background worker so we have to stop them
-- to make sure they dont interfere with this database being used as template below
SELECT _timescaledb_functions.stop_background_workers();
 stop_background_workers 
-------------------------
 t

--should be same as count above
SELECT count(*) = :num_dependent_objects as dependent_objects_match
  FROM pg_depend
 WHERE refclassid = 'pg_extension'::regclass
     AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb');
 dependent_objects_match 
-------------------------
 t

--we should have the original uuid from the backed up db set as the exported_uuid
SELECT value = 'original_uuid' FROM _timescaledb_catalog.metadata  WHERE key='exported_uuid';
 ?column? 
----------
 t

SELECT count(*) = 1 FROM _timescaledb_catalog.metadata WHERE key LIKE 'exported%';
 ?column? 
----------
 t

--we should have the original value of metadata_test
SELECT * FROM _timescaledb_catalog.metadata  WHERE key='metadata_test';
      key      | value | include_in_telemetry 
---------------+-------+----------------------
 metadata_test | FOO   | f

--main table and chunk schemas should be the same
SELECT * FROM test.show_columns('"test_schema"."two_Partitions"');
   Column    |       Type       | NotNull 
-------------+------------------+---------
 timeCustom  | bigint           | t
 device_id   | text             | t
 series_0    | double precision | f
 series_1    | double precision | f
 series_2    | double precision | f
 series_bool | boolean          | f

SELECT * FROM test.show_columns('_timescaledb_internal._hyper_1_1_chunk');
   Column    |       Type       | NotNull 
-------------+------------------+---------
 timeCustom  | bigint           | t
 device_id   | text             | t
 series_0    | double precision | f
 series_1    | double precision | f
 series_2    | double precision | f
 series_bool | boolean          | f

SELECT * FROM test.show_indexes('"test_schema"."two_Partitions"');
                          Index                          |             Columns             | Expr | Unique | Primary | Exclusion | Tablespace 
---------------------------------------------------------+---------------------------------+------+--------+---------+-----------+------------
 test_schema.timecustom_device_id_series_2_key           | {timeCustom,device_id,series_2} |      | t      | f       | f         | 
 test_schema."two_Partitions_device_id_timeCustom_idx"   | {device_id,timeCustom}          |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_device_id_idx"   | {timeCustom,device_id}          |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_idx"             | {timeCustom}                    |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_0_idx"    | {timeCustom,series_0}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_1_idx"    | {timeCustom,series_1}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_2_idx"    | {timeCustom,series_2}           |      | f      | f       | f         | 
 test_schema."two_Partitions_timeCustom_series_bool_idx" | {timeCustom,series_bool}        |      | f      | f       | f         | 

SELECT * FROM test.show_indexes('_timescaledb_internal._hyper_1_1_chunk');
                                       Index                                        |             Columns             | Expr | Unique | Primary | Exclusion | Tablespace 
------------------------------------------------------------------------------------+---------------------------------+------+--------+---------+-----------+------------
 _timescaledb_internal."1_1_timecustom_device_id_series_2_key"                      | {timeCustom,device_id,series_2} |      | t      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_device_id_timeCustom_idx"   | {device_id,timeCustom}          |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_device_id_idx"   | {timeCustom,device_id}          |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_idx"             | {timeCustom}                    |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_0_idx"    | {timeCustom,series_0}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_1_idx"    | {timeCustom,series_1}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_2_idx"    | {timeCustom,series_2}           |      | f      | f       | f         | 
 _timescaledb_internal."_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" | {timeCustom,series_bool}        |      | f      | f       | f         | 

SELECT * FROM test.show_constraints('"test_schema"."two_Partitions"');
            Constraint             | Type |             Columns             |                     Index                     | Expr | Deferrable | Deferred | Validated 
-----------------------------------+------+---------------------------------+-----------------------------------------------+------+------------+----------+-----------
 timecustom_device_id_series_2_key | u    | {timeCustom,device_id,series_2} | test_schema.timecustom_device_id_series_2_key |      | f          | f        | t

SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_1_1_chunk');
              Constraint               | Type |             Columns             |                             Index                             |                                                 Expr                                                 | Deferrable | Deferred | Validated 
---------------------------------------+------+---------------------------------+---------------------------------------------------------------+------------------------------------------------------------------------------------------------------+------------+----------+-----------
 1_1_timecustom_device_id_series_2_key | u    | {timeCustom,device_id,series_2} | _timescaledb_internal."1_1_timecustom_device_id_series_2_key" |                                                                                                      | f          | f        | t
 constraint_1                          | c    | {timeCustom}                    | -                                                             | (("timeCustom" >= '1257892416000000000'::bigint) AND ("timeCustom" < '1257895008000000000'::bigint)) | f          | f        | t
 constraint_2                          | c    | {device_id}                     | -                                                             | (_timescaledb_functions.get_partition_hash(device_id) >= 1073741823)                                 | f          | f        | t

SELECT * FROM test.show_triggers('"test_schema"."two_Partitions"');
     Trigger     | Type |   Function   
-----------------+------+--------------
 restore_trigger |    7 | test_trigger

SELECT * FROM test.show_triggers('_timescaledb_internal._hyper_1_1_chunk');
     Trigger     | Type |   Function   
-----------------+------+--------------
 restore_trigger |    7 | test_trigger

--data should be the same
SELECT * FROM "test_schema"."two_Partitions" ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257894000000000000 | dev1      |      1.5 |        1 |        2 | t
 1257894000000000000 | dev1      |      1.5 |        2 |          | 
 1257894000000000000 | dev2      |      1.5 |        1 |          | 
 1257894000000000000 | dev2      |      1.5 |        2 |          | 
 1257894000000001000 | dev1      |      2.5 |        3 |          | 
 1257894001000000000 | dev1      |      3.5 |        4 |          | 
 1257894002000000000 | dev1      |      2.5 |        3 |          | 
 1257894002000000000 | dev1      |      5.5 |        6 |          | t
 1257894002000000000 | dev1      |      5.5 |        7 |          | f
 1257897600000000000 | dev1      |      4.5 |        5 |          | f
 1257987600000000000 | dev1      |      1.5 |        1 |          | 
 1257987600000000000 | dev1      |      1.5 |        2 |          | 

SELECT * FROM _timescaledb_internal._hyper_1_1_chunk ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257894000000000000 | dev1      |      1.5 |        1 |        2 | t
 1257894000000000000 | dev1      |      1.5 |        2 |          | 
 1257894000000001000 | dev1      |      2.5 |        3 |          | 
 1257894001000000000 | dev1      |      3.5 |        4 |          | 
 1257894002000000000 | dev1      |      2.5 |        3 |          | 
 1257894002000000000 | dev1      |      5.5 |        6 |          | t
 1257894002000000000 | dev1      |      5.5 |        7 |          | f

SELECT * FROM _timescaledb_internal._hyper_1_2_chunk ORDER BY "timeCustom", device_id, series_0, series_1;
     timeCustom      | device_id | series_0 | series_1 | series_2 | series_bool 
---------------------+-----------+----------+----------+----------+-------------
 1257897600000000000 | dev1      |      4.5 |        5 |          | f

SELECT * FROM _timescaledb_catalog.chunk_constraint;
 chunk_id | dimension_slice_id |            constraint_name            |    hypertable_constraint_name     
----------+--------------------+---------------------------------------+-----------------------------------
        1 |                  1 | constraint_1                          | 
        1 |                  2 | constraint_2                          | 
        2 |                  3 | constraint_3                          | 
        2 |                  2 | constraint_2                          | 
        3 |                  4 | constraint_4                          | 
        3 |                  2 | constraint_2                          | 
        4 |                  1 | constraint_1                          | 
        4 |                  5 | constraint_5                          | 
        1 |                    | 1_1_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        2 |                    | 2_2_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        3 |                    | 3_3_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key
        4 |                    | 4_4_timecustom_device_id_series_2_key | timecustom_device_id_series_2_key

--Chunk sizing function should have been restored
SELECT * FROM _timescaledb_catalog.hypertable;
 id | schema_name |   table_name   | associated_schema_name | associated_table_prefix | num_dimensions | chunk_sizing_func_schema |     chunk_sizing_func_name      | chunk_target_size | compression_state | compressed_hypertable_id | status 
----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+---------------------------------+-------------------+-------------------+--------------------------+--------
  1 | test_schema | two_Partitions | _timescaledb_internal  | _hyper_1                |              2 | public                   | custom_calculate_chunk_interval |           1048576 |                 0 |                          |      0

SELECT proname, pronamespace, pronargs
FROM pg_proc WHERE proname = 'custom_calculate_chunk_interval';
             proname             | pronamespace | pronargs 
---------------------------------+--------------+----------
 custom_calculate_chunk_interval |         2200 |        3

--check simple ddl still works
ALTER TABLE "test_schema"."two_Partitions" ADD COLUMN series_3 integer;
INSERT INTO "test_schema"."two_Partitions"("timeCustom", device_id, series_0, series_1, series_3) VALUES
(1357894000000000000, 'dev5', 1.5, 2, 4);
SELECT * FROM ONLY "test_schema"."two_Partitions";
 timeCustom | device_id | series_0 | series_1 | series_2 | series_bool | series_3 
------------+-----------+----------+----------+----------+-------------+----------

--query for the extension tables/sequences that will not be dumped by pg_dump (should
--be empty except for views and explicitly excluded tables)
SELECT objid::regclass
FROM pg_catalog.pg_depend
WHERE   refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
        refobjid = (select oid from pg_extension where extname='timescaledb') AND
        deptype = 'e' AND
        classid='pg_catalog.pg_class'::pg_catalog.regclass
        AND objid NOT IN (select unnest(extconfig) from pg_extension where extname='timescaledb')
        ORDER BY objid::regclass::text COLLATE "C";
                          objid                          
---------------------------------------------------------
 _timescaledb_cache.cache_inval_bgw_job
 _timescaledb_cache.cache_inval_extension
 _timescaledb_cache.cache_inval_hypertable
 _timescaledb_catalog.chunk_rewrite
 _timescaledb_catalog.compression_algorithm
 _timescaledb_catalog.tablespace_id_seq
 _timescaledb_catalog.telemetry_event
 _timescaledb_config.bgw_job
 _timescaledb_internal.bgw_job_stat
 _timescaledb_internal.bgw_job_stat_history
 _timescaledb_internal.bgw_job_stat_history_id_seq
 _timescaledb_internal.bgw_policy_chunk_stats
 _timescaledb_internal.compressed_chunk_stats
 _timescaledb_internal.hypertable_chunk_local_size
 timescaledb_experimental.policies
 timescaledb_information.chunk_columnstore_settings
 timescaledb_information.chunk_compression_settings
 timescaledb_information.chunks
 timescaledb_information.compression_settings
 timescaledb_information.continuous_aggregates
 timescaledb_information.dimensions
 timescaledb_information.hypertable_columnstore_settings
 timescaledb_information.hypertable_compression_settings
 timescaledb_information.hypertables
 timescaledb_information.job_errors
 timescaledb_information.job_history
 timescaledb_information.job_stats
 timescaledb_information.jobs

-- Make sure we can't run our restoring functions as a normal perm user as that would disable functionality for the whole db
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- Hides error messages in cases where error messages differ between Postgres versions
create or replace function get_sqlstate(in_text TEXT) RETURNS TEXT AS
$$
BEGIN
    BEGIN
        EXECUTE in_text;
    EXCEPTION WHEN others THEN GET STACKED DIAGNOSTICS in_text = RETURNED_SQLSTATE;
    END;
    RETURN in_text;
END;
$$
LANGUAGE PLPGSQL;
SELECT get_sqlstate('SELECT timescaledb_pre_restore()');
 get_sqlstate 
--------------
 42501

SELECT get_sqlstate('SELECT timescaledb_post_restore()');
 get_sqlstate 
--------------
 42501

drop function get_sqlstate(TEXT);
-- Check that the extension can be copied from an existing database
-- without explicitly installing it. Stop background workers since we
-- cannot have any backends connected to the database when cloning it.
\c :TEST_DBNAME :ROLE_SUPERUSER
SELECT timescaledb_pre_restore();
 timescaledb_pre_restore 
-------------------------
 t

SELECT bgw_wait(:'TEST_DBNAME', 60, FALSE);
 bgw_wait 
----------
 

-- Force other sessions connected to the TEST_DBNAME to be finished
\c postgres :ROLE_SUPERUSER
REVOKE CONNECT ON DATABASE :TEST_DBNAME FROM public;
ALTER DATABASE :TEST_DBNAME allow_connections = off;
SET client_min_messages TO ERROR;
SELECT COUNT(pg_catalog.pg_terminate_backend(pid))>=0
FROM pg_stat_activity
WHERE datname = ':TEST_DBNAME';
 ?column? 
----------
 t

RESET client_min_messages;
CREATE DATABASE :TEST_DBNAME_EXTRA WITH TEMPLATE :TEST_DBNAME;
ALTER DATABASE :TEST_DBNAME allow_connections = on;
GRANT CONNECT ON DATABASE :TEST_DBNAME TO public;
-- Connect to the database and do some basic stuff to check that the
-- extension works.
\c :TEST_DBNAME_EXTRA :ROLE_DEFAULT_PERM_USER
CREATE TABLE test_tz(time timestamptz not null, temp float8, device text);
SELECT create_hypertable('test_tz', 'time', 'device', 2);
  create_hypertable   
----------------------
 (2,public,test_tz,t)

SELECT id, schema_name, table_name FROM _timescaledb_catalog.hypertable;
 id | schema_name |   table_name   
----+-------------+----------------
  1 | test_schema | two_Partitions
  2 | public      | test_tz

INSERT INTO test_tz VALUES('Mon Mar 20 09:17:00.936242 2017', 23.4, 'dev1');
INSERT INTO test_tz VALUES('Mon Mar 20 09:27:00.936242 2017', 22, 'dev2');
INSERT INTO test_tz VALUES('Mon Mar 20 09:28:00.936242 2017', 21.2, 'dev1');
INSERT INTO test_tz VALUES('Mon Mar 20 09:37:00.936242 2017', 30, 'dev3');
SELECT * FROM test_tz ORDER BY time;
                time                 | temp | device 
-------------------------------------+------+--------
 Mon Mar 20 09:17:00.936242 2017 PDT | 23.4 | dev1
 Mon Mar 20 09:27:00.936242 2017 PDT |   22 | dev2
 Mon Mar 20 09:28:00.936242 2017 PDT | 21.2 | dev1
 Mon Mar 20 09:37:00.936242 2017 PDT |   30 | dev3

\c :TEST_DBNAME :ROLE_SUPERUSER
-- make sure nobody is using it
SET client_min_messages TO ERROR;
REVOKE CONNECT ON DATABASE :TEST_DBNAME_EXTRA FROM public;
SELECT count(pg_terminate_backend(pg_stat_activity.pid)) AS TERMINATED
FROM pg_stat_activity
WHERE pg_stat_activity.datname = :'TEST_DBNAME_EXTRA'
AND pg_stat_activity.pid <> pg_backend_pid() \gset
RESET client_min_messages;
DROP DATABASE :TEST_DBNAME_EXTRA WITH (FORCE);
