Merge tnurnberg@bk-internal.mysql.com:/home/bk/mysql-5.1-opt

into  mysql.com:/misc/mysql/31700/51-31700
parents 4bd91d2b f4570801
...@@ -4150,6 +4150,55 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; ...@@ -4150,6 +4150,55 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
0 0
0 0
DROP TABLE t1, t2; DROP TABLE t1, t2;
CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
s1 s2
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
s1 s2
CREATE INDEX I1 ON t1 (s1);
CREATE INDEX I2 ON t1 (s2);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
s1 s2
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
s1 s2
TRUNCATE t1;
INSERT INTO t1 VALUES (0x41,0x41);
SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
s1 s2
DROP TABLE t1;
CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
CREATE TABLE t3 (a3 BINARY(2) default '0');
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1),(2),(3);
SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
LEFT(t2.a2, 1)
1
2
3
SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
1 0
2 0
3 0
4 0
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
INSERT INTO t2 VALUES (2), (3), (4), (5);
INSERT INTO t3 VALUES (10), (20), (30);
SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
LEFT(t1.a1,1)
1
2
3
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
a2
DROP TABLE t1, t2, t3;
End of 5.0 tests. End of 5.0 tests.
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22); INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
......
...@@ -3002,6 +3002,48 @@ INSERT INTO t2 VALUES (103, 203); ...@@ -3002,6 +3002,48 @@ INSERT INTO t2 VALUES (103, 203);
SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# Bug #28076: inconsistent binary/varbinary comparison
#
CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
CREATE INDEX I1 ON t1 (s1);
CREATE INDEX I2 ON t1 (s2);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
TRUNCATE t1;
INSERT INTO t1 VALUES (0x41,0x41);
SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
DROP TABLE t1;
CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
CREATE TABLE t3 (a3 BINARY(2) default '0');
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1),(2),(3);
SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
INSERT INTO t2 VALUES (2), (3), (4), (5);
INSERT INTO t3 VALUES (10), (20), (30);
SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
DROP TABLE t1, t2, t3;
--echo End of 5.0 tests. --echo End of 5.0 tests.
# #
......
...@@ -6358,9 +6358,9 @@ bool field_is_equal_to_item(Field *field,Item *item) ...@@ -6358,9 +6358,9 @@ bool field_is_equal_to_item(Field *field,Item *item)
return result == field->val_real(); return result == field->val_real();
} }
Item_cache* Item_cache::get_cache(Item_result type) Item_cache* Item_cache::get_cache(const Item *item)
{ {
switch (type) { switch (item->result_type()) {
case INT_RESULT: case INT_RESULT:
return new Item_cache_int(); return new Item_cache_int();
case REAL_RESULT: case REAL_RESULT:
...@@ -6368,7 +6368,7 @@ Item_cache* Item_cache::get_cache(Item_result type) ...@@ -6368,7 +6368,7 @@ Item_cache* Item_cache::get_cache(Item_result type)
case DECIMAL_RESULT: case DECIMAL_RESULT:
return new Item_cache_decimal(); return new Item_cache_decimal();
case STRING_RESULT: case STRING_RESULT:
return new Item_cache_str(); return new Item_cache_str(item);
case ROW_RESULT: case ROW_RESULT:
return new Item_cache_row(); return new Item_cache_row();
default: default:
...@@ -6546,6 +6546,14 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val) ...@@ -6546,6 +6546,14 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
} }
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
int res= Item_cache::save_in_field(field, no_conversions);
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
value->length() < field->field_length) ? 1 : res;
}
bool Item_cache_row::allocate(uint num) bool Item_cache_row::allocate(uint num)
{ {
item_count= num; item_count= num;
...@@ -6564,7 +6572,7 @@ bool Item_cache_row::setup(Item * item) ...@@ -6564,7 +6572,7 @@ bool Item_cache_row::setup(Item * item)
{ {
Item *el= item->element_index(i); Item *el= item->element_index(i);
Item_cache *tmp; Item_cache *tmp;
if (!(tmp= values[i]= Item_cache::get_cache(el->result_type()))) if (!(tmp= values[i]= Item_cache::get_cache(el)))
return 1; return 1;
tmp->setup(el); tmp->setup(el);
} }
......
...@@ -2637,7 +2637,7 @@ public: ...@@ -2637,7 +2637,7 @@ public:
}; };
virtual void store(Item *)= 0; virtual void store(Item *)= 0;
enum Type type() const { return CACHE_ITEM; } enum Type type() const { return CACHE_ITEM; }
static Item_cache* get_cache(Item_result type); static Item_cache* get_cache(const Item *item);
table_map used_tables() const { return used_table_map; } table_map used_tables() const { return used_table_map; }
virtual void keep_array() {} virtual void keep_array() {}
// to prevent drop fixed flag (no need parent cleanup call) // to prevent drop fixed flag (no need parent cleanup call)
...@@ -2699,9 +2699,16 @@ class Item_cache_str: public Item_cache ...@@ -2699,9 +2699,16 @@ class Item_cache_str: public Item_cache
{ {
char buffer[STRING_BUFFER_USUAL_SIZE]; char buffer[STRING_BUFFER_USUAL_SIZE];
String *value, value_buff; String *value, value_buff;
public: bool is_varbinary;
Item_cache_str(): Item_cache(), value(0) { }
public:
Item_cache_str(const Item *item) :
Item_cache(), value(0),
is_varbinary(item->type() == FIELD_ITEM &&
((const Item_field *) item)->field->type() ==
MYSQL_TYPE_VARCHAR &&
!((const Item_field *) item)->field->has_charset())
{}
void store(Item *item); void store(Item *item);
double val_real(); double val_real();
longlong val_int(); longlong val_int();
...@@ -2709,6 +2716,7 @@ public: ...@@ -2709,6 +2716,7 @@ public:
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return STRING_RESULT; } enum Item_result result_type() const { return STRING_RESULT; }
CHARSET_INFO *charset() const { return value->charset(); }; CHARSET_INFO *charset() const { return value->charset(); };
int save_in_field(Field *field, bool no_conversions);
}; };
class Item_cache_row: public Item_cache class Item_cache_row: public Item_cache
......
...@@ -1438,7 +1438,7 @@ longlong Item_func_truth::val_int() ...@@ -1438,7 +1438,7 @@ longlong Item_func_truth::val_int()
bool Item_in_optimizer::fix_left(THD *thd, Item **ref) bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{ {
if (!args[0]->fixed && args[0]->fix_fields(thd, args) || if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
!cache && !(cache= Item_cache::get_cache(args[0]->result_type()))) !cache && !(cache= Item_cache::get_cache(args[0])))
return 1; return 1;
cache->setup(args[0]); cache->setup(args[0]);
......
...@@ -1760,7 +1760,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) ...@@ -1760,7 +1760,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->decimals= sel_item->decimals; item->decimals= sel_item->decimals;
item->unsigned_flag= sel_item->unsigned_flag; item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null; maybe_null= sel_item->maybe_null;
if (!(row[i]= Item_cache::get_cache(res_type))) if (!(row[i]= Item_cache::get_cache(sel_item)))
return; return;
row[i]->setup(sel_item); row[i]->setup(sel_item);
} }
...@@ -2222,6 +2222,7 @@ int subselect_indexsubquery_engine::exec() ...@@ -2222,6 +2222,7 @@ int subselect_indexsubquery_engine::exec()
((Item_in_subselect *) item)->value= 0; ((Item_in_subselect *) item)->value= 0;
empty_result_set= TRUE; empty_result_set= TRUE;
null_keypart= 0; null_keypart= 0;
table->status= 0;
if (check_null) if (check_null)
{ {
...@@ -2234,6 +2235,16 @@ int subselect_indexsubquery_engine::exec() ...@@ -2234,6 +2235,16 @@ int subselect_indexsubquery_engine::exec()
if (copy_ref_key()) if (copy_ref_key())
DBUG_RETURN(1); DBUG_RETURN(1);
if (table->status)
{
/*
We know that there will be no rows even if we scan.
Can be set in copy_ref_key.
*/
((Item_in_subselect *) item)->value= 0;
DBUG_RETURN(0);
}
if (null_keypart) if (null_keypart)
DBUG_RETURN(scan_table()); DBUG_RETURN(scan_table());
......
...@@ -503,14 +503,14 @@ sp_cursor::fetch(THD *thd, List<struct sp_variable> *vars) ...@@ -503,14 +503,14 @@ sp_cursor::fetch(THD *thd, List<struct sp_variable> *vars)
*/ */
Item_cache * Item_cache *
sp_rcontext::create_case_expr_holder(THD *thd, Item_result result_type) sp_rcontext::create_case_expr_holder(THD *thd, const Item *item)
{ {
Item_cache *holder; Item_cache *holder;
Query_arena current_arena; Query_arena current_arena;
thd->set_n_backup_active_arena(thd->spcont->callers_arena, &current_arena); thd->set_n_backup_active_arena(thd->spcont->callers_arena, &current_arena);
holder= Item_cache::get_cache(result_type); holder= Item_cache::get_cache(item);
thd->restore_active_arena(thd->spcont->callers_arena, &current_arena); thd->restore_active_arena(thd->spcont->callers_arena, &current_arena);
...@@ -559,7 +559,7 @@ sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr ...@@ -559,7 +559,7 @@ sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr
case_expr_item->result_type()) case_expr_item->result_type())
{ {
m_case_expr_holders[case_expr_id]= m_case_expr_holders[case_expr_id]=
create_case_expr_holder(thd, case_expr_item->result_type()); create_case_expr_holder(thd, case_expr_item);
} }
m_case_expr_holders[case_expr_id]->store(case_expr_item); m_case_expr_holders[case_expr_id]->store(case_expr_item);
......
...@@ -261,7 +261,7 @@ private: ...@@ -261,7 +261,7 @@ private:
bool init_var_table(THD *thd); bool init_var_table(THD *thd);
bool init_var_items(); bool init_var_items();
Item_cache *create_case_expr_holder(THD *thd, Item_result result_type); Item_cache *create_case_expr_holder(THD *thd, const Item *item);
int set_variable(THD *thd, Field *field, Item **value); int set_variable(THD *thd, Field *field, Item **value);
}; // class sp_rcontext : public Sql_alloc }; // class sp_rcontext : public Sql_alloc
......
...@@ -1899,7 +1899,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items) ...@@ -1899,7 +1899,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
{ {
if (!cache) if (!cache)
{ {
cache= Item_cache::get_cache(val_item->result_type()); cache= Item_cache::get_cache(val_item);
switch (val_item->result_type()) switch (val_item->result_type())
{ {
case REAL_RESULT: case REAL_RESULT:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment