mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
bugfix: mark_columns_needed_for_update
cannot use TABLE:merge_keys for that, because Field::part_of_key was designed to mark fields for KEY_READ, so a field is not a "part of key", if only prefix of the field is.
This commit is contained in:
@ -430,9 +430,9 @@ call p_verify_status_increment(2, 2, 2, 2);
|
||||
--echo # 4. Read-write statement: UPDATE, update 0 rows, 1 row matches WHERE
|
||||
--echo #
|
||||
update t1 set a=2;
|
||||
call p_verify_status_increment(2, 2, 1, 0);
|
||||
call p_verify_status_increment(2, 0, 1, 0);
|
||||
commit;
|
||||
call p_verify_status_increment(2, 2, 1, 0);
|
||||
call p_verify_status_increment(2, 0, 1, 0);
|
||||
|
||||
--echo # 5. Read-write statement: UPDATE, update 0 rows, 0 rows match WHERE
|
||||
--echo #
|
||||
|
@ -419,11 +419,11 @@ SUCCESS
|
||||
# 4. Read-write statement: UPDATE, update 0 rows, 1 row matches WHERE
|
||||
#
|
||||
update t1 set a=2;
|
||||
call p_verify_status_increment(2, 2, 1, 0);
|
||||
call p_verify_status_increment(2, 0, 1, 0);
|
||||
SUCCESS
|
||||
|
||||
commit;
|
||||
call p_verify_status_increment(2, 2, 1, 0);
|
||||
call p_verify_status_increment(2, 0, 1, 0);
|
||||
SUCCESS
|
||||
|
||||
# 5. Read-write statement: UPDATE, update 0 rows, 0 rows match WHERE
|
||||
|
@ -8,3 +8,30 @@ select * from t1;
|
||||
a b c
|
||||
2 3 4
|
||||
drop table t1;
|
||||
create table t1 (a int, c int as(a), p varchar(20) as(y), y char(20), index (p,c));
|
||||
insert into t1 (a,y) values(1, "yyy");
|
||||
update t1 set a = 100 where a = 1;
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
d varchar(5000) generated always as (b) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
i varchar(5000) generated always as (b) virtual,
|
||||
d varchar(5000) generated always as (i) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
|
@ -10,3 +10,39 @@ select * from t1;
|
||||
update t1 set a=2;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
#
|
||||
# one keypart is virtual, the other keypart is updated
|
||||
# this tests TABLE::mark_columns_needed_for_update()
|
||||
#
|
||||
create table t1 (a int, c int as(a), p varchar(20) as(y), y char(20), index (p,c));
|
||||
insert into t1 (a,y) values(1, "yyy");
|
||||
update t1 set a = 100 where a = 1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# note: prefix keys below
|
||||
#
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
d varchar(5000) generated always as (b) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
i varchar(5000) generated always as (b) virtual,
|
||||
d varchar(5000) generated always as (i) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
|
36
sql/table.cc
36
sql/table.cc
@ -6272,15 +6272,34 @@ void TABLE::mark_columns_needed_for_update()
|
||||
|
||||
if (triggers)
|
||||
triggers->mark_fields_used(TRG_EVENT_UPDATE);
|
||||
if (default_field)
|
||||
mark_default_fields_for_write(FALSE);
|
||||
if (vfield)
|
||||
need_signal|= mark_virtual_columns_for_write(FALSE);
|
||||
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
|
||||
{
|
||||
/* Mark all used key columns for read */
|
||||
Field **reg_field;
|
||||
for (reg_field= field ; *reg_field ; reg_field++)
|
||||
KEY *end= key_info + s->keys;
|
||||
for (KEY *k= key_info; k < end; k++)
|
||||
{
|
||||
/* Merge keys is all keys that had a column refered to in the query */
|
||||
if (merge_keys.is_overlapping((*reg_field)->part_of_key))
|
||||
bitmap_set_bit(read_set, (*reg_field)->field_index);
|
||||
KEY_PART_INFO *kpend= k->key_part + k->ext_key_parts;
|
||||
bool any_written= false, all_read= true;
|
||||
for (KEY_PART_INFO *kp= k->key_part; kp < kpend; kp++)
|
||||
{
|
||||
int idx= kp->fieldnr - 1;
|
||||
any_written|= bitmap_is_set(write_set, idx);
|
||||
all_read&= bitmap_is_set(read_set, idx);
|
||||
}
|
||||
if (any_written && !all_read)
|
||||
{
|
||||
for (KEY_PART_INFO *kp= k->key_part; kp < kpend; kp++)
|
||||
{
|
||||
int idx= kp->fieldnr - 1;
|
||||
if (bitmap_fast_test_and_set(read_set, idx))
|
||||
continue;
|
||||
if (field[idx]->vcol_info)
|
||||
mark_virtual_col(field[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
need_signal= true;
|
||||
}
|
||||
@ -6299,11 +6318,6 @@ void TABLE::mark_columns_needed_for_update()
|
||||
need_signal= true;
|
||||
}
|
||||
}
|
||||
if (default_field)
|
||||
mark_default_fields_for_write(FALSE);
|
||||
/* Mark all virtual columns needed for update */
|
||||
if (vfield)
|
||||
need_signal|= mark_virtual_columns_for_write(FALSE);
|
||||
if (check_constraints)
|
||||
{
|
||||
mark_check_constraint_columns_for_read();
|
||||
|
Reference in New Issue
Block a user