mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-ref-4.1
This commit is contained in:
@ -1490,9 +1490,6 @@ Warnings:
|
||||
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < (select max(test.t2.b) from test.t2)))
|
||||
select * from t3 where a >= some (select b from t2);
|
||||
a
|
||||
6
|
||||
7
|
||||
3
|
||||
explain extended select * from t3 where a >= some (select b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
@ -1512,9 +1509,6 @@ Warnings:
|
||||
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < <max>(select test.t2.b AS `b` from test.t2 group by test.t2.b)))
|
||||
select * from t3 where a >= some (select b from t2 group by 1);
|
||||
a
|
||||
6
|
||||
7
|
||||
3
|
||||
explain extended select * from t3 where a >= some (select b from t2 group by 1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
@ -2105,3 +2099,31 @@ s1 s1 < all (select s1 from t1)
|
||||
1 0
|
||||
NULL NULL
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
Code char(3) NOT NULL default '',
|
||||
Name char(52) NOT NULL default '',
|
||||
Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
|
||||
Region char(26) NOT NULL default '',
|
||||
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||
IndepYear smallint(6) default NULL,
|
||||
Population int(11) NOT NULL default '0',
|
||||
LifeExpectancy float(3,1) default NULL,
|
||||
GNP float(10,2) default NULL,
|
||||
GNPOld float(10,2) default NULL,
|
||||
LocalName char(45) NOT NULL default '',
|
||||
GovernmentForm char(45) NOT NULL default '',
|
||||
HeadOfState char(60) default NULL,
|
||||
Capital int(11) default NULL,
|
||||
Code2 char(2) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
Warnings:
|
||||
Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
|
||||
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
|
||||
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
|
||||
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes fran<61>aises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
|
||||
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
|
||||
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
c
|
||||
Oceania
|
||||
drop table t1;
|
||||
|
@ -1358,3 +1358,31 @@ insert into t1 values (1),(null);
|
||||
select * from t1 where s1 < all (select s1 from t1);
|
||||
select s1, s1 < all (select s1 from t1) from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# reference on changable fields from subquery
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
Code char(3) NOT NULL default '',
|
||||
Name char(52) NOT NULL default '',
|
||||
Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
|
||||
Region char(26) NOT NULL default '',
|
||||
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||
IndepYear smallint(6) default NULL,
|
||||
Population int(11) NOT NULL default '0',
|
||||
LifeExpectancy float(3,1) default NULL,
|
||||
GNP float(10,2) default NULL,
|
||||
GNPOld float(10,2) default NULL,
|
||||
LocalName char(45) NOT NULL default '',
|
||||
GovernmentForm char(45) NOT NULL default '',
|
||||
HeadOfState char(60) default NULL,
|
||||
Capital int(11) default NULL,
|
||||
Code2 char(2) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
|
||||
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
|
||||
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes fran<61>aises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
|
||||
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
|
||||
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
drop table t1;
|
||||
|
34
sql/item.cc
34
sql/item.cc
@ -69,7 +69,7 @@ Item::Item():
|
||||
}
|
||||
|
||||
/*
|
||||
Constructor used by Item_field, Item_ref & agregate (sum) functions.
|
||||
Constructor used by Item_field, Item_*_ref & agregate (sum) functions.
|
||||
Used for duplicating lists in processing queries with temporary
|
||||
tables
|
||||
*/
|
||||
@ -114,7 +114,7 @@ Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
||||
name = (char*) field_name_par;
|
||||
}
|
||||
|
||||
// Constructor used by Item_field & Item_ref (see Item comment)
|
||||
// Constructor used by Item_field & Item_*_ref (see Item comment)
|
||||
Item_ident::Item_ident(THD *thd, Item_ident *item)
|
||||
:Item(thd, item),
|
||||
orig_db_name(item->orig_db_name),
|
||||
@ -1372,6 +1372,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
|
||||
|
||||
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
enum_parsing_place place;
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
if (!field) // If field is not checked
|
||||
{
|
||||
@ -1419,8 +1420,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
}
|
||||
|
||||
Item_subselect *prev_subselect_item= prev_unit->item;
|
||||
enum_parsing_place place=
|
||||
prev_subselect_item->parsing_place;
|
||||
place= prev_subselect_item->parsing_place;
|
||||
/*
|
||||
check table fields only if subquery used somewhere out of HAVING
|
||||
or outer SELECT do not use groupping (i.e. tables are
|
||||
@ -1489,8 +1489,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
return -1;
|
||||
}
|
||||
|
||||
Item_ref *rf= new Item_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name, (char *)field_name);
|
||||
Item_ref *rf= (place == IN_HAVING ?
|
||||
new Item_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name) :
|
||||
new Item_direct_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name));
|
||||
if (!rf)
|
||||
return 1;
|
||||
thd->change_item_tree(ref, rf);
|
||||
@ -2039,6 +2044,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
uint counter;
|
||||
enum_parsing_place place;
|
||||
bool not_used;
|
||||
if (!ref)
|
||||
{
|
||||
@ -2097,8 +2103,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
// it is primary INSERT st_select_lex => skip first table resolving
|
||||
table_list= table_list->next;
|
||||
}
|
||||
enum_parsing_place place=
|
||||
prev_subselect_item->parsing_place;
|
||||
place= prev_subselect_item->parsing_place;
|
||||
/*
|
||||
check table fields only if subquery used somewhere out of HAVING
|
||||
or SELECT list or outer SELECT do not use groupping (i.e. tables
|
||||
@ -2168,6 +2173,19 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
}
|
||||
mark_as_dependent(thd, last, thd->lex->current_select,
|
||||
this);
|
||||
if (place == IN_HAVING)
|
||||
{
|
||||
Item_ref *rf;
|
||||
if (!(rf= new Item_direct_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name)))
|
||||
return 1;
|
||||
ref= 0; // Safety
|
||||
if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1))
|
||||
return 1;
|
||||
thd->change_item_tree(reference, rf);
|
||||
return 0;
|
||||
}
|
||||
ref= last->ref_pointer_array + counter;
|
||||
}
|
||||
else if (!ref)
|
||||
|
39
sql/item.h
39
sql/item.h
@ -889,6 +889,45 @@ public:
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
||||
class Item_direct_ref :public Item_ref
|
||||
{
|
||||
public:
|
||||
Item_direct_ref(Item **item, const char *table_name_par,
|
||||
const char *field_name_par)
|
||||
:Item_ref(item, table_name_par, field_name_par) {}
|
||||
/* Constructor need to process subselect with temporary tables (see Item) */
|
||||
Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
|
||||
double val()
|
||||
{
|
||||
double tmp=(*ref)->val();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
longlong tmp=(*ref)->val_int();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
String *val_str(String* tmp)
|
||||
{
|
||||
tmp=(*ref)->val_str(tmp);
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
bool is_null()
|
||||
{
|
||||
(void) (*ref)->val_int();
|
||||
return (*ref)->null_value;
|
||||
}
|
||||
bool get_date(TIME *ltime,uint fuzzydate)
|
||||
{
|
||||
return (null_value=(*ref)->get_date(ltime,fuzzydate));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_in_subselect;
|
||||
class Item_ref_null_helper: public Item_ref
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ longlong Item_func_not_all::val_int()
|
||||
|
||||
/*
|
||||
return TRUE if there was records in underlaying select in max/min
|
||||
optimisation
|
||||
optimisation (ALL subquery)
|
||||
*/
|
||||
if (empty_underlying_subquery())
|
||||
return 1;
|
||||
@ -157,11 +157,11 @@ longlong Item_func_nop_all::val_int()
|
||||
double value= args[0]->val();
|
||||
|
||||
/*
|
||||
return TRUE if there was records in underlaying select in max/min
|
||||
optimisation
|
||||
return FALSE if there was records in underlaying select in max/min
|
||||
optimisation (SAME/ANY subquery)
|
||||
*/
|
||||
if (empty_underlying_subquery())
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
null_value= args[0]->null_value;
|
||||
return (null_value || value == 0) ? 0 : 1;
|
||||
|
@ -797,9 +797,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
we can use same item for all selects.
|
||||
*/
|
||||
expr= new Item_ref((Item**)optimizer->get_cache(),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name);
|
||||
expr= new Item_direct_ref((Item**)optimizer->get_cache(),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name);
|
||||
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
}
|
||||
@ -993,9 +993,10 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
(char *) "<no matter>",
|
||||
(char *) "<list ref>");
|
||||
func=
|
||||
eq_creator.create(new Item_ref((*optimizer->get_cache())->addr(i),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
eq_creator.create(new Item_direct_ref((*optimizer->get_cache())->
|
||||
addr(i),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
func);
|
||||
item= and_items(item, func);
|
||||
}
|
||||
|
Reference in New Issue
Block a user