Hello Igor, On Thu, Jul 15, 2010 at 04:54:37PM -0700, Igor Babaev wrote: > Please review this patch for the 5.2 tree. > > Regards, > Igor.
Ok to push. > -------- Original Message -------- > Subject: [Commits] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 > branch (igor:2823) Bug#603186 > Date: Thu, 15 Jul 2010 16:51:17 -0700 (PDT) > From: Igor Babaev <[email protected]> > Reply-To: [email protected] > To: [email protected] > > #At lp:maria/5.2 based on > revid:[email protected] > > 2823 Igor Babaev 2010-07-15 > Fixed bug #603186. > There were two problems that caused wrong results reported with > this bug. > 1. In some cases stored(persistent) virtual columns were not marked > in the write_set and in the vcol_set bitmaps. > 2. If the list of fields in an insert command was empty then the > values of > the stored virtual columns were set to default. > > To fix the first problem the function > st_table::mark_virtual_columns_for_write > was modified. Now the function has a parameter that says whether > the virtual > columns are to be marked for insert or for update. > To fix the second problem a special handling of empty insert lists is > added in the function fill_record(). > modified: > mysql-test/suite/vcol/r/vcol_misc.result > mysql-test/suite/vcol/t/vcol_misc.test > sql/sql_base.cc > sql/sql_insert.cc > sql/sql_lex.cc > sql/sql_lex.h > sql/sql_table.cc > sql/table.cc > sql/table.h > > === modified file 'mysql-test/suite/vcol/r/vcol_misc.result' > --- a/mysql-test/suite/vcol/r/vcol_misc.result 2010-07-13 17:45:23 > +0000 > +++ b/mysql-test/suite/vcol/r/vcol_misc.result 2010-07-15 23:51:05 > +0000 > @@ -45,3 +45,20 @@ C > 1 > 1 > DROP TABLE t1; > +CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT); > +INSERT INTO t1(a) VALUES (1); > +SELECT b, v FROM t1; > +b v > +0 10 > +DROP TABLE t1; > +CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT); > +INSERT INTO t1 () VALUES (); > +CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1)); > +INSERT INTO t2 () VALUES (); > +SELECT a, v FROM t1; > +a v > +100 101 > +SELECT a, v FROM t2; > +a v > +100 101 > +DROP TABLE t1,t2; > > === modified file 'mysql-test/suite/vcol/t/vcol_misc.test' > --- a/mysql-test/suite/vcol/t/vcol_misc.test 2010-07-13 17:45:23 +0000 > +++ b/mysql-test/suite/vcol/t/vcol_misc.test 2010-07-15 23:51:05 +0000 > @@ -43,5 +43,22 @@ SELECT 1 AS C FROM t1 ORDER BY v; > > DROP TABLE t1; > > +# > +# Bug#603186: Insert for a table with stored vurtual columns > +# > > +CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT); > +INSERT INTO t1(a) VALUES (1); > +SELECT b, v FROM t1; > > +DROP TABLE t1; > + > +CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT); > +INSERT INTO t1 () VALUES (); > +CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1)); > +INSERT INTO t2 () VALUES (); > + > +SELECT a, v FROM t1; > +SELECT a, v FROM t2; > + > +DROP TABLE t1,t2; > > === modified file 'sql/sql_base.cc' > --- a/sql/sql_base.cc 2010-06-01 19:52:20 +0000 > +++ b/sql/sql_base.cc 2010-07-15 23:51:05 +0000 > @@ -8204,6 +8204,8 @@ fill_record(THD * thd, List<Item> &field > table->auto_increment_field_not_null= FALSE; > f.rewind(); > } > + else if (thd->lex->unit.insert_table_with_stored_vcol) > + tbl_list.push_back(thd->lex->unit.insert_table_with_stored_vcol); > while ((fld= f++)) > { > if (!(field= fld->filed_for_view_update())) > > === modified file 'sql/sql_insert.cc' > --- a/sql/sql_insert.cc 2010-06-01 19:52:20 +0000 > +++ b/sql/sql_insert.cc 2010-07-15 23:51:05 +0000 > @@ -273,7 +273,7 @@ static int check_insert_fields(THD *thd, > } > /* Mark virtual columns used in the insert statement */ > if (table->vfield) > - table->mark_virtual_columns_for_write(); > + table->mark_virtual_columns_for_write(TRUE); > // For the values we need select_priv > #ifndef NO_EMBEDDED_ACCESS_CHECKS > table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); > @@ -1267,7 +1267,6 @@ bool mysql_prepare_insert(THD *thd, TABL > if (mysql_prepare_insert_check_table(thd, table_list, fields, > select_insert)) > DBUG_RETURN(TRUE); > > - > /* Prepare the fields in the statement. */ > if (values) > { > @@ -1320,6 +1319,18 @@ bool mysql_prepare_insert(THD *thd, TABL > if (!table) > table= table_list->table; > > + if (!fields.elements && table->vfield) > + { > + for (Field **vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) > + { > + if ((*vfield_ptr)->stored_in_db) > + { > + thd->lex->unit.insert_table_with_stored_vcol= table; > + break; > + } > + } > + } > + > if (!select_insert) > { > Item *fake_conds= 0; > > === modified file 'sql/sql_lex.cc' > --- a/sql/sql_lex.cc 2010-06-01 19:52:20 +0000 > +++ b/sql/sql_lex.cc 2010-07-15 23:51:05 +0000 > @@ -1590,6 +1590,7 @@ void st_select_lex_unit::init_query() > item_list.empty(); > describe= 0; > found_rows_for_union= 0; > + insert_table_with_stored_vcol= 0; > } > > void st_select_lex::init_query() > > === modified file 'sql/sql_lex.h' > --- a/sql/sql_lex.h 2010-06-01 19:52:20 +0000 > +++ b/sql/sql_lex.h 2010-07-15 23:51:05 +0000 > @@ -532,6 +532,13 @@ public: > bool describe; /* union exec() called for EXPLAIN */ > Procedure *last_procedure; /* Pointer to procedure, if such exists */ > > + /* > + Insert table with stored virtual columns. > + This is used only in those rare cases > + when the list of inserted values is empty. > + */ > + TABLE *insert_table_with_stored_vcol; > + > void init_query(); > st_select_lex_unit* master_unit(); > st_select_lex* outer_select(); > > === modified file 'sql/sql_table.cc' > --- a/sql/sql_table.cc 2010-06-05 14:53:36 +0000 > +++ b/sql/sql_table.cc 2010-07-15 23:51:05 +0000 > @@ -7876,7 +7876,7 @@ copy_data_between_tables(TABLE *from,TAB > > /* Tell handler that we have values for all columns in the to table */ > to->use_all_columns(); > - to->mark_virtual_columns_for_write(); > + to->mark_virtual_columns_for_write(TRUE); > init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE); > errpos= 4; > if (ignore) > > === modified file 'sql/table.cc' > --- a/sql/table.cc 2010-07-13 14:34:14 +0000 > +++ b/sql/table.cc 2010-07-15 23:51:05 +0000 > @@ -5024,7 +5024,7 @@ void st_table::mark_columns_needed_for_u > } > } > /* Mark all virtual columns needed for update */ > - mark_virtual_columns_for_write(); > + mark_virtual_columns_for_write(FALSE); > DBUG_VOID_RETURN; > } > > @@ -5052,7 +5052,7 @@ void st_table::mark_columns_needed_for_i > if (found_next_number_field) > mark_auto_increment_column(); > /* Mark virtual columns for insert */ > - mark_virtual_columns_for_write(); > + mark_virtual_columns_for_write(TRUE); > } > > > @@ -5090,10 +5090,14 @@ bool st_table::mark_virtual_col(Field *f > > /* > @brief Mark virtual columns for update/insert commands > + > + @param insert_fl <-> virtual columns are marked for insert command > > @details > The function marks virtual columns used in a update/insert commands > in the vcol_set bitmap. > + For an insert command a virtual column is always marked in write_set if > + it is a stored column. > If a virtual column is from write_set it is always marked in vcol_set. > If a stored virtual column is not from write_set but it is computed > through columns from write_set it is also marked in vcol_set, and, > @@ -5112,7 +5116,7 @@ bool st_table::mark_virtual_col(Field *f > be added to read_set either. > */ > > -void st_table::mark_virtual_columns_for_write(void) > +void st_table::mark_virtual_columns_for_write(bool insert_fl) > { > Field **vfield_ptr, *tmp_vfield; > bool bitmap_updated= FALSE; > @@ -5124,16 +5128,21 @@ void st_table::mark_virtual_columns_for_ > bitmap_updated= mark_virtual_col(tmp_vfield); > else if (tmp_vfield->stored_in_db) > { > - MY_BITMAP *save_read_set; > - Item *vcol_item= tmp_vfield->vcol_info->expr_item; > - DBUG_ASSERT(vcol_item); > - bitmap_clear_all(&tmp_set); > - save_read_set= read_set; > - read_set= &tmp_set; > - vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); > - read_set= save_read_set; > - bitmap_intersect(&tmp_set, write_set); > - if (!bitmap_is_clear_all(&tmp_set)) > + bool mark_fl= insert_fl; > + if (!mark_fl) > + { > + MY_BITMAP *save_read_set; > + Item *vcol_item= tmp_vfield->vcol_info->expr_item; > + DBUG_ASSERT(vcol_item); > + bitmap_clear_all(&tmp_set); > + save_read_set= read_set; > + read_set= &tmp_set; > + vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); > + read_set= save_read_set; > + bitmap_intersect(&tmp_set, write_set); > + mark_fl= !bitmap_is_clear_all(&tmp_set); > + } > + if (mark_fl) > { > bitmap_set_bit(write_set, tmp_vfield->field_index); > mark_virtual_col(tmp_vfield); > > === modified file 'sql/table.h' > --- a/sql/table.h 2010-06-03 09:28:54 +0000 > +++ b/sql/table.h 2010-07-15 23:51:05 +0000 > @@ -886,7 +886,7 @@ struct st_table { > void mark_columns_needed_for_delete(void); > void mark_columns_needed_for_insert(void); > bool mark_virtual_col(Field *field); > - void mark_virtual_columns_for_write(void); > + void mark_virtual_columns_for_write(bool insert_fl); > inline void column_bitmaps_set(MY_BITMAP *read_set_arg, > MY_BITMAP *write_set_arg) > { > > _______________________________________________ > commits mailing list > [email protected] > https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits -- BR Sergey -- Sergey Petrunia, Software Developer Monty Program AB, http://askmonty.org Blog: http://s.petrunia.net/blog _______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp

