#At file:///home/igor/dev-bzr/mysql-6.0-opt-bug45092/
2740 Igor Babaev 2009-06-02
Fixed bug #45092.
When the descriptors of the data fields stored in a join buffer
are created first the descriptors of the the fields used in
building access keys are constructed. The construction is done
with a call of the function add_table_data_fields_to_join_cache.
One of the parameters of this function, namely field_set, specifies
for what fields the descriptors are to be constructed. This function
is called once again for the remaining fields.
As the function adds new elements to the array of the field
descriptors it has to save the number of the descriptors that
has been already built in order to be able continue adding them
later. The same is true for the array of pointers to the field
descriptors that is created for blob fields.
However the length of this array was not been saved. As a result,
when the remaining blob fields were processed the pointers to
their field descriptors overwrote the pointers to the descriptors
of the blob fields used to build the access keys.
modified:
mysql-test/r/join_cache.result
mysql-test/t/join_cache.test
sql/sql_join_cache.cc
sql/sql_select.h
per-file messages:
mysql-test/r/join_cache.result
Added a test case for bug #45092.
mysql-test/t/join_cache.test
Added a test case for bug #45092.
sql/sql_join_cache.cc
Fixed bug #45092.
Added a new in/out parameter for the function
add_table_data_fields_to_join_cache that returns
the number of pointers to blob field descriptors
built so far.
sql/sql_select.h
Fixed bug #45092.
Added a new member called data_field_ptr_count in the JOIN_CACHE class
to store the current number of already saved pointers to the data field
descriptors.
The pointer of this member is passed as a parameter to the
function add_table_data_fields_to_join_cache.
=== modified file 'mysql-test/r/join_cache.result'
--- a/mysql-test/r/join_cache.result 2009-04-16 02:25:27 +0000
+++ b/mysql-test/r/join_cache.result 2009-06-02 21:58:56 +0000
@@ -3966,3 +3966,21 @@ id1 num3 text1 id4 id3 dummy
set join_buffer_size=default;
set join_cache_level=default;
DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug #45019: join buffer contains two blob columns one of which is
+# used in the key employed to access the joined table
+#
+CREATE TABLE t1 (c1 int, c2 int, key (c2));
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (2,2);
+CREATE TABLE t2 (c1 text, c2 text);
+INSERT INTO t2 VALUES('tt', 'uu');
+INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
+ANALYZE TABLE t1,t2;
+set join_cache_level=6;
+SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
+WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
+c1 c2 c1 c2 LENGTH(t2.c1) LENGTH(t2.c2)
+2 2 tt uu 2 2
+set join_cache_level=default;
+DROP TABLE t1,t2;
=== modified file 'mysql-test/t/join_cache.test'
--- a/mysql-test/t/join_cache.test 2009-04-16 02:25:27 +0000
+++ b/mysql-test/t/join_cache.test 2009-06-02 21:58:56 +0000
@@ -1617,3 +1617,29 @@ set join_buffer_size=default;
set join_cache_level=default;
DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug #45019: join buffer contains two blob columns one of which is
+--echo # used in the key employed to access the joined table
+--echo #
+
+CREATE TABLE t1 (c1 int, c2 int, key (c2));
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (2,2);
+
+CREATE TABLE t2 (c1 text, c2 text);
+INSERT INTO t2 VALUES('tt', 'uu');
+INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
+
+--disable_result_log
+ANALYZE TABLE t1,t2;
+--enable_result_log
+
+set join_cache_level=6;
+
+SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
+ WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
+
+set join_cache_level=default;
+
+DROP TABLE t1,t2;
=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc 2009-04-16 02:25:27 +0000
+++ b/sql/sql_join_cache.cc 2009-06-02 21:58:56 +0000
@@ -79,9 +79,10 @@ uint add_flag_field_to_join_cache(uchar
add_table_data_fields_to_join_cache()
tab descriptors of fields from this table are to be filled
field_set descriptors for only these fields are to be created
- field_cnt IN/OUT counter of data fields
- descr IN/OUT pointer to the first descriptor to be filled
- descr_ptr IN/OUT pointer to the first pointer to blob descriptors
+ field_cnt IN/OUT counter of data fields
+ descr IN/OUT pointer to the first descriptor to be filled
+ field_ptr_cnt IN/OUT counter of pointers to the data fields
+ descr_ptr IN/OUT pointer to the first pointer to blob descriptors
DESCRIPTION
The function fills in the descriptors of cache data fields from the table
@@ -103,6 +104,7 @@ uint add_table_data_fields_to_join_cache
MY_BITMAP *field_set,
uint *field_cnt,
CACHE_FIELD **descr,
+ uint *field_ptr_cnt,
CACHE_FIELD ***descr_ptr)
{
Field **fld_ptr;
@@ -118,7 +120,8 @@ uint add_table_data_fields_to_join_cache
if (copy->type == CACHE_BLOB)
{
*copy_ptr= copy;
- copy_ptr++;
+ copy_ptr++;
+ (*field_ptr_cnt)++;
}
copy->field= *fld_ptr;
copy->referenced_field_no= 0;
@@ -160,6 +163,7 @@ void JOIN_CACHE::calc_record_fields()
blobs= 0;
flag_fields= 0;
data_field_count= 0;
+ data_field_ptr_count= 0;
referenced_fields= 0;
for ( ; tab < join_tab ; tab++)
@@ -316,7 +320,9 @@ void JOIN_CACHE::create_flag_fields()
to this field is added as an element of the array blob_ptr. For a blob
field only the size of the length of the blob data is taken into account.
It is assumed that 'data_field_count' contains the number of descriptors
- for data fields that have been already created.
+ for data fields that have been already created and 'data_field_ptr_count'
+ contains the number of the pointers to such descriptors having been
+ stored up to the moment.
RETURN
none
@@ -326,7 +332,7 @@ void JOIN_CACHE:: create_remaining_field
{
JOIN_TAB *tab;
CACHE_FIELD *copy= field_descr+flag_fields+data_field_count;
- CACHE_FIELD **copy_ptr= blob_ptr;
+ CACHE_FIELD **copy_ptr= blob_ptr+data_field_ptr_count;
for (tab= join_tab-tables; tab < join_tab; tab++)
{
@@ -343,8 +349,9 @@ void JOIN_CACHE:: create_remaining_field
}
length+= add_table_data_fields_to_join_cache(tab, rem_field_set,
- &data_field_count,
- ©, ©_ptr);
+ &data_field_count, ©,
+ &data_field_ptr_count,
+ ©_ptr);
/* SemiJoinDuplicateElimination: allocate space for rowid if needed */
if (tab->keep_current_rowid)
@@ -627,8 +634,9 @@ int JOIN_CACHE_BKA::init()
for (tab= join_tab-tables; tab < join_tab ; tab++)
{
length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
- &data_field_count,
- ©, ©_ptr);
+ &data_field_count, ©,
+ &data_field_ptr_count,
+ ©_ptr);
}
use_emb_key= check_emb_key_usage();
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2009-04-17 21:12:36 +0000
+++ b/sql/sql_select.h 2009-06-02 21:58:56 +0000
@@ -476,11 +476,17 @@ protected:
uint referenced_fields;
/*
- The current number of already created data field descriptors. This number
- is can be useful for implementations of the init functions.
+ The current number of already created data field descriptors.
+ This number can be useful for implementations of the init methods.
*/
uint data_field_count;
+ /*
+ The current number of already created pointers to the data field
+ descriptors. This number can be useful for implementations of
+ the init methods.
+ */
+ uint data_field_ptr_count;
/*
Array of the descriptors of fields containing 'fields' elements.
These are all fields that are stored for a record in the cache.
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (igor:2740) Bug#45092 | Igor Babaev | 2 Jun |