Skip to content

Commit ee728a7

Browse files
committed
Check columns when creating new chunk from table
Chunks must have the same columns with their hypertables. create_chunk() should not allow to have a chunk with additional columns which do not exist in the parent hypertable. Check columns by name in create_chunk() when creating a chunk from an existing table. This commit also forces chunks and hypertable to have the same expressions for generated columns, even though PostgreSQL inheritance may allow it. For PG15, it is allowed to have generated column in chunks if and only if the corresponding hypertable column is also generated. For later versions, this is handled by PostgreSQL code.
1 parent 4c3740c commit ee728a7

File tree

6 files changed

+318
-3
lines changed

6 files changed

+318
-3
lines changed

.unreleased/pr_8164

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixes: #8164 Check columns when creating new chunk from table

src/chunk.c

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,29 +1091,90 @@ chunk_create_from_hypercube_and_table_after_lock(const Hypertable *ht, Hypercube
10911091

10921092
Assert(OidIsValid(chunk_table_relid));
10931093
Assert(OidIsValid(current_chunk_schemaid));
1094+
Assert(OidIsValid(ht->main_table_relid));
1095+
1096+
Relation chunk_rel = table_open(chunk_table_relid, AccessShareLock);
1097+
Relation ht_rel = table_open(ht->main_table_relid, AccessShareLock);
1098+
TupleDesc tupdesc = RelationGetDescr(chunk_rel);
1099+
1100+
for (int attno = 0; attno < tupdesc->natts; attno++)
1101+
{
1102+
Form_pg_attribute att = TupleDescAttr(tupdesc, attno);
1103+
AttrNumber ht_attnum = InvalidAttrNumber;
1104+
1105+
/* Ignore dropped */
1106+
if (att->attisdropped)
1107+
continue;
1108+
1109+
ht_attnum = get_attnum(ht->main_table_relid, NameStr(att->attname));
1110+
/* Try to find the column in parent (matching on column name) */
1111+
if (ht_attnum == InvalidAttrNumber)
1112+
ereport(ERROR,
1113+
(errcode(ERRCODE_DATATYPE_MISMATCH),
1114+
errmsg("table \"%s\" contains column \"%s\" not found in parent \"%s\"",
1115+
RelationGetRelationName(chunk_rel),
1116+
NameStr(att->attname),
1117+
RelationGetRelationName(ht_rel)),
1118+
errdetail("The new chunk can contain only the columns present in parent.")));
1119+
1120+
/*
1121+
* PG16 and later does not allow generated columns on child tables if the parent
1122+
* column is not generated. This is a change from PG15 and earlier, where the
1123+
* child column could be generated even if the parent was not.
1124+
* We check if a generated column is also generated in the parent here to disallow
1125+
* this behavior in PG15 too.
1126+
*
1127+
* The case when the parent column is generated and the child column is not is handled
1128+
* by Postgres code, which will throw an error.
1129+
*
1130+
* This check can be removed once we drop support for PG15.
1131+
*/
1132+
if (att->attgenerated && !get_attgenerated(ht->main_table_relid, ht_attnum))
1133+
{
1134+
ereport(ERROR,
1135+
(errcode(ERRCODE_DATATYPE_MISMATCH),
1136+
errmsg("column \"%s\" in chunk table must not be a generated column",
1137+
NameStr(att->attname)),
1138+
errdetail("Chunk column must be generated if and only if parent column is "
1139+
"also generated")));
1140+
}
1141+
1142+
/* Check that the chunk column has the same expression as the hypertable column */
1143+
if (att->attgenerated && get_attgenerated(ht->main_table_relid, ht_attnum))
1144+
{
1145+
char *chunk_expr = ts_get_attr_expr(chunk_rel, attno + 1);
1146+
char *ht_expr = ts_get_attr_expr(ht_rel, ht_attnum);
1147+
1148+
if (strcmp(chunk_expr, ht_expr) != 0)
1149+
ereport(ERROR,
1150+
(errcode(ERRCODE_DATATYPE_MISMATCH),
1151+
errmsg("chunk column \"%s\" must have the same expression as the "
1152+
"hypertable column.",
1153+
NameStr(att->attname))));
1154+
}
1155+
}
1156+
table_close(ht_rel, NoLock);
10941157

10951158
/* Insert any new dimension slices into metadata */
10961159
ts_dimension_slice_insert_multi(cube->slices, cube->num_slices);
10971160
chunk = chunk_create_object(ht, cube, schema_name, table_name, prefix, get_next_chunk_id());
10981161
chunk->table_id = chunk_table_relid;
10991162
chunk->hypertable_relid = ht->main_table_relid;
1100-
Assert(OidIsValid(ht->main_table_relid));
11011163

11021164
new_chunk_schemaid = get_namespace_oid(NameStr(chunk->fd.schema_name), false);
11031165

11041166
if (current_chunk_schemaid != new_chunk_schemaid)
11051167
{
1106-
Relation chunk_rel = table_open(chunk_table_relid, AccessExclusiveLock);
11071168
ObjectAddresses *objects;
11081169

11091170
CheckSetNamespace(current_chunk_schemaid, new_chunk_schemaid);
11101171
objects = new_object_addresses();
11111172
AlterTableNamespaceInternal(chunk_rel, current_chunk_schemaid, new_chunk_schemaid, objects);
11121173
free_object_addresses(objects);
1113-
table_close(chunk_rel, NoLock);
11141174
/* Make changes visible */
11151175
CommandCounterIncrement();
11161176
}
1177+
table_close(chunk_rel, NoLock);
11171178

11181179
if (namestrcmp(&chunk->fd.table_name, get_rel_name(chunk_table_relid)) != 0)
11191180
{

src/utils.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,3 +1972,24 @@ ts_errdata_to_jsonb(ErrorData *edata, Name proc_schema, Name proc_name)
19721972
JsonbValue *result = pushJsonbValue(&parse_state, WJB_END_OBJECT, NULL);
19731973
return JsonbValueToJsonb(result);
19741974
}
1975+
1976+
char *
1977+
ts_get_attr_expr(Relation rel, AttrNumber attno)
1978+
{
1979+
TupleConstr *constr = rel->rd_att->constr;
1980+
char *expr = NULL;
1981+
1982+
for (int i = 0; i < constr->num_defval; i++)
1983+
{
1984+
if (constr->defval[i].adnum == attno)
1985+
{
1986+
expr = TextDatumGetCString(
1987+
DirectFunctionCall2(pg_get_expr,
1988+
CStringGetTextDatum(constr->defval[i].adbin),
1989+
ObjectIdGetDatum(RelationGetRelid(rel))));
1990+
break;
1991+
}
1992+
}
1993+
1994+
return expr;
1995+
}

src/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,4 @@ extern TSDLLEXPORT Oid ts_get_rel_am(Oid relid);
412412
extern TSDLLEXPORT void ts_relation_set_reloption(Relation rel, List *options, LOCKMODE lockmode);
413413
extern TSDLLEXPORT bool ts_is_hypercore_am(Oid amoid);
414414
extern TSDLLEXPORT Jsonb *ts_errdata_to_jsonb(ErrorData *edata, Name proc_schema, Name proc_name);
415+
extern TSDLLEXPORT char *ts_get_attr_expr(Relation rel, AttrNumber attno);

tsl/test/expected/chunk_api.out

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,141 @@ SELECT * FROM test.show_constraints(format('%I.%I', :'CHUNK_SCHEMA', :'CHUNK_NAM
172172
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
173173
(4 rows)
174174

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 count(*) FROM ' || chunk_schema || '.' || chunk_name
236+
FROM timescaledb_information.chunks
237+
WHERE hypertable_name = 'chunkapi'; \gexec
238+
?column?
239+
-------------------------------------------------------------
240+
SELECT count(*) FROM _timescaledb_internal._hyper_2_6_chunk
241+
SELECT count(*) FROM _timescaledb_internal._hyper_2_7_chunk
242+
SELECT count(*) FROM _timescaledb_internal._hyper_2_8_chunk
243+
(3 rows)
244+
245+
SELECT count(*) FROM _timescaledb_internal._hyper_2_6_chunk
246+
count
247+
-------
248+
1
249+
(1 row)
250+
251+
SELECT count(*) FROM _timescaledb_internal._hyper_2_7_chunk
252+
count
253+
-------
254+
1
255+
(1 row)
256+
257+
SELECT count(*) FROM _timescaledb_internal._hyper_2_8_chunk
258+
count
259+
-------
260+
3
261+
(1 row)
262+
263+
TRUNCATE chunkapi;
264+
-- Test generated columns
265+
-- This should fail since generated column is not allowed in chunks if parent does not have the column as generated.
266+
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));
267+
\set ON_ERROR_STOP 0
268+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516838400000000, 1517443200000000]}', NULL, NULL, 'generated_col_chunk');
269+
ERROR: column "temp" in chunk table must not be a generated column
270+
DETAIL: Chunk column must be generated if and only if parent column is also generated
271+
\set ON_ERROR_STOP 1
272+
-- When parent has a generated column while the chunk does not have the same column as generated, it should fail too.
273+
CREATE TABLE non_generated_chunk (time timestamptz NOT NULL, device int, temp float, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
274+
\set ON_ERROR_STOP 0
275+
ALTER TABLE chunkapi DROP COLUMN temp;
276+
ALTER TABLE chunkapi ADD COLUMN temp float GENERATED ALWAYS AS (device::float) STORED;
277+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1517443200000000, 1518048000000000]}', NULL, NULL, 'non_generated_chunk');
278+
ERROR: column "temp" in child table must be a generated column
279+
\set ON_ERROR_STOP 1
280+
-- Generation expression cannot be different from the parent
281+
\set ON_ERROR_STOP 0
282+
ALTER TABLE generated_col_chunk DROP COLUMN temp;
283+
ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)+1) STORED;
284+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518048000000000, 1518652800000000]}', NULL, NULL, 'generated_col_chunk');
285+
ERROR: chunk column "temp" must have the same expression as the hypertable column.
286+
\set ON_ERROR_STOP 1
287+
-- This should succeed since the generated column is now the same as in the parent
288+
ALTER TABLE generated_col_chunk DROP COLUMN temp;
289+
ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)) STORED;
290+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518652800000000, 1519257600000000]}', NULL, NULL, 'generated_col_chunk');
291+
chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
292+
----------+---------------+-----------------------+-------------------+---------+------------------------------------------------+---------
293+
12 | 2 | _timescaledb_internal | _hyper_2_12_chunk | r | {"time": [1518652800000000, 1519257600000000]} | t
294+
(1 row)
295+
296+
INSERT INTO chunkapi VALUES ('2018-02-20 05:00:00-8', 1);
297+
SELECT
298+
'SELECT count(*) FROM ' || chunk_schema || '.' || chunk_name
299+
FROM timescaledb_information.chunks
300+
WHERE hypertable_name = 'chunkapi'; \gexec
301+
?column?
302+
--------------------------------------------------------------
303+
SELECT count(*) FROM _timescaledb_internal._hyper_2_12_chunk
304+
(1 row)
305+
306+
SELECT count(*) FROM _timescaledb_internal._hyper_2_12_chunk
307+
count
308+
-------
309+
1
310+
(1 row)
311+
175312
DROP TABLE chunkapi;

tsl/test/sql/chunk_api.sql

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,98 @@ SELECT * FROM chunkapi ORDER BY 1,2,3;
115115
-- primary key constraints are not inherited or auto-created.
116116
SELECT * FROM test.show_constraints(format('%I.%I', :'CHUNK_SCHEMA', :'CHUNK_NAME')::regclass);
117117

118+
TRUNCATE chunkapi;
119+
120+
-- Create a table with extra columns
121+
CREATE TABLE extra_col_chunk (time timestamptz NOT NULL, device int, temp float, extra int, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
122+
123+
-- Adding a new chunk with extra column should fail
124+
\set ON_ERROR_STOP 0
125+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1514419200000000, 1515024000000000]}', NULL, NULL, 'extra_col_chunk');
126+
\set ON_ERROR_STOP 1
127+
128+
-- It should succeed after dropping the extra column
129+
ALTER TABLE extra_col_chunk DROP COLUMN extra;
130+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1514419200000000, 1515024000000000]}', NULL, NULL, 'extra_col_chunk');
131+
132+
-- Test creating a chunk with columns in different order
133+
CREATE TABLE reordered_chunk (device int, temp float, time timestamptz NOT NULL, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
134+
135+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1515024000000000, 1515628800000000]}', NULL, NULL, 'reordered_chunk');
136+
137+
-- Test creating a chunk with initially missing a column
138+
CREATE TABLE missing_col_chunk (time timestamptz NOT NULL, device int);
139+
INSERT INTO missing_col_chunk (time, device) VALUES ('2018-01-11 05:00:00-8', 1);
140+
ALTER TABLE missing_col_chunk ADD COLUMN temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0);
141+
INSERT INTO missing_col_chunk (time, device, temp) VALUES ('2018-01-12 05:00:00-8', 1, 19.5);
142+
143+
-- This should succeed since all required columns are now present
144+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1515628800000000, 1516233600000000]}', NULL, NULL, 'missing_col_chunk');
145+
146+
-- Test creating a chunk with mismatched column types
147+
CREATE TABLE wrong_type_chunk (time timestamptz NOT NULL, device text, temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
148+
149+
-- This should fail due to type mismatch
150+
\set ON_ERROR_STOP 0
151+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516233600000000, 1516838400000000]}', NULL, NULL, 'wrong_type_chunk');
152+
\set ON_ERROR_STOP 1
153+
154+
-- Test creating a chunk with binary coercible types
155+
ALTER TABLE chunkapi ADD COLUMN name varchar(10);
156+
CREATE TABLE coercible_type_chunk (time timestamptz NOT NULL, device int, temp float CONSTRAINT chunkapi_temp_check CHECK (temp > 0), name text);
157+
INSERT INTO coercible_type_chunk (time, device, temp, name) VALUES ('2018-01-20 06:00:00-8', 1, 25.1, 'device1');
158+
159+
\set ON_ERROR_STOP 0
160+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516233600000000, 1516838400000000]}', NULL, NULL, 'coercible_type_chunk');
161+
\set ON_ERROR_STOP 1
162+
163+
ALTER TABLE chunkapi DROP COLUMN name;
164+
165+
-- Test data routing to the successfully created chunks. Each row should go to a different chunks
166+
INSERT INTO chunkapi VALUES
167+
('2018-01-01 05:00:00-8', 1, 23.4),
168+
('2018-01-08 05:00:00-8', 1, 24.5),
169+
('2018-01-15 05:00:00-8', 1, 25.6);
170+
171+
-- Verify data was routed correctly
172+
SELECT
173+
'SELECT count(*) FROM ' || chunk_schema || '.' || chunk_name
174+
FROM timescaledb_information.chunks
175+
WHERE hypertable_name = 'chunkapi'; \gexec
176+
177+
TRUNCATE chunkapi;
178+
179+
-- Test generated columns
180+
-- This should fail since generated column is not allowed in chunks if parent does not have the column as generated.
181+
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));
182+
\set ON_ERROR_STOP 0
183+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1516838400000000, 1517443200000000]}', NULL, NULL, 'generated_col_chunk');
184+
\set ON_ERROR_STOP 1
185+
186+
-- When parent has a generated column while the chunk does not have the same column as generated, it should fail too.
187+
CREATE TABLE non_generated_chunk (time timestamptz NOT NULL, device int, temp float, CONSTRAINT chunkapi_temp_check CHECK (temp > 0));
188+
\set ON_ERROR_STOP 0
189+
ALTER TABLE chunkapi DROP COLUMN temp;
190+
ALTER TABLE chunkapi ADD COLUMN temp float GENERATED ALWAYS AS (device::float) STORED;
191+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1517443200000000, 1518048000000000]}', NULL, NULL, 'non_generated_chunk');
192+
\set ON_ERROR_STOP 1
193+
194+
-- Generation expression cannot be different from the parent
195+
\set ON_ERROR_STOP 0
196+
ALTER TABLE generated_col_chunk DROP COLUMN temp;
197+
ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)+1) STORED;
198+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518048000000000, 1518652800000000]}', NULL, NULL, 'generated_col_chunk');
199+
\set ON_ERROR_STOP 1
200+
201+
-- This should succeed since the generated column is now the same as in the parent
202+
ALTER TABLE generated_col_chunk DROP COLUMN temp;
203+
ALTER TABLE generated_col_chunk ADD COLUMN temp float GENERATED ALWAYS AS ((device::float)) STORED;
204+
SELECT * FROM _timescaledb_functions.create_chunk('chunkapi', '{"time": [1518652800000000, 1519257600000000]}', NULL, NULL, 'generated_col_chunk');
205+
206+
INSERT INTO chunkapi VALUES ('2018-02-20 05:00:00-8', 1);
207+
SELECT
208+
'SELECT count(*) FROM ' || chunk_schema || '.' || chunk_name
209+
FROM timescaledb_information.chunks
210+
WHERE hypertable_name = 'chunkapi'; \gexec
211+
118212
DROP TABLE chunkapi;

0 commit comments

Comments
 (0)