mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 11:03:36 +08:00
Make slot for upserts be update for every chunk switch
Previously, the slots for upserts were only updated when a ChunkInsertState was created, but not when it was found in the ChunkDispatch cache. This was wrong -- we need to update the slots every time we switch to the chunk. Right now the switch function is called on every tuple. We will optimize that later to only be called when the previous chunk was different. But, that is not part of this bug-fix PR.
This commit is contained in:
parent
8a7c127f6c
commit
61e524e0c1
@ -69,5 +69,6 @@ ts_chunk_dispatch_get_chunk_insert_state(ChunkDispatch *dispatch, Point *point)
|
||||
}
|
||||
|
||||
Assert(cis != NULL);
|
||||
ts_chunk_insert_state_switch(cis);
|
||||
return cis;
|
||||
}
|
||||
|
@ -409,21 +409,6 @@ adjust_projections(ChunkInsertState *cis, ChunkDispatch *dispatch, Oid rowtype)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_slots(ChunkInsertState *cis)
|
||||
{
|
||||
/*
|
||||
* Note: we have to adjust the slot descriptor whether or not this chunk
|
||||
* has a tup_conv_map since we reuse the same slot across chunks. thus the
|
||||
* slot will be set to the last chunk's slot descriptor and NOT the
|
||||
* hypertable's slot descriptor.
|
||||
*/
|
||||
if (ResultRelInfo_OnConflictNotNull(cis->result_relation_info) && ResultRelInfo_OnConflictProjInfoCompat(cis->result_relation_info) != NULL)
|
||||
{
|
||||
ExecSetSlotDescriptor(get_projection_info_slot_compat(ResultRelInfo_OnConflictProjInfoCompat(cis->result_relation_info)), RelationGetDescr(cis->rel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if tuple conversion is needed between a chunk and its parent table.
|
||||
@ -537,7 +522,6 @@ ts_chunk_insert_state_create(Chunk *chunk, ChunkDispatch *dispatch)
|
||||
gettext_noop("could not convert row type"));
|
||||
adjust_projections(state, dispatch, RelationGetForm(rel)->reltype);
|
||||
}
|
||||
adjust_slots(state);
|
||||
|
||||
/* Need a tuple table slot to store converted tuples */
|
||||
if (state->tup_conv_map)
|
||||
@ -550,6 +534,25 @@ ts_chunk_insert_state_create(Chunk *chunk, ChunkDispatch *dispatch)
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
ts_chunk_insert_state_switch(ChunkInsertState *state)
|
||||
{
|
||||
/*
|
||||
* Adjust the slots descriptor.
|
||||
*
|
||||
* Note: we have to adjust the slot descriptor whether or not this chunk
|
||||
* has a tup_conv_map since we reuse the same slot across chunks. thus the
|
||||
* slot will be set to the last chunk's slot descriptor and NOT the
|
||||
* hypertable's slot descriptor.
|
||||
*/
|
||||
if (ResultRelInfo_OnConflictNotNull(state->result_relation_info) && ResultRelInfo_OnConflictProjInfoCompat(state->result_relation_info) != NULL)
|
||||
{
|
||||
TupleTableSlot *slot = get_projection_info_slot_compat(ResultRelInfo_OnConflictProjInfoCompat(state->result_relation_info));
|
||||
|
||||
ExecSetSlotDescriptor(slot, RelationGetDescr(state->rel));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
chunk_insert_state_free(void *arg)
|
||||
{
|
||||
|
@ -32,6 +32,9 @@ typedef struct ChunkDispatch ChunkDispatch;
|
||||
|
||||
extern HeapTuple ts_chunk_insert_state_convert_tuple(ChunkInsertState *state, HeapTuple tuple, TupleTableSlot **existing_slot);
|
||||
extern ChunkInsertState *ts_chunk_insert_state_create(Chunk *chunk, ChunkDispatch *dispatch);
|
||||
extern void ts_chunk_insert_state_switch(ChunkInsertState *state);
|
||||
|
||||
|
||||
extern void ts_chunk_insert_state_destroy(ChunkInsertState *state);
|
||||
|
||||
#endif /* TIMESCALEDB_CHUNK_INSERT_STATE_H */
|
||||
|
@ -250,6 +250,21 @@ DO UPDATE SET device_id_2 = 'device-id-2-new', color = 'orange10' RETURNING *;
|
||||
Fri Jan 20 09:00:01 2017 | 3.5 | orange10 | dev5 | device-id-2-new
|
||||
(1 row)
|
||||
|
||||
--test inserting to to a chunk already in the chunk dispatch cache again.
|
||||
INSERT INTO upsert_test_space as current (time, device_id, temp, color, device_id_2) VALUES ('2017-01-20T09:00:01', 'dev5', 43.5, 'orange8', 'device-id-2'),
|
||||
('2018-01-20T09:00:01', 'dev5', 43.5, 'orange8', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev3', 43.5, 'orange7', 'device-id-2'),
|
||||
('2018-01-21T09:00:01', 'dev5', 43.5, 'orange9', 'device-id-2')
|
||||
ON CONFLICT (time, device_id)
|
||||
DO UPDATE SET device_id_2 = coalesce(excluded.device_id_2,current.device_id_2), color = coalesce(excluded.color,current.color) RETURNING *;
|
||||
time | temp | color | device_id | device_id_2
|
||||
--------------------------+------+---------+----------------------+----------------------
|
||||
Fri Jan 20 09:00:01 2017 | 3.5 | orange8 | dev5 | device-id-2
|
||||
Sat Jan 20 09:00:01 2018 | 43.5 | orange8 | dev5 | device-id-2
|
||||
Fri Jan 20 09:00:01 2017 | 23.5 | orange7 | dev3 | device-id-2
|
||||
Sun Jan 21 09:00:01 2018 | 43.5 | orange9 | dev5 | device-id-2
|
||||
(4 rows)
|
||||
|
||||
WITH CTE AS (
|
||||
INSERT INTO upsert_test_multi_unique
|
||||
VALUES ('2017-01-20T09:00:01', 25.9, 'purple')
|
||||
@ -326,9 +341,9 @@ select * from upsert_test_diffchunk order by time, device_id;
|
||||
|
||||
--make sure current works
|
||||
INSERT INTO upsert_test_diffchunk as current (time, device_id, temp, color, device_id_2) VALUES
|
||||
('2019-01-20T09:00:01', 'dev1', 43.5, 'orange2', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev1', 43.5, 'yellow2', 'device-id-2')
|
||||
--('2019-01-20T09:00:01', 'dev2', 43.5, 'orange2', 'device-id-2')
|
||||
('2019-01-20T09:00:01', 'dev1', 43.5, 'orange2', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev1', 43.5, 'yellow2', 'device-id-2'),
|
||||
('2019-01-20T09:00:01', 'dev2', 43.5, 'orange2', 'device-id-2')
|
||||
ON CONFLICT (time, device_id)
|
||||
DO UPDATE SET
|
||||
device_id_2 = coalesce(excluded.device_id_2,current.device_id_2),
|
||||
@ -340,6 +355,6 @@ select * from upsert_test_diffchunk order by time, device_id;
|
||||
Fri Jan 20 09:00:01 2017 | dev1 | 43.5 | yellow2 | device-id-2
|
||||
Fri Jan 20 09:00:01 2017 | dev2 | 25.9 | yellow |
|
||||
Sun Jan 20 09:00:01 2019 | dev1 | 43.5 | orange2 | device-id-2
|
||||
Sun Jan 20 09:00:01 2019 | dev2 | 23.5 | orange |
|
||||
Sun Jan 20 09:00:01 2019 | dev2 | 43.5 | orange2 | device-id-2
|
||||
(4 rows)
|
||||
|
||||
|
@ -105,6 +105,13 @@ INSERT INTO upsert_test_space (time, device_id, temp, color, device_id_2) VALUES
|
||||
ON CONFLICT (time, device_id)
|
||||
DO UPDATE SET device_id_2 = 'device-id-2-new', color = 'orange10' RETURNING *;
|
||||
|
||||
--test inserting to to a chunk already in the chunk dispatch cache again.
|
||||
INSERT INTO upsert_test_space as current (time, device_id, temp, color, device_id_2) VALUES ('2017-01-20T09:00:01', 'dev5', 43.5, 'orange8', 'device-id-2'),
|
||||
('2018-01-20T09:00:01', 'dev5', 43.5, 'orange8', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev3', 43.5, 'orange7', 'device-id-2'),
|
||||
('2018-01-21T09:00:01', 'dev5', 43.5, 'orange9', 'device-id-2')
|
||||
ON CONFLICT (time, device_id)
|
||||
DO UPDATE SET device_id_2 = coalesce(excluded.device_id_2,current.device_id_2), color = coalesce(excluded.color,current.color) RETURNING *;
|
||||
|
||||
WITH CTE AS (
|
||||
INSERT INTO upsert_test_multi_unique
|
||||
@ -147,9 +154,9 @@ select * from upsert_test_diffchunk order by time, device_id;
|
||||
|
||||
--make sure current works
|
||||
INSERT INTO upsert_test_diffchunk as current (time, device_id, temp, color, device_id_2) VALUES
|
||||
('2019-01-20T09:00:01', 'dev1', 43.5, 'orange2', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev1', 43.5, 'yellow2', 'device-id-2')
|
||||
--('2019-01-20T09:00:01', 'dev2', 43.5, 'orange2', 'device-id-2')
|
||||
('2019-01-20T09:00:01', 'dev1', 43.5, 'orange2', 'device-id-2'),
|
||||
('2017-01-20T09:00:01', 'dev1', 43.5, 'yellow2', 'device-id-2'),
|
||||
('2019-01-20T09:00:01', 'dev2', 43.5, 'orange2', 'device-id-2')
|
||||
ON CONFLICT (time, device_id)
|
||||
DO UPDATE SET
|
||||
device_id_2 = coalesce(excluded.device_id_2,current.device_id_2),
|
||||
|
Loading…
x
Reference in New Issue
Block a user