Commit 96b8697d authored by Nikita Malyavin's avatar Nikita Malyavin

try to make less row fetches by searching for rows on condition period_start <...

try to make less row fetches by searching for rows on condition period_start < (period_end of new_data)
parent 712648fd
...@@ -32,6 +32,11 @@ update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15'; ...@@ -32,6 +32,11 @@ update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15';
# diminish/enlarge # diminish/enlarge
update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01'; update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01';
update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10'; update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10';
select * from t;
id s e
1 2003-01-01 2003-02-01
1 2003-03-01 2003-05-01
1 2003-05-01 2003-07-01
# intersect left/right, strict inclusion/containment # intersect left/right, strict inclusion/containment
update t set e= '2003-04-01' where s = '2003-01-01'; update t set e= '2003-04-01' where s = '2003-01-01';
ERROR 23000: Duplicate entry '1-2003-01-01-2003-04-01' for key 'PRIMARY' ERROR 23000: Duplicate entry '1-2003-01-01-2003-04-01' for key 'PRIMARY'
......
...@@ -42,6 +42,8 @@ update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15'; ...@@ -42,6 +42,8 @@ update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15';
update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01'; update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01';
update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10'; update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10';
select * from t;
--echo # intersect left/right, strict inclusion/containment --echo # intersect left/right, strict inclusion/containment
--error ER_DUP_ENTRY --error ER_DUP_ENTRY
update t set e= '2003-04-01' where s = '2003-01-01'; update t set e= '2003-04-01' where s = '2003-01-01';
......
...@@ -6999,7 +6999,6 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data) ...@@ -6999,7 +6999,6 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data)
if (!key_info.without_overlaps) if (!key_info.without_overlaps)
continue; continue;
key_copy(check_overlaps_buffer, new_data, &key_info, 0);
if (is_update) if (is_update)
{ {
bool key_used= false; bool key_used= false;
...@@ -7026,25 +7025,33 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data) ...@@ -7026,25 +7025,33 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data)
error= handler->ha_start_keyread(key_nr); error= handler->ha_start_keyread(key_nr);
DBUG_ASSERT(!error); DBUG_ASSERT(!error);
const uint period_field_length= key_info.key_part[key_parts - 1].length;
const uint key_base_length= key_info.key_length - 2 * period_field_length;
key_copy(check_overlaps_buffer, new_data, &key_info, 0);
/* Copy period_end to period_start.
* the value in period_end field is not significant, but anyway let's leave
* it defined to avoid uninitialized memory access
*/
memcpy(check_overlaps_buffer + key_base_length,
check_overlaps_buffer + key_base_length + period_field_length,
period_field_length);
/* Find row with period_start < (period_end of new_data) */
error = handler->ha_index_read_map(record_buffer, error = handler->ha_index_read_map(record_buffer,
check_overlaps_buffer, check_overlaps_buffer,
key_part_map((1 << key_parts) - 1), key_part_map((1 << key_parts) - 1),
HA_READ_KEY_OR_PREV); HA_READ_BEFORE_KEY);
if (!error && !old_row_found()
&& table->check_period_overlaps(key_info, key_info,
new_data, record_buffer) == 0)
error= HA_ERR_FOUND_DUPP_KEY;
if (!error || error == HA_ERR_KEY_NOT_FOUND) if (!error && old_row_found())
error = handler->ha_index_next(record_buffer); error= handler->ha_index_prev(record_buffer);
if (!error && !old_row_found() if (!error && table->check_period_overlaps(key_info, key_info,
&& table->check_period_overlaps(key_info, key_info,
new_data, record_buffer) == 0) new_data, record_buffer) == 0)
error= HA_ERR_FOUND_DUPP_KEY; error= HA_ERR_FOUND_DUPP_KEY;
if (error == HA_ERR_END_OF_FILE) if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
error= 0; error= 0;
if (error == HA_ERR_FOUND_DUPP_KEY) if (error == HA_ERR_FOUND_DUPP_KEY)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment