mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed LP bug #707555.
The bug was in the code of the patch fixing bug 698882. With improper casting the method store_key_field::change_source_field was called for the elements of the array TABLE_REF::key_copy that were either of a different type or not allocated at all. This caused crashes in some queries.
This commit is contained in:
@ -4977,4 +4977,44 @@ a1 b1 a2 b2 a3 b3
|
|||||||
2 xx 2 yy 2 zzz
|
2 xx 2 yy 2 zzz
|
||||||
SET SESSION optimizer_switch=DEFAULT;
|
SET SESSION optimizer_switch=DEFAULT;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug #707555: crash with equality substitution in ref
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
|
||||||
|
CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
|
||||||
|
INSERT INTO t3 VALUES (1,494862336);
|
||||||
|
CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
|
||||||
|
INSERT INTO t4 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
|
||||||
|
INSERT IGNORE INTO t5 VALUES (100);
|
||||||
|
CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
|
||||||
|
INSERT INTO t6 VALUES (NULL,1), (3,10);
|
||||||
|
CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
|
||||||
|
INSERT INTO t7 VALUES (1,NULL), (2,7);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
|
||||||
|
1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
|
||||||
|
1 SIMPLE t2 ref f22 f22 5 const 1
|
||||||
|
1 SIMPLE t6 ref f61 f61 5 const 1 Using where
|
||||||
|
1 SIMPLE t4 ref f42 f42 5 const 1 Using index
|
||||||
|
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
f23
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5,t6,t7;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -4984,6 +4984,46 @@ a1 b1 a2 b2 a3 b3
|
|||||||
2 xx 2 yy 2 zzz
|
2 xx 2 yy 2 zzz
|
||||||
SET SESSION optimizer_switch=DEFAULT;
|
SET SESSION optimizer_switch=DEFAULT;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug #707555: crash with equality substitution in ref
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
|
||||||
|
CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
|
||||||
|
INSERT INTO t3 VALUES (1,494862336);
|
||||||
|
CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
|
||||||
|
INSERT INTO t4 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
|
||||||
|
INSERT IGNORE INTO t5 VALUES (100);
|
||||||
|
CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
|
||||||
|
INSERT INTO t6 VALUES (NULL,1), (3,10);
|
||||||
|
CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
|
||||||
|
INSERT INTO t7 VALUES (1,NULL), (2,7);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
|
||||||
|
1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
|
||||||
|
1 SIMPLE t2 ref f22 f22 5 const 1
|
||||||
|
1 SIMPLE t6 ref f61 f61 5 const 1 Using where; Using join buffer (flat, BKA join)
|
||||||
|
1 SIMPLE t4 ref f42 f42 5 const 1 Using index
|
||||||
|
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
f23
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5,t6,t7;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
|
@ -4977,4 +4977,44 @@ a1 b1 a2 b2 a3 b3
|
|||||||
2 xx 2 yy 2 zzz
|
2 xx 2 yy 2 zzz
|
||||||
SET SESSION optimizer_switch=DEFAULT;
|
SET SESSION optimizer_switch=DEFAULT;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug #707555: crash with equality substitution in ref
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
|
||||||
|
CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
|
||||||
|
INSERT INTO t3 VALUES (1,494862336);
|
||||||
|
CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
|
||||||
|
INSERT INTO t4 VALUES (1,NULL), (8,NULL);
|
||||||
|
CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
|
||||||
|
INSERT IGNORE INTO t5 VALUES (100);
|
||||||
|
CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
|
||||||
|
INSERT INTO t6 VALUES (NULL,1), (3,10);
|
||||||
|
CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
|
||||||
|
INSERT INTO t7 VALUES (1,NULL), (2,7);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
|
||||||
|
1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
|
||||||
|
1 SIMPLE t2 ref f22 f22 5 const 1
|
||||||
|
1 SIMPLE t6 ref f61 f61 5 const 1 Using where
|
||||||
|
1 SIMPLE t4 ref f42 f42 5 const 1 Using index
|
||||||
|
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
f23
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5,t6,t7;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -4167,4 +4167,47 @@ SET SESSION optimizer_switch=DEFAULT;
|
|||||||
|
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #707555: crash with equality substitution in ref
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,NULL), (8,NULL);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
|
||||||
|
INSERT INTO t3 VALUES (1,494862336);
|
||||||
|
|
||||||
|
CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
|
||||||
|
INSERT INTO t4 VALUES (1,NULL), (8,NULL);
|
||||||
|
|
||||||
|
CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
|
||||||
|
INSERT IGNORE INTO t5 VALUES (100);
|
||||||
|
|
||||||
|
CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
|
||||||
|
INSERT INTO t6 VALUES (NULL,1), (3,10);
|
||||||
|
|
||||||
|
CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
|
||||||
|
INSERT INTO t7 VALUES (1,NULL), (2,7);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
|
||||||
|
SELECT t2.f23 FROM
|
||||||
|
(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
|
||||||
|
LEFT JOIN
|
||||||
|
(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
|
||||||
|
ON t3.f31 = t6.f61
|
||||||
|
WHERE t7.f71>0;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5,t6,t7;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -1059,6 +1059,8 @@ JOIN::optimize()
|
|||||||
|
|
||||||
Item **ref_item_ptr= tab->ref.items+i;
|
Item **ref_item_ptr= tab->ref.items+i;
|
||||||
Item *ref_item= *ref_item_ptr;
|
Item *ref_item= *ref_item_ptr;
|
||||||
|
if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE))
|
||||||
|
continue;
|
||||||
COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal :
|
COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal :
|
||||||
cond_equal;
|
cond_equal;
|
||||||
ref_item= substitute_for_best_equal_field(ref_item, equals, map2table);
|
ref_item= substitute_for_best_equal_field(ref_item, equals, map2table);
|
||||||
@ -1067,10 +1069,11 @@ JOIN::optimize()
|
|||||||
{
|
{
|
||||||
*ref_item_ptr= ref_item;
|
*ref_item_ptr= ref_item;
|
||||||
Item *item= ref_item->real_item();
|
Item *item= ref_item->real_item();
|
||||||
if (item->type() == Item::FIELD_ITEM)
|
store_key *key_copy= tab->ref.key_copy[i];
|
||||||
{
|
if (key_copy->type() == store_key::FIELD_STORE_KEY)
|
||||||
store_key_field *key_copy= (store_key_field *) tab->ref.key_copy[i];
|
{
|
||||||
key_copy->change_source_field((Item_field *) item);
|
store_key_field *field_copy= ((store_key_field *)key_copy);
|
||||||
|
field_copy->change_source_field((Item_field *) item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -997,6 +997,7 @@ class store_key :public Sql_alloc
|
|||||||
public:
|
public:
|
||||||
bool null_key; /* TRUE <=> the value of the key has a null part */
|
bool null_key; /* TRUE <=> the value of the key has a null part */
|
||||||
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
|
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
|
||||||
|
enum Type { FIELD_STORE_KEY, ITEM_STORE_KEY, CONST_ITEM_STORE_KEY };
|
||||||
store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
|
store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
|
||||||
:null_key(0), null_ptr(null), err(0)
|
:null_key(0), null_ptr(null), err(0)
|
||||||
{
|
{
|
||||||
@ -1017,6 +1018,7 @@ public:
|
|||||||
ptr, null, 1);
|
ptr, null, 1);
|
||||||
}
|
}
|
||||||
virtual ~store_key() {} /** Not actually needed */
|
virtual ~store_key() {} /** Not actually needed */
|
||||||
|
virtual enum Type type() const=0;
|
||||||
virtual const char *name() const=0;
|
virtual const char *name() const=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1068,7 +1070,9 @@ class store_key_field: public store_key
|
|||||||
{
|
{
|
||||||
copy_field.set(to_field,from_field,0);
|
copy_field.set(to_field,from_field,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Type type() const { return FIELD_STORE_KEY; }
|
||||||
const char *name() const { return field_name; }
|
const char *name() const { return field_name; }
|
||||||
|
|
||||||
void change_source_field(Item_field *fld_item)
|
void change_source_field(Item_field *fld_item)
|
||||||
@ -1116,6 +1120,8 @@ public:
|
|||||||
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
|
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
|
||||||
&err : (uchar*) 0, length), item(item_arg), use_value(val)
|
&err : (uchar*) 0, length), item(item_arg), use_value(val)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
enum Type type() const { return ITEM_STORE_KEY; }
|
||||||
const char *name() const { return "func"; }
|
const char *name() const { return "func"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -1164,6 +1170,8 @@ public:
|
|||||||
&err : (uchar*) 0, length, item_arg, FALSE), inited(0)
|
&err : (uchar*) 0, length, item_arg, FALSE), inited(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Type type() const { return CONST_ITEM_STORE_KEY; }
|
||||||
const char *name() const { return "const"; }
|
const char *name() const { return "const"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Reference in New Issue
Block a user