maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #03471
Re: [Fwd: [Commits] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2823) Bug#603186]
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 <igor@xxxxxxxxxxxx>
> Reply-To: maria-developers@xxxxxxxxxxxxxxxxxxx
> To: commits@xxxxxxxxxxx
>
> #At lp:maria/5.2 based on
> revid:igor@xxxxxxxxxxxx-20100713174523-mjvsvvp6ow8dc81x
>
> 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
> commits@xxxxxxxxxxx
> 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