Merge gleb.loc:/home/uchum/5.0-opt
into gleb.loc:/home/uchum/5.1-opt sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_subselect.cc: Auto merged sql/sp_rcontext.cc: Auto merged sql/sql_class.cc: Auto merged mysql-test/r/subselect.result: Merge with 5.0-opt. mysql-test/t/subselect.test: Merge with 5.0-opt.
This commit is contained in:
commit
2892d3a2ab
@ -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);
|
|||||||
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.
|
||||||
|
|
||||||
#
|
#
|
||||||
|
16
sql/item.cc
16
sql/item.cc
@ -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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
|||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
14
sql/item.h
14
sql/item.h
@ -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
|
|||||||
{
|
{
|
||||||
char buffer[STRING_BUFFER_USUAL_SIZE];
|
char buffer[STRING_BUFFER_USUAL_SIZE];
|
||||||
String *value, value_buff;
|
String *value, value_buff;
|
||||||
|
bool is_varbinary;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_cache_str(): Item_cache(), value(0) { }
|
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:
|
|||||||
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()
|
|||||||
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)
|
|||||||
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()
|
|||||||
((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()
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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, ¤t_arena);
|
thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena);
|
||||||
|
|
||||||
holder= Item_cache::get_cache(result_type);
|
holder= Item_cache::get_cache(item);
|
||||||
|
|
||||||
thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena);
|
thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena);
|
||||||
|
|
||||||
@ -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:
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user