Fix chunk exclusion for space partitions in SELECT FOR UPDATE queries

Since we do not use our own hypertable expansion for SELECT FOR UPDATE
queries we need to make sure to add the extra information necessary to
get hashed space partitions with the native postgres inheritance
expansion working.
This commit is contained in:
Sven Klemm 2022-09-09 13:57:16 +02:00 committed by Sven Klemm
parent 6de979518d
commit f27e627341
6 changed files with 159 additions and 4 deletions

View File

@ -19,8 +19,10 @@ argument or resolve the type ambiguity by casting to the intended type.
**Bugfixes**
* #4619 Improve handling enum columns in compressed hypertables
* #4681 Fix compression_chunk_size primary key
* #4685 Improve chunk exclusion for space partitions
**Thanks**
* @maxtwardowski for reporting problems with chunk exclusion and space partitions
* @yuezhihan for reporting GROUP BY error when setting compress_segmentby with an enum column
## 2.8.0 (2022-08-30)

View File

@ -341,11 +341,12 @@ preprocess_query(Node *node, PreprocessQueryContext *context)
ts_constify_now(context->root, context->current_query->rtable, from->quals);
}
/*
* We only amend space constraints for UPDATE/DELETE as for SELECT
* we use our own hypertable expansion which can handle constraints on
* space dimensions without further help.
* We only amend space constraints for UPDATE/DELETE and SELECT FOR UPDATE
* as for normal SELECT we use our own hypertable expansion which can handle
* constraints on hashed space dimensions without further help.
*/
if (context->current_query->commandType != CMD_SELECT)
if (context->current_query->commandType != CMD_SELECT ||
context->current_query->rowMarks != NIL)
{
from->quals = ts_add_space_constraints(context->root,
context->current_query->rtable,

View File

@ -5,6 +5,55 @@ SET timescaledb.enable_chunk_append TO false;
SET timescaledb.enable_constraint_aware_append TO false;
SET timescaledb.current_timestamp_mock TO '1990-01-01';
\set PREFIX 'EXPLAIN (COSTS OFF, SUMMARY OFF, TIMING OFF)'
-- test SELECT FOR UPDATE
:PREFIX SELECT FROM metrics_space WHERE device_id = 1 FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1,3) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk
Filter: (device_id = ANY ('{1,3}'::integer[]))
(16 rows)
-- test valid variants we are optimizing
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
QUERY PLAN

View File

@ -5,6 +5,55 @@ SET timescaledb.enable_chunk_append TO false;
SET timescaledb.enable_constraint_aware_append TO false;
SET timescaledb.current_timestamp_mock TO '1990-01-01';
\set PREFIX 'EXPLAIN (COSTS OFF, SUMMARY OFF, TIMING OFF)'
-- test SELECT FOR UPDATE
:PREFIX SELECT FROM metrics_space WHERE device_id = 1 FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1,3) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_5
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_6
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_7
Filter: (device_id = ANY ('{1,3}'::integer[]))
(16 rows)
-- test valid variants we are optimizing
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
QUERY PLAN

View File

@ -5,6 +5,55 @@ SET timescaledb.enable_chunk_append TO false;
SET timescaledb.enable_constraint_aware_append TO false;
SET timescaledb.current_timestamp_mock TO '1990-01-01';
\set PREFIX 'EXPLAIN (COSTS OFF, SUMMARY OFF, TIMING OFF)'
-- test SELECT FOR UPDATE
:PREFIX SELECT FROM metrics_space WHERE device_id = 1 FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = 1)
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = 1)
(10 rows)
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1,3) FOR UPDATE;
QUERY PLAN
LockRows
-> Append
-> Seq Scan on metrics_space metrics_space_1
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_5
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_6
Filter: (device_id = ANY ('{1,3}'::integer[]))
-> Seq Scan on _hyper_X_X_chunk metrics_space_7
Filter: (device_id = ANY ('{1,3}'::integer[]))
(16 rows)
-- test valid variants we are optimizing
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
QUERY PLAN

View File

@ -9,6 +9,11 @@ SET timescaledb.current_timestamp_mock TO '1990-01-01';
\set PREFIX 'EXPLAIN (COSTS OFF, SUMMARY OFF, TIMING OFF)'
-- test SELECT FOR UPDATE
:PREFIX SELECT FROM metrics_space WHERE device_id = 1 FOR UPDATE;
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1) FOR UPDATE;
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1,3) FOR UPDATE;
-- test valid variants we are optimizing
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
:PREFIX DELETE FROM metrics_space WHERE device_id IN (1);