-- 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.
--
--
-- Test "time" partitioning on UUIDv7
--
--
CREATE TABLE uuid_events(id uuid primary key, device int, temp float);
\set ON_ERROR_STOP 0
-- Test invalid interval type
SELECT create_hypertable('uuid_events', 'id', chunk_time_interval => true);
ERROR:  invalid interval type for uuid dimension
\set ON_ERROR_STOP 1
SELECT create_hypertable('uuid_events', 'id', chunk_time_interval => interval '1 day');
    create_hypertable     
--------------------------
 (1,public,uuid_events,t)

SELECT time_interval
FROM timescaledb_information.dimensions
WHERE hypertable_name = 'uuid_events';
 time_interval 
---------------
 @ 1 day

--
-- Test that inserting boundary values generates the right constraints
-- on chunks.
--
-- First value with min time: 00000000-0000-7000-8000-000000000000
BEGIN;
INSERT INTO uuid_events VALUES ('00000000-0000-7000-8000-000000000000', 1, 1.0);
SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                                                      Expr                                                      | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------+------------+----------+-----------
 1_1_uuid_events_pkey | p    | {id}    | _timescaledb_internal."1_1_uuid_events_pkey" |                                                                                                                | f          | f        | t
 constraint_1         | c    | {id}    | -                                            | ((id >= '00000000-0000-0000-0000-000000000000'::uuid) AND (id < '00000526-5c00-0000-0000-000000000000'::uuid)) | f          | f        | t

SELECT uuid_timestamp(id), device, temp
FROM uuid_events ORDER BY id;
        uuid_timestamp        | device | temp 
------------------------------+--------+------
 Wed Dec 31 16:00:00 1969 PST |      1 |    1

-- Update v7 UUID to a v4 UUID that doesn't violate the chunk's range
-- constraint. Currently we don't prevent this "loophole".
UPDATE uuid_events SET id = '00000000-0001-4000-8000-000000000000'
WHERE id = '00000000-0000-7000-8000-000000000000';
SELECT uuid_timestamp(id), device, temp
FROM uuid_events ORDER BY id;
 uuid_timestamp | device | temp 
----------------+--------+------
                |      1 |    1

-- Update v7 UUID to a v4 that violates the chunk constraint:
\set ON_ERROR_STOP 0
UPDATE uuid_events SET id = 'ffff0000-0000-4000-8000-000000000000'
WHERE id = '00000000-0001-4000-8000-000000000000';
ERROR:  new row for relation "_hyper_1_1_chunk" violates check constraint "constraint_1"
\set ON_ERROR_STOP 1
ROLLBACK;
-- Last value with min time: 00000000-0000-7fff-bfff-ffffffffffff
BEGIN;
INSERT INTO uuid_events VALUES ('00000000-0000-7fff-bfff-ffffffffffff', 1, 1.0);
SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                                                      Expr                                                      | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------+------------+----------+-----------
 2_2_uuid_events_pkey | p    | {id}    | _timescaledb_internal."2_2_uuid_events_pkey" |                                                                                                                | f          | f        | t
 constraint_2         | c    | {id}    | -                                            | ((id >= '00000000-0000-0000-0000-000000000000'::uuid) AND (id < '00000526-5c00-0000-0000-000000000000'::uuid)) | f          | f        | t

ROLLBACK;
-- First value with max time: ffffffff-ffff-7000-8000-000000000000
BEGIN;
INSERT INTO uuid_events VALUES ('ffffffff-ffff-7000-8000-000000000000', 1, 1.0);
SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                         Expr                         | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+------------------------------------------------------+------------+----------+-----------
 3_3_uuid_events_pkey | p    | {id}    | _timescaledb_internal."3_3_uuid_events_pkey" |                                                      | f          | f        | t
 constraint_3         | c    | {id}    | -                                            | (id >= 'fffffed0-3000-0000-0000-000000000000'::uuid) | f          | f        | t

ROLLBACK;
-- (Max time with min value) + 1
BEGIN;
INSERT INTO uuid_events VALUES ('ffffffff-ffff-7000-8000-000000000001', 1, 1.0);
SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                         Expr                         | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+------------------------------------------------------+------------+----------+-----------
 4_4_uuid_events_pkey | p    | {id}    | _timescaledb_internal."4_4_uuid_events_pkey" |                                                      | f          | f        | t
 constraint_4         | c    | {id}    | -                                            | (id >= 'fffffed0-3000-0000-0000-000000000000'::uuid) | f          | f        | t

ROLLBACK;
-- Last value with max time: ffffffff-ffff-7fff-bfff-ffffffffffff
BEGIN;
INSERT INTO uuid_events VALUES ('ffffffff-ffff-7fff-bfff-ffffffffffff', 1, 1.0);
SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                         Expr                         | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+------------------------------------------------------+------------+----------+-----------
 5_5_uuid_events_pkey | p    | {id}    | _timescaledb_internal."5_5_uuid_events_pkey" |                                                      | f          | f        | t
 constraint_5         | c    | {id}    | -                                            | (id >= 'fffffed0-3000-0000-0000-000000000000'::uuid) | f          | f        | t

ROLLBACK;
--
-- It is possible to generate UUIDs like follows, but the random
-- generator used doesn't respect setseed() so used constant UUIDs for
-- determinism.
--
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-01 01:00 PST'), 1, 1.0),
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-01 02:00 PST'), 2, 2.0),
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-02 01:00 PST'), 3, 3.0),
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-02 02:00 PST'), 4, 4.0),
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-03 03:00 PST'), 5, 5.0),
-- (_timescaledb_functions.uuid_v7_from_timestamptz('2025-01-03 10:00 PST'), 6, 6.0);
--
INSERT INTO uuid_events VALUES
       ('0194214e-cd00-7000-a9a7-63f1416dab45', 2, 2.0),
       ('01942117-de80-7000-8121-f12b2b69dd96', 1, 1.0),
       ('0194263e-3a80-7000-8f40-82c987b1bc1f', 3, 3.0),
       ('01942675-2900-7000-8db1-a98694b18785', 4, 4.0),
       ('01942bd2-7380-7000-9bc4-5f97443907b8', 5, 5.0),
       ('01942d52-f900-7000-866e-07d6404d53c1', 6, 6.0);
SELECT * FROM show_chunks('uuid_events');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_6_chunk
 _timescaledb_internal._hyper_1_7_chunk
 _timescaledb_internal._hyper_1_8_chunk

SELECT (test.show_constraints(ch)).* from show_chunks('uuid_events') ch;
      Constraint      | Type | Columns |                    Index                     |                                                      Expr                                                      | Deferrable | Deferred | Validated 
----------------------+------+---------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------+------------+----------+-----------
 6_6_uuid_events_pkey | p    | {id}    | _timescaledb_internal."6_6_uuid_events_pkey" |                                                                                                                | f          | f        | t
 constraint_6         | c    | {id}    | -                                            | ((id >= '01941f29-7c00-0000-0000-000000000000'::uuid) AND (id < '0194244f-d800-0000-0000-000000000000'::uuid)) | f          | f        | t
 7_7_uuid_events_pkey | p    | {id}    | _timescaledb_internal."7_7_uuid_events_pkey" |                                                                                                                | f          | f        | t
 constraint_7         | c    | {id}    | -                                            | ((id >= '0194244f-d800-0000-0000-000000000000'::uuid) AND (id < '01942976-3400-0000-0000-000000000000'::uuid)) | f          | f        | t
 8_8_uuid_events_pkey | p    | {id}    | _timescaledb_internal."8_8_uuid_events_pkey" |                                                                                                                | f          | f        | t
 constraint_8         | c    | {id}    | -                                            | ((id >= '01942976-3400-0000-0000-000000000000'::uuid) AND (id < '01942e9c-9000-0000-0000-000000000000'::uuid)) | f          | f        | t

SELECT id, device, temp FROM uuid_events;
                  id                  | device | temp 
--------------------------------------+--------+------
 0194214e-cd00-7000-a9a7-63f1416dab45 |      2 |    2
 01942117-de80-7000-8121-f12b2b69dd96 |      1 |    1
 0194263e-3a80-7000-8f40-82c987b1bc1f |      3 |    3
 01942675-2900-7000-8db1-a98694b18785 |      4 |    4
 01942bd2-7380-7000-9bc4-5f97443907b8 |      5 |    5
 01942d52-f900-7000-866e-07d6404d53c1 |      6 |    6

SELECT uuid_timestamp(id), device, temp
FROM uuid_events;
        uuid_timestamp        | device | temp 
------------------------------+--------+------
 Wed Jan 01 02:00:00 2025 PST |      2 |    2
 Wed Jan 01 01:00:00 2025 PST |      1 |    1
 Thu Jan 02 01:00:00 2025 PST |      3 |    3
 Thu Jan 02 02:00:00 2025 PST |      4 |    4
 Fri Jan 03 03:00:00 2025 PST |      5 |    5
 Fri Jan 03 10:00:00 2025 PST |      6 |    6

SELECT uuid_timestamp(id), device, temp
FROM uuid_events ORDER BY id;
        uuid_timestamp        | device | temp 
------------------------------+--------+------
 Wed Jan 01 01:00:00 2025 PST |      1 |    1
 Wed Jan 01 02:00:00 2025 PST |      2 |    2
 Thu Jan 02 01:00:00 2025 PST |      3 |    3
 Thu Jan 02 02:00:00 2025 PST |      4 |    4
 Fri Jan 03 03:00:00 2025 PST |      5 |    5
 Fri Jan 03 10:00:00 2025 PST |      6 |    6

SELECT
    _timescaledb_functions.to_timestamp(range_start) AS range_start,
    _timescaledb_functions.to_timestamp(range_end) AS range_end
FROM _timescaledb_catalog.dimension_slice ds
JOIN _timescaledb_catalog.dimension d ON (ds.dimension_id = d.id)
JOIN _timescaledb_catalog.hypertable h ON (d.hypertable_id = h.id)
WHERE h.table_name = 'uuid_events';
         range_start          |          range_end           
------------------------------+------------------------------
 Tue Dec 31 16:00:00 2024 PST | Wed Jan 01 16:00:00 2025 PST
 Wed Jan 01 16:00:00 2025 PST | Thu Jan 02 16:00:00 2025 PST
 Thu Jan 02 16:00:00 2025 PST | Fri Jan 03 16:00:00 2025 PST

SELECT
    _timescaledb_functions.to_timestamp(range_start) AS chunk_range_start,
    _timescaledb_functions.to_timestamp(range_end) AS chunk_range_end
FROM _timescaledb_catalog.dimension_slice ds
JOIN _timescaledb_catalog.dimension d ON (ds.dimension_id = d.id)
JOIN _timescaledb_catalog.hypertable h ON (d.hypertable_id = h.id)
WHERE h.table_name = 'uuid_events'
LIMIT 1 OFFSET 1 \gset
-- Test that chunk exclusion on uuidv7 column works
SELECT :'chunk_range_start',  to_uuidv7_boundary(:'chunk_range_start');
           ?column?           |          to_uuidv7_boundary          
------------------------------+--------------------------------------
 Wed Jan 01 16:00:00 2025 PST | 0194244f-d800-7000-8000-000000000000

-- Exclude all but one chunk
EXPLAIN (verbose, buffers off, costs off, timing off)
SELECT uuid_timestamp(id), device, temp
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_start');
--- QUERY PLAN ---
 Result
   Output: uuid_timestamp(_hyper_1_6_chunk.id), _hyper_1_6_chunk.device, _hyper_1_6_chunk.temp
   ->  Seq Scan on _timescaledb_internal._hyper_1_6_chunk
         Output: _hyper_1_6_chunk.id, _hyper_1_6_chunk.device, _hyper_1_6_chunk.temp

SELECT uuid_timestamp(id), device, temp
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_start') ORDER BY id;
        uuid_timestamp        | device | temp 
------------------------------+--------+------
 Wed Jan 01 01:00:00 2025 PST |      1 |    1
 Wed Jan 01 02:00:00 2025 PST |      2 |    2

-- Exclude only one chunk. Add ordering (DESC)
EXPLAIN (verbose, buffers off, costs off, timing off)
SELECT uuid_timestamp(id), device, temp
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
ORDER BY id DESC;
--- QUERY PLAN ---
 Result
   Output: uuid_timestamp(uuid_events.id), uuid_events.device, uuid_events.temp, uuid_events.id
   ->  Custom Scan (ChunkAppend) on public.uuid_events
         Output: uuid_events.id, uuid_events.device, uuid_events.temp
         Order: uuid_events.id DESC
         Startup Exclusion: false
         Runtime Exclusion: false
         ->  Index Scan Backward using "7_7_uuid_events_pkey" on _timescaledb_internal._hyper_1_7_chunk
               Output: _hyper_1_7_chunk.id, _hyper_1_7_chunk.device, _hyper_1_7_chunk.temp
         ->  Index Scan Backward using "6_6_uuid_events_pkey" on _timescaledb_internal._hyper_1_6_chunk
               Output: _hyper_1_6_chunk.id, _hyper_1_6_chunk.device, _hyper_1_6_chunk.temp

SELECT uuid_timestamp(id), device, temp
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
ORDER BY id DESC;
        uuid_timestamp        | device | temp 
------------------------------+--------+------
 Thu Jan 02 02:00:00 2025 PST |      4 |    4
 Thu Jan 02 01:00:00 2025 PST |      3 |    3
 Wed Jan 01 02:00:00 2025 PST |      2 |    2
 Wed Jan 01 01:00:00 2025 PST |      1 |    1

SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 16:00:00 2025 PST |   4
 Wed Jan 01 16:00:00 2025 PST |   3
 Tue Dec 31 16:00:00 2024 PST |   2
 Tue Dec 31 16:00:00 2024 PST |   1

SELECT time_bucket('1 day', uuid_timestamp(id)) AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 16:00:00 2025 PST |   4
 Wed Jan 01 16:00:00 2025 PST |   3
 Tue Dec 31 16:00:00 2024 PST |   2
 Tue Dec 31 16:00:00 2024 PST |   1

-- Bucket with offset
SELECT time_bucket('1 day', id, "offset" => '1 week') AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 16:00:00 2025 PST |   4
 Wed Jan 01 16:00:00 2025 PST |   3
 Tue Dec 31 16:00:00 2024 PST |   2
 Tue Dec 31 16:00:00 2024 PST |   1

-- Bucket with origin
SELECT time_bucket('1 day', id, timestamptz '2000-01-01 00:00') AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Thu Jan 02 00:00:00 2025 PST |   4
 Thu Jan 02 00:00:00 2025 PST |   3
 Wed Jan 01 00:00:00 2025 PST |   2
 Wed Jan 01 00:00:00 2025 PST |   1

-- Bucket with time zone
SELECT time_bucket('1 day', id, 'Europe/Stockholm') at time zone 'Europe/Stockholm' as day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
           day            | avg 
--------------------------+-----
 Thu Jan 02 00:00:00 2025 |   4
 Thu Jan 02 00:00:00 2025 |   3
 Wed Jan 01 00:00:00 2025 |   2
 Wed Jan 01 00:00:00 2025 |   1

-- Test NULL arguments
SELECT time_bucket('1 day', id, 'Europe/Stockholm'::text, NULL::timestamptz) AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 15:00:00 2025 PST |   4
 Wed Jan 01 15:00:00 2025 PST |   3
 Tue Dec 31 15:00:00 2024 PST |   2
 Tue Dec 31 15:00:00 2024 PST |   1

SELECT time_bucket('1 day', id, 'Europe/Stockholm'::text, '2000-01-01 00:00'::timestamptz, NULL::interval) AS day, avg(temp)
FROM uuid_events WHERE id < to_uuidv7_boundary(:'chunk_range_end')
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Thu Jan 02 00:00:00 2025 PST |   4
 Thu Jan 02 00:00:00 2025 PST |   3
 Wed Jan 01 00:00:00 2025 PST |   2
 Wed Jan 01 00:00:00 2025 PST |   1

-- Test UUID time_bucket in WHERE clause. Note that there is currently no chunk
-- exclusion when using time_bucket() in the WHERE clause qual. This requires
-- special handling of the time_bucket() transform optimizatios for different
-- operators.
EXPLAIN (COSTS OFF) SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) >= :'chunk_range_end'
GROUP BY id ORDER BY id DESC;
--- QUERY PLAN ---
 Sort
   Sort Key: _hyper_1_8_chunk.id DESC
   ->  HashAggregate
         Group Key: _hyper_1_8_chunk.id
         ->  Seq Scan on _hyper_1_8_chunk
               Filter: (time_bucket('@ 1 day'::interval, id) >= 'Thu Jan 02 16:00:00 2025 PST'::timestamp with time zone)

SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) >= :'chunk_range_end'
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Thu Jan 02 16:00:00 2025 PST |   6
 Thu Jan 02 16:00:00 2025 PST |   5

EXPLAIN (COSTS OFF) SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) > :'chunk_range_start'
GROUP BY id ORDER BY id DESC;
--- QUERY PLAN ---
 GroupAggregate
   Group Key: uuid_events.id
   ->  Custom Scan (ChunkAppend) on uuid_events
         Order: uuid_events.id DESC
         ->  Index Scan Backward using "8_8_uuid_events_pkey" on _hyper_1_8_chunk
               Filter: (time_bucket('@ 1 day'::interval, id) > 'Wed Jan 01 16:00:00 2025 PST'::timestamp with time zone)
         ->  Index Scan Backward using "7_7_uuid_events_pkey" on _hyper_1_7_chunk
               Index Cond: (id > '0194244f-d800-7000-8000-000000000000'::uuid)
               Filter: (time_bucket('@ 1 day'::interval, id) > 'Wed Jan 01 16:00:00 2025 PST'::timestamp with time zone)

SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) > :'chunk_range_start'
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Thu Jan 02 16:00:00 2025 PST |   6
 Thu Jan 02 16:00:00 2025 PST |   5

EXPLAIN (COSTS OFF) SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) < :'chunk_range_end'
GROUP BY id ORDER BY id DESC;
--- QUERY PLAN ---
 Sort
   Sort Key: uuid_events.id DESC
   ->  HashAggregate
         Group Key: uuid_events.id
         ->  Append
               ->  Seq Scan on _hyper_1_7_chunk
                     Filter: (time_bucket('@ 1 day'::interval, id) < 'Thu Jan 02 16:00:00 2025 PST'::timestamp with time zone)
               ->  Seq Scan on _hyper_1_6_chunk
                     Filter: (time_bucket('@ 1 day'::interval, id) < 'Thu Jan 02 16:00:00 2025 PST'::timestamp with time zone)

SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) < :'chunk_range_end'
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 16:00:00 2025 PST |   4
 Wed Jan 01 16:00:00 2025 PST |   3
 Tue Dec 31 16:00:00 2024 PST |   2
 Tue Dec 31 16:00:00 2024 PST |   1

EXPLAIN (COSTS OFF) SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) <= :'chunk_range_start'
GROUP BY id ORDER BY id DESC;
--- QUERY PLAN ---
 Sort
   Sort Key: uuid_events.id DESC
   ->  HashAggregate
         Group Key: uuid_events.id
         ->  Append
               ->  Index Scan Backward using "8_8_uuid_events_pkey" on _hyper_1_8_chunk
                     Index Cond: (id <= '01942976-3400-7000-8000-000000000000'::uuid)
                     Filter: (time_bucket('@ 1 day'::interval, id) <= 'Wed Jan 01 16:00:00 2025 PST'::timestamp with time zone)
               ->  Seq Scan on _hyper_1_7_chunk
                     Filter: (time_bucket('@ 1 day'::interval, id) <= 'Wed Jan 01 16:00:00 2025 PST'::timestamp with time zone)
               ->  Seq Scan on _hyper_1_6_chunk
                     Filter: (time_bucket('@ 1 day'::interval, id) <= 'Wed Jan 01 16:00:00 2025 PST'::timestamp with time zone)

SELECT time_bucket('1 day', id) AS day, avg(temp)
FROM uuid_events WHERE time_bucket('1 day', id) <= :'chunk_range_start'
GROUP BY id ORDER BY id DESC;
             day              | avg 
------------------------------+-----
 Wed Jan 01 16:00:00 2025 PST |   4
 Wed Jan 01 16:00:00 2025 PST |   3
 Tue Dec 31 16:00:00 2024 PST |   2
 Tue Dec 31 16:00:00 2024 PST |   1

-- Test time_bucket on non-v7 UUID
\set ON_ERROR_STOP 0
SELECT time_bucket('1 day', 'ffff0000-0000-4000-8000-000000000000'::uuid);
ERROR:  not a version 7 UUID: ffff0000-0000-4000-8000-000000000000
\set ON_ERROR_STOP 1
CREATE VIEW chunk_ranges AS
SELECT
  chunk_name,
  range_start,
  range_end
FROM timescaledb_information.chunks
WHERE hypertable_name = 'uuid_events';
SELECT * FROM chunk_ranges;
    chunk_name    |         range_start          |          range_end           
------------------+------------------------------+------------------------------
 _hyper_1_6_chunk | Tue Dec 31 16:00:00 2024 PST | Wed Jan 01 16:00:00 2025 PST
 _hyper_1_7_chunk | Wed Jan 01 16:00:00 2025 PST | Thu Jan 02 16:00:00 2025 PST
 _hyper_1_8_chunk | Thu Jan 02 16:00:00 2025 PST | Fri Jan 03 16:00:00 2025 PST

SELECT show_chunks('uuid_events', older_than => INTERVAL '1 day');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_6_chunk
 _timescaledb_internal._hyper_1_7_chunk
 _timescaledb_internal._hyper_1_8_chunk

SELECT show_chunks('uuid_events', older_than => '2025-01-02');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_6_chunk

SELECT show_chunks('uuid_events', newer_than => '2025-01-02');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_8_chunk

SELECT drop_chunks('uuid_events', older_than => '2025-01-02');
              drop_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_6_chunk

SELECT show_chunks('uuid_events');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_7_chunk
 _timescaledb_internal._hyper_1_8_chunk

-- Insert non-v7 UUIDs
\set ON_ERROR_STOP 0
INSERT INTO uuid_events SELECT 'a8961135-cd89-4c4b-aa05-79df642407dd', 5, 5.0;
ERROR:  a8961135-cd89-4c4b-aa05-79df642407dd is not a version 7 UUID
\set ON_ERROR_STOP 1
-- Insert as v7 UUID and later change to non-v7 to show effect on show_chunks()
-- and drop_chunks()
INSERT INTO uuid_events SELECT 'a8961135-cd89-7000-aa05-79df642407dd', 5, 5.0;
SELECT * FROM chunk_ranges;
    chunk_name    |         range_start          |          range_end           
------------------+------------------------------+------------------------------
 _hyper_1_7_chunk | Wed Jan 01 16:00:00 2025 PST | Thu Jan 02 16:00:00 2025 PST
 _hyper_1_8_chunk | Thu Jan 02 16:00:00 2025 PST | Fri Jan 03 16:00:00 2025 PST
 _hyper_1_9_chunk | Sun Nov 26 16:00:00 7843 PST | Mon Nov 27 16:00:00 7843 PST

UPDATE uuid_events
SET id = 'a8961135-cd89-4c4b-aa05-79df642407dd'
WHERE id = 'a8961135-cd89-7000-aa05-79df642407dd';
SELECT show_chunks('uuid_events', newer_than => '2025-01-02');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_8_chunk
 _timescaledb_internal._hyper_1_9_chunk

SELECT drop_chunks('uuid_events', newer_than => '2025-01-02');
              drop_chunks               
----------------------------------------
 _timescaledb_internal._hyper_1_8_chunk
 _timescaledb_internal._hyper_1_9_chunk

SELECT * FROM chunk_ranges;
    chunk_name    |         range_start          |          range_end           
------------------+------------------------------+------------------------------
 _hyper_1_7_chunk | Wed Jan 01 16:00:00 2025 PST | Thu Jan 02 16:00:00 2025 PST

INSERT INTO uuid_events SELECT to_uuidv7(now()), 6, 6.0;
SELECT show_chunks('uuid_events', newer_than => INTERVAL '2 months');
               show_chunks               
-----------------------------------------
 _timescaledb_internal._hyper_1_10_chunk

SELECT drop_chunks('uuid_events', newer_than => INTERVAL '2 months');
               drop_chunks               
-----------------------------------------
 _timescaledb_internal._hyper_1_10_chunk

SELECT show_chunks('uuid_events', newer_than => INTERVAL '2 months');
 show_chunks 
-------------

DROP TABLE uuid_events;
BEGIN;
-- Test UUID partition when using CREATE TABLE ... WITH
CREATE TABLE IF NOT EXISTS events (
     event_id UUID NOT NULL,
     entity_id VARCHAR(100) NOT NULL,
     ts TIMESTAMPTZ NOT NULL,
     event_type VARCHAR(100) NOT NULL,
     metadata JSONB,
     PRIMARY KEY (event_id)
)
WITH (
     tsdb.hypertable,
     tsdb.partition_column='event_id',
     tsdb.chunk_interval='2 hours'
);
-- Verify that the chunk time interval is two hours
SELECT ((interval_length/1000000)/60)/60 AS hours
FROM _timescaledb_catalog.dimension d JOIN _timescaledb_catalog.hypertable h ON (h.id = d.hypertable_id)
WHERE h.table_name='events';
 hours 
-------
     2

ROLLBACK;
-- Test a different interval
BEGIN;
CREATE TABLE IF NOT EXISTS events (
     event_id UUID NOT NULL,
     entity_id VARCHAR(100) NOT NULL,
     ts TIMESTAMPTZ NOT NULL,
     event_type VARCHAR(100) NOT NULL,
     metadata JSONB,
     PRIMARY KEY (event_id)
)
WITH (
     tsdb.hypertable,
     tsdb.partition_column='event_id',
     tsdb.chunk_interval='2 months'
);
-- Verify that the chunk time interval is two hours
SELECT (((interval_length/1000000)/60)/60)/24 AS days
FROM _timescaledb_catalog.dimension d JOIN _timescaledb_catalog.hypertable h ON (h.id = d.hypertable_id)
WHERE h.table_name='events';
 days 
------
   60

ROLLBACK;
-- Verify same behavior without CREATE TABLE WITH:
BEGIN;
CREATE TABLE IF NOT EXISTS events (
     event_id UUID NOT NULL,
     entity_id VARCHAR(100) NOT NULL,
     ts TIMESTAMPTZ NOT NULL,
     event_type VARCHAR(100) NOT NULL,
     metadata JSONB,
     PRIMARY KEY (event_id)
);
SELECT create_hypertable('events', 'event_id', chunk_time_interval => interval '2 hours');
WARNING:  column type "character varying" used for "entity_id" does not follow best practices
WARNING:  column type "character varying" used for "event_type" does not follow best practices
  create_hypertable  
---------------------
 (4,public,events,t)

-- Verify that the chunk time interval is two hours
SELECT ((interval_length/1000000)/60)/60 AS hours
FROM _timescaledb_catalog.dimension d JOIN _timescaledb_catalog.hypertable h ON (h.id = d.hypertable_id)
WHERE h.table_name='events';
 hours 
-------
     2

ROLLBACK;
BEGIN;
CREATE TABLE IF NOT EXISTS events (
     event_id UUID NOT NULL,
     entity_id VARCHAR(100) NOT NULL,
     ts TIMESTAMPTZ NOT NULL,
     event_type VARCHAR(100) NOT NULL,
     metadata JSONB,
     PRIMARY KEY (event_id)
);
SELECT create_hypertable('events', 'event_id', chunk_time_interval => interval '2 months');
WARNING:  column type "character varying" used for "entity_id" does not follow best practices
WARNING:  column type "character varying" used for "event_type" does not follow best practices
  create_hypertable  
---------------------
 (5,public,events,t)

-- Verify that the chunk time interval is two hours
SELECT (((interval_length/1000000)/60)/60)/24 AS days
FROM _timescaledb_catalog.dimension d JOIN _timescaledb_catalog.hypertable h ON (h.id = d.hypertable_id)
WHERE h.table_name='events';
 days 
------
   60

ROLLBACK;
