@@ -172,4 +172,143 @@ SELECT * FROM test.show_constraints(format('%I.%I', :'CHUNK_SCHEMA', :'CHUNK_NAM
172
172
constraint_6 | c | {time} | - | (("time" >= 'Wed Dec 27 16:00:00 2017 PST'::timestamp with time zone) AND ("time" < 'Wed Jan 03 16:00:00 2018 PST'::timestamp with time zone)) | f | f | t
173
173
(4 rows)
174
174
175
+ TRUNCATE chunkapi;
176
+ -- Create a table with extra columns
177
+ CREATE TABLE extra_col_chunk (time timestamptz NOT NULL, device int, temp float, extra int, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
178
+ -- Adding a new chunk with extra column should fail
179
+ \set ON_ERROR_STOP 0
180
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1514419200000000, 1515024000000000]}', NULL, NULL, 'extra_col_chunk');
181
+ ERROR: table "extra_col_chunk" contains column "extra" not found in parent "chunkapi"
182
+ DETAIL: The new chunk can contain only the columns present in parent.
183
+ \set ON_ERROR_STOP 1
184
+ -- It should succeed after dropping the extra column
185
+ ALTER TABLE extra_col_chunk DROP COLUMN extra;
186
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1514419200000000, 1515024000000000]}', NULL, NULL, 'extra_col_chunk');
187
+ chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
188
+ ----------+---------------+-----------------------+------------------+---------+------------------------------------------------+---------
189
+ 6 | 2 | _timescaledb_internal | _hyper_2_6_chunk | r | {"time": [1514419200000000, 1515024000000000]} | t
190
+ (1 row)
191
+
192
+ -- Test creating a chunk with columns in different order
193
+ CREATE TABLE reordered_chunk (device int, temp float, time timestamptz NOT NULL, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
194
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1515024000000000, 1515628800000000]}', NULL, NULL, 'reordered_chunk');
195
+ chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
196
+ ----------+---------------+-----------------------+------------------+---------+------------------------------------------------+---------
197
+ 7 | 2 | _timescaledb_internal | _hyper_2_7_chunk | r | {"time": [1515024000000000, 1515628800000000]} | t
198
+ (1 row)
199
+
200
+ -- Test creating a chunk with initially missing a column
201
+ CREATE TABLE missing_col_chunk (time timestamptz NOT NULL, device int);
202
+ INSERT INTO missing_col_chunk (time, device) VALUES ('2018-01-11 05:00:00-8', 1);
203
+ ALTER TABLE missing_col_chunk ADD COLUMN temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0);
204
+ INSERT INTO missing_col_chunk (time, device, temp) VALUES ('2018-01-12 05:00:00-8', 1, 19.5);
205
+ -- This should succeed since all required columns are now present
206
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1515628800000000, 1516233600000000]}', NULL, NULL, 'missing_col_chunk');
207
+ chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
208
+ ----------+---------------+-----------------------+------------------+---------+------------------------------------------------+---------
209
+ 8 | 2 | _timescaledb_internal | _hyper_2_8_chunk | r | {"time": [1515628800000000, 1516233600000000]} | t
210
+ (1 row)
211
+
212
+ -- Test creating a chunk with mismatched column types
213
+ CREATE TABLE wrong_type_chunk (time timestamptz NOT NULL, device text, temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
214
+ -- This should fail due to type mismatch
215
+ \set ON_ERROR_STOP 0
216
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516233600000000, 1516838400000000]}', NULL, NULL, 'wrong_type_chunk');
217
+ ERROR: child table "_hyper_2_9_chunk" has different type for column "device"
218
+ \set ON_ERROR_STOP 1
219
+ -- Test creating a chunk with binary coercible types
220
+ ALTER TABLE chunkapi ADD COLUMN name varchar(10);
221
+ CREATE TABLE coercible_type_chunk (time timestamptz NOT NULL, device int, temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0), name text);
222
+ INSERT INTO coercible_type_chunk (time, device, temp, name) VALUES ('2018-01-20 06:00:00-8', 1, 25.1, 'device1');
223
+ \set ON_ERROR_STOP 0
224
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516233600000000, 1516838400000000]}', NULL, NULL, 'coercible_type_chunk');
225
+ ERROR: child table "_hyper_2_10_chunk" has different type for column "name"
226
+ \set ON_ERROR_STOP 1
227
+ ALTER TABLE chunkapi DROP COLUMN name;
228
+ -- Test data routing to the successfully created chunks. Each row should go to a different chunks
229
+ INSERT INTO chunkapi VALUES
230
+ ('2018-01-01 05:00:00-8', 1, 23.4),
231
+ ('2018-01-08 05:00:00-8', 1, 24.5),
232
+ ('2018-01-15 05:00:00-8', 1, 25.6);
233
+ -- Verify data was routed correctly
234
+ SELECT
235
+ 'SELECT * FROM ' || chunk_schema || '.' || chunk_name
236
+ FROM timescaledb_information.chunks
237
+ WHERE hypertable_name = 'chunkapi'; \gexec
238
+ ?column?
239
+ ------------------------------------------------------
240
+ SELECT * FROM _timescaledb_internal._hyper_2_6_chunk
241
+ SELECT * FROM _timescaledb_internal._hyper_2_7_chunk
242
+ SELECT * FROM _timescaledb_internal._hyper_2_8_chunk
243
+ (3 rows)
244
+
245
+ SELECT * FROM _timescaledb_internal._hyper_2_6_chunk
246
+ time | device | temp
247
+ ------------------------------+--------+------
248
+ Mon Jan 01 05:00:00 2018 PST | 1 | 23.4
249
+ (1 row)
250
+
251
+ SELECT * FROM _timescaledb_internal._hyper_2_7_chunk
252
+ device | temp | time
253
+ --------+------+------------------------------
254
+ 1 | 24.5 | Mon Jan 08 05:00:00 2018 PST
255
+ (1 row)
256
+
257
+ SELECT * FROM _timescaledb_internal._hyper_2_8_chunk
258
+ time | device | temp
259
+ ------------------------------+--------+------
260
+ Thu Jan 11 05:00:00 2018 PST | 1 |
261
+ Fri Jan 12 05:00:00 2018 PST | 1 | 19.5
262
+ Mon Jan 15 05:00:00 2018 PST | 1 | 25.6
263
+ (3 rows)
264
+
265
+ TRUNCATE chunkapi;
266
+ -- Test generated columns
267
+ -- This should fail since generated column is not allowed in chunks if parent does not have the column as generated.
268
+ CREATE TABLE generated_col_chunk (time timestamptz NOT NULL, device int, temp float GENERATED ALWAYS AS (device::float) STORED, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
269
+ \set ON_ERROR_STOP 0
270
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516838400000000, 1517443200000000]}', NULL, NULL, 'generated_col_chunk');
271
+ ERROR: column "temp" in chunk table must not be a generated column
272
+ DETAIL: Chunk column must be generated if and only if parent column is also generated
273
+ \set ON_ERROR_STOP 1
274
+ -- When parent has a generated column while the chunk does not have the same column as generated, it should fail too.
275
+ CREATE TABLE non_generated_chunk (time timestamptz NOT NULL, device int, temp float, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
276
+ \set ON_ERROR_STOP 0
277
+ ALTER TABLE chunkapi DROP COLUMN temp;
278
+ ALTER TABLE chunkapi ADD COLUMN temp float GENERATED ALWAYS AS (device::float) STORED;
279
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1517443200000000, 1518048000000000]}', NULL, NULL, 'non_generated_chunk');
280
+ ERROR: column "temp" in child table must be a generated column
281
+ \set ON_ERROR_STOP 1
282
+ -- Generation expression cannot be different from the parent
283
+ \set ON_ERROR_STOP 0
284
+ ALTER TABLE generated_col_chunk DROP COLUMN temp;
285
+ ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)+1) STORED;
286
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518048000000000, 1518652800000000]}', NULL, NULL, 'generated_col_chunk');
287
+ ERROR: chunk column "temp" must have the same expression as the hypertable column.
288
+ \set ON_ERROR_STOP 1
289
+ -- This should succeed since the generated column is now the same as in the parent
290
+ ALTER TABLE generated_col_chunk DROP COLUMN temp;
291
+ ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)) STORED;
292
+ SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518652800000000, 1519257600000000]}', NULL, NULL, 'generated_col_chunk');
293
+ chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
294
+ ----------+---------------+-----------------------+-------------------+---------+------------------------------------------------+---------
295
+ 12 | 2 | _timescaledb_internal | _hyper_2_12_chunk | r | {"time": [1518652800000000, 1519257600000000]} | t
296
+ (1 row)
297
+
298
+ INSERT INTO chunkapi VALUES ('2018-02-20 05:00:00-8', 1);
299
+ SELECT
300
+ 'SELECT * FROM ' || chunk_schema || '.' || chunk_name
301
+ FROM timescaledb_information.chunks
302
+ WHERE hypertable_name = 'chunkapi'; \gexec
303
+ ?column?
304
+ -------------------------------------------------------
305
+ SELECT * FROM _timescaledb_internal._hyper_2_12_chunk
306
+ (1 row)
307
+
308
+ SELECT * FROM _timescaledb_internal._hyper_2_12_chunk
309
+ time | device | temp
310
+ ------------------------------+--------+------
311
+ Tue Feb 20 05:00:00 2018 PST | 1 | 1
312
+ (1 row)
313
+
175
314
DROP TABLE chunkapi;
0 commit comments