Skip to content

Commit

Permalink
Fix ON CONFLICT DO UPDATE on compressed hypertables.
Browse files Browse the repository at this point in the history
This patch fixes execution of INSERT with ON CONFLICT DO UPDATE by
removing error and allowing UPDATE do happen on the given compressed
hypertable.
  • Loading branch information
sb230132 committed Mar 16, 2023
1 parent 790b322 commit 23d6f9e
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ accidentally triggering the load of a previous DB version.**
* #5361 Add parallel support for partialize_agg()
* #5252 Improve unique constraint support on compressed hypertables
* #5312 Add timeout support to ping_data_node()
* #5454 Fix ON CONFLICT DO UPDATE on compressed hypertables

**Bugfixes**
* #5396 Fix SEGMENTBY columns predicates to be pushed down
Expand Down
8 changes: 8 additions & 0 deletions src/nodes/chunk_dispatch/chunk_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* LICENSE-APACHE for a copy of the license.
*/
#include <postgres.h>
#include <access/xact.h>
#include <nodes/nodes.h>
#include <nodes/extensible.h>
#include <nodes/makefuncs.h>
Expand Down Expand Up @@ -145,7 +146,14 @@ ts_chunk_dispatch_get_chunk_insert_state(ChunkDispatch *dispatch, Point *point,
* postgres can do proper constraint checking.
*/
if (ts_cm_functions->decompress_batches_for_insert)
{
ts_cm_functions->decompress_batches_for_insert(cis, chunk, slot);
OnConflictAction onconflict_action =
chunk_dispatch_get_on_conflict_action(dispatch);
/* mark rows visible */
if (onconflict_action == ONCONFLICT_UPDATE)
dispatch->estate->es_output_cid = GetCurrentCommandId(false);
}
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Expand Down
9 changes: 1 addition & 8 deletions src/nodes/chunk_dispatch/chunk_insert_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ chunk_dispatch_get_returning_clauses(const ChunkDispatch *dispatch)
#endif
}

static OnConflictAction
OnConflictAction
chunk_dispatch_get_on_conflict_action(const ChunkDispatch *dispatch)
{
if (!dispatch->dispatch_state)
Expand Down Expand Up @@ -583,7 +583,6 @@ ts_chunk_insert_state_create(const Chunk *chunk, ChunkDispatch *dispatch)
ALLOCSET_DEFAULT_SIZES);
OnConflictAction onconflict_action = chunk_dispatch_get_on_conflict_action(dispatch);
ResultRelInfo *relinfo;
bool has_compressed_chunk = (chunk->fd.compressed_chunk_id != 0);

/* permissions NOT checked here; were checked at hypertable level */
if (check_enable_rls(chunk->table_id, InvalidOid, false) == RLS_ENABLED)
Expand All @@ -597,12 +596,6 @@ ts_chunk_insert_state_create(const Chunk *chunk, ChunkDispatch *dispatch)
CHUNK_INSERT,
true);

if (has_compressed_chunk && onconflict_action == ONCONFLICT_UPDATE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg(
"INSERT with ON CONFLICT DO UPDATE is not supported on compressed chunks")));

rel = table_open(chunk->table_id, RowExclusiveLock);

MemoryContext old_mcxt = MemoryContextSwitchTo(cis_context);
Expand Down
1 change: 1 addition & 0 deletions src/nodes/chunk_dispatch/chunk_insert_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ typedef struct ChunkDispatch ChunkDispatch;
extern ChunkInsertState *ts_chunk_insert_state_create(const Chunk *chunk, ChunkDispatch *dispatch);
extern void ts_chunk_insert_state_destroy(ChunkInsertState *state);

OnConflictAction chunk_dispatch_get_on_conflict_action(const ChunkDispatch *dispatch);
#endif /* TIMESCALEDB_CHUNK_INSERT_STATE_H */
23 changes: 20 additions & 3 deletions tsl/test/expected/compression.out
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,26 @@ ERROR: cannot update/delete rows from chunk "_hyper_1_1_chunk" as it is compres
insert into foo values(10, 12, 12, 12)
on conflict( a, b)
do update set b = excluded.b;
ERROR: INSERT with ON CONFLICT DO UPDATE is not supported on compressed chunks
SELECT * from foo ORDER BY a,b;
a | b | c | d
----+-----+----+----
10 | 12 | 12 | 12
20 | 11 | 20 |
30 | 222 | 40 |
(3 rows)

--TEST2c Do DML directly on the chunk.
insert into _timescaledb_internal._hyper_1_2_chunk values(10, 12, 12, 12);
insert into _timescaledb_internal._hyper_1_2_chunk values(10, 12, 12, 12)
on conflict( a, b)
do update set b = excluded.b + 12;
SELECT * from foo ORDER BY a,b;
a | b | c | d
----+-----+----+----
10 | 24 | 12 | 12
20 | 11 | 20 |
30 | 222 | 40 |
(3 rows)

update _timescaledb_internal._hyper_1_2_chunk
set b = 12;
ERROR: cannot update/delete rows from chunk "_hyper_1_2_chunk" as it is compressed
Expand All @@ -229,7 +246,7 @@ ERROR: duplicate key value violates unique constraint "_hyper_1_2_chunk_foo_uni
select * from _timescaledb_internal._hyper_1_2_chunk order by a;
a | b | c | d
----+----+----+-----
10 | 12 | 12 | 12
10 | 24 | 12 | 12
10 | 10 | 20 |
11 | 10 | 20 | 120
(3 rows)
Expand Down
7 changes: 6 additions & 1 deletion tsl/test/sql/compression.sql
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,14 @@ set b = (select f1.newval from foo_join f1 left join lateral (select newval as n
insert into foo values(10, 12, 12, 12)
on conflict( a, b)
do update set b = excluded.b;
SELECT * from foo ORDER BY a,b;

--TEST2c Do DML directly on the chunk.
insert into _timescaledb_internal._hyper_1_2_chunk values(10, 12, 12, 12);
insert into _timescaledb_internal._hyper_1_2_chunk values(10, 12, 12, 12)
on conflict( a, b)
do update set b = excluded.b + 12;
SELECT * from foo ORDER BY a,b;

update _timescaledb_internal._hyper_1_2_chunk
set b = 12;
delete from _timescaledb_internal._hyper_1_2_chunk;
Expand Down

0 comments on commit 23d6f9e

Please sign in to comment.