Commit 94457097 authored by serg@serg.mylan's avatar serg@serg.mylan

Merge bk-internal:/home/bk/mysql-4.1/

into serg.mylan:/usr/home/serg/Abk/mysql-4.1
parents b820d2a3 6457b899
...@@ -435,11 +435,6 @@ void STDCALL mysql_server_end() ...@@ -435,11 +435,6 @@ void STDCALL mysql_server_end()
my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
copy_arguments_ptr=0; copy_arguments_ptr=0;
clean_up(0); clean_up(0);
#ifdef THREAD
/* Don't call my_thread_end() if the application is using MY_INIT() */
if (!org_my_init_done)
my_thread_end();
#endif
/* If library called my_init(), free memory allocated by it */ /* If library called my_init(), free memory allocated by it */
if (!org_my_init_done) if (!org_my_init_done)
my_end(0); my_end(0);
......
...@@ -1439,3 +1439,28 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1439,3 +1439,28 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
drop table t2, t3; drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') TYPE=MyISAM CHARSET=latin1;
INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
-1 Valid 1
-1 Valid 2 1
-1 Should Not Return 0
SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
dbid name
-1 Valid
-1 Valid 2
drop table t1,t2,t3,t4;
CREATE TABLE t1 (id int(11) default NULL) TYPE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES (1),(5);
CREATE TABLE t2 (id int(11) default NULL) TYPE=MyISAM CHARSET=latin1;
INSERT INTO t2 VALUES (2),(6);
select * from t1 where (1,2,6) in (select * from t2);
ERROR 21000: Operand should contain 3 column(s)
DROP TABLE t1,t2;
...@@ -965,3 +965,30 @@ insert into t2 values (2,2), (2,1), (3,3), (3,1); ...@@ -965,3 +965,30 @@ insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a); select * from t3 where a > all (select max(b) from t2 group by a);
explain select * from t3 where a > all (select max(b) from t2 group by a); explain select * from t3 where a > all (select max(b) from t2 group by a);
drop table t2, t3; drop table t2, t3;
#
# correct used_tables()
#
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) TYPE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') TYPE=MyISAM CHARSET=latin1;
INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
drop table t1,t2,t3,t4;
#
# cardinality check
#
CREATE TABLE t1 (id int(11) default NULL) TYPE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES (1),(5);
CREATE TABLE t2 (id int(11) default NULL) TYPE=MyISAM CHARSET=latin1;
INSERT INTO t2 VALUES (2),(6);
-- error 1240
select * from t1 where (1,2,6) in (select * from t2);
DROP TABLE t1,t2;
...@@ -20,27 +20,28 @@ ...@@ -20,27 +20,28 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "mysys_err.h" #include "mysys_err.h"
static void read_texts(const char *file_name,const char ***point, static bool read_texts(const char *file_name,const char ***point,
uint error_messages); uint error_messages);
static void init_myfunc_errs(void); static void init_myfunc_errs(void);
/* Read messages from errorfile */ /* Read messages from errorfile */
void init_errmessage(void) bool init_errmessage(void)
{ {
DBUG_ENTER("init_errmessage"); DBUG_ENTER("init_errmessage");
read_texts(ERRMSG_FILE,&my_errmsg[ERRMAPP],ER_ERROR_MESSAGES); if (read_texts(ERRMSG_FILE,&my_errmsg[ERRMAPP],ER_ERROR_MESSAGES))
DBUG_RETURN(TRUE);
errmesg=my_errmsg[ERRMAPP]; /* Init global variabel */ errmesg=my_errmsg[ERRMAPP]; /* Init global variabel */
init_myfunc_errs(); /* Init myfunc messages */ init_myfunc_errs(); /* Init myfunc messages */
DBUG_VOID_RETURN; DBUG_RETURN(FALSE);
} }
/* Read text from packed textfile in language-directory */ /* Read text from packed textfile in language-directory */
/* If we can't read messagefile then it's panic- we can't continue */ /* If we can't read messagefile then it's panic- we can't continue */
static void read_texts(const char *file_name,const char ***point, static bool read_texts(const char *file_name,const char ***point,
uint error_messages) uint error_messages)
{ {
register uint i; register uint i;
...@@ -116,7 +117,7 @@ Check that the above file is the right version for this program!", ...@@ -116,7 +117,7 @@ Check that the above file is the right version for this program!",
point[i]= *point +uint2korr(head+10+i+i); point[i]= *point +uint2korr(head+10+i+i);
} }
VOID(my_close(file,MYF(0))); VOID(my_close(file,MYF(0)));
DBUG_VOID_RETURN; DBUG_RETURN(FALSE);
err: err:
switch (funktpos) { switch (funktpos) {
......
...@@ -37,7 +37,9 @@ void unireg_init(ulong options) ...@@ -37,7 +37,9 @@ void unireg_init(ulong options)
#ifdef USE_MY_ATOF #ifdef USE_MY_ATOF
init_my_atof(); /* use our atof */ init_my_atof(); /* use our atof */
#endif #endif
#ifndef EMBEDDED_LIBRARY
my_abort_hook=unireg_abort; /* Abort with close of databases */ my_abort_hook=unireg_abort; /* Abort with close of databases */
#endif
VOID(strmov(reg_ext,".frm")); VOID(strmov(reg_ext,".frm"));
for (i=0 ; i < 6 ; i++) // YYMMDDHHMMSS for (i=0 ; i < 6 ; i++) // YYMMDDHHMMSS
......
...@@ -819,9 +819,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -819,9 +819,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
// Prevent using outer fields in subselects, that is not supported now // Prevent using outer fields in subselects, that is not supported now
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select; SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl= cursel->outer_select(); {
SELECT_LEX_UNIT *prev_unit= cursel->master_unit();
for (SELECT_LEX *sl= prev_unit->outer_select();
sl; sl;
sl= sl->outer_select()) sl= (prev_unit= sl->master_unit())->outer_select())
{ {
table_list= (last= sl)->get_table_list(); table_list= (last= sl)->get_table_list();
if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
...@@ -829,19 +831,38 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -829,19 +831,38 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
// it is primary INSERT st_select_lex => skip first table resolving // it is primary INSERT st_select_lex => skip first table resolving
table_list= table_list->next; table_list= table_list->next;
} }
Item_subselect *prev_subselect_item= prev_unit->item;
if ((tmp= find_field_in_tables(thd, this, if ((tmp= find_field_in_tables(thd, this,
table_list, &where, table_list, &where,
0)) != not_found_field) 0)) != not_found_field)
{
prev_subselect_item->used_tables_cache|= tmp->table->map;
prev_subselect_item->const_item_cache= 0;
break; break;
}
if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && if (sl->resolve_mode == SELECT_LEX::SELECT_MODE &&
(refer= find_item_in_list(this, sl->item_list, &counter, (refer= find_item_in_list(this, sl->item_list, &counter,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **) not_found_item) (Item **) not_found_item)
{
if (*refer && (*refer)->fixed) // Avoid crash in case of error
{
prev_subselect_item->used_tables_cache|= (*refer)->used_tables();
prev_subselect_item->const_item_cache&= (*refer)->const_item();
}
break; break;
}
// Reference is not found => depend from outer (or just error)
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
prev_subselect_item->const_item_cache= 0;
if (sl->master_unit()->first_select()->linkage == if (sl->master_unit()->first_select()->linkage ==
DERIVED_TABLE_TYPE) DERIVED_TABLE_TYPE)
break; // do not look over derived table break; // do not look over derived table
} }
}
if (!tmp) if (!tmp)
return -1; return -1;
else if (!refer) else if (!refer)
...@@ -1360,7 +1381,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -1360,7 +1381,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
if (!ref) if (!ref)
{ {
TABLE_LIST *where= 0, *table_list; TABLE_LIST *where= 0, *table_list;
SELECT_LEX *sl= thd->lex.current_select->outer_select(); SELECT_LEX_UNIT *prev_unit= thd->lex.current_select->master_unit();
SELECT_LEX *sl= prev_unit->outer_select();
/* /*
Finding only in current select will be performed for selects that have Finding only in current select will be performed for selects that have
not outer one and for derived tables (which not support using outer not outer one and for derived tables (which not support using outer
...@@ -1388,15 +1410,23 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -1388,15 +1410,23 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
cause error ER_NON_UNIQ_ERROR in find_item_in_list. cause error ER_NON_UNIQ_ERROR in find_item_in_list.
*/ */
SELECT_LEX *last=0; SELECT_LEX *last=0;
for ( ; sl ; sl= sl->outer_select()) for ( ; sl ; sl= (prev_unit= sl->master_unit())->outer_select())
{ {
last= sl; last= sl;
Item_subselect *prev_subselect_item= prev_unit->item;
if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && if (sl->resolve_mode == SELECT_LEX::SELECT_MODE &&
(ref= find_item_in_list(this, sl->item_list, (ref= find_item_in_list(this, sl->item_list,
&counter, &counter,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **)not_found_item) (Item **)not_found_item)
{
if (*ref && (*ref)->fixed) // Avoid crash in case of error
{
prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
prev_subselect_item->const_item_cache&= (*ref)->const_item();
}
break; break;
}
table_list= sl->get_table_list(); table_list= sl->get_table_list();
if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
{ {
...@@ -1406,7 +1436,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -1406,7 +1436,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
if ((tmp= find_field_in_tables(thd, this, if ((tmp= find_field_in_tables(thd, this,
table_list, &where, table_list, &where,
0)) != not_found_field) 0)) != not_found_field)
{
prev_subselect_item->used_tables_cache|= tmp->table->map;
prev_subselect_item->const_item_cache= 0;
break; break;
}
// Reference is not found => depend from outer (or just error)
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
prev_subselect_item->const_item_cache= 0;
if (sl->master_unit()->first_select()->linkage == if (sl->master_unit()->first_select()->linkage ==
DERIVED_TABLE_TYPE) DERIVED_TABLE_TYPE)
break; // do not look over derived table break; // do not look over derived table
......
...@@ -36,7 +36,8 @@ inline Item * and_items(Item* cond, Item *item) ...@@ -36,7 +36,8 @@ inline Item * and_items(Item* cond, Item *item)
Item_subselect::Item_subselect(): Item_subselect::Item_subselect():
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0), Item_result_field(), engine_owner(1), value_assigned(0), substitution(0),
engine(0), have_to_be_excluded(0), engine_changed(0) engine(0), used_tables_cache(0), have_to_be_excluded(0),
const_item_cache(1), engine_changed(0)
{ {
reset(); reset();
/* /*
...@@ -111,6 +112,11 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) ...@@ -111,6 +112,11 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
} }
fix_length_and_dec(); fix_length_and_dec();
} }
if (engine->uncacheable())
{
const_item_cache= 0;
used_tables_cache|= RAND_TABLE_BIT;
}
fixed= 1; fixed= 1;
thd->where= save_where; thd->where= save_where;
return res; return res;
...@@ -146,10 +152,24 @@ void Item_subselect::fix_length_and_dec() ...@@ -146,10 +152,24 @@ void Item_subselect::fix_length_and_dec()
engine->fix_length_and_dec(0); engine->fix_length_and_dec(0);
} }
inline table_map Item_subselect::used_tables() const table_map Item_subselect::used_tables() const
{
return (table_map) (engine->dependent() ? used_tables_cache : 0L);
}
bool Item_subselect::const_item() const
{ {
return (table_map) (engine->dependent() ? 1L : return const_item_cache;
(engine->uncacheable() ? RAND_TABLE_BIT : 0L)); }
void Item_subselect::update_used_tables()
{
if (!engine->uncacheable())
{
// did all used tables become ststic?
if ((used_tables_cache & ~engine->upper_select_const_tables()))
const_item_cache= 1;
}
} }
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
...@@ -494,6 +514,12 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -494,6 +514,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
THD *thd= join->thd; THD *thd= join->thd;
thd->where= "scalar IN/ALL/ANY subquery"; thd->where= "scalar IN/ALL/ANY subquery";
if (select_lex->item_list.elements > 1)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
DBUG_RETURN(RES_ERROR);
}
if ((abort_on_null || (upper_not && upper_not->top_level())) && if ((abort_on_null || (upper_not && upper_not->top_level())) &&
!select_lex->master_unit()->dependent && !select_lex->master_unit()->dependent &&
(func == &Item_bool_func2::gt_creator || (func == &Item_bool_func2::gt_creator ||
...@@ -586,11 +612,6 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -586,11 +612,6 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex->dependent= 1; select_lex->dependent= 1;
Item *item; Item *item;
if (select_lex->item_list.elements > 1)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
DBUG_RETURN(RES_ERROR);
}
item= (Item*) select_lex->item_list.head(); item= (Item*) select_lex->item_list.head();
...@@ -690,6 +711,12 @@ Item_in_subselect::row_value_transformer(JOIN *join, ...@@ -690,6 +711,12 @@ Item_in_subselect::row_value_transformer(JOIN *join,
SELECT_LEX *select_lex= join->select_lex; SELECT_LEX *select_lex= join->select_lex;
if (select_lex->item_list.elements != left_expr->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
DBUG_RETURN(RES_ERROR);
}
if (!substitution) if (!substitution)
{ {
//first call for this unit //first call for this unit
...@@ -1138,3 +1165,29 @@ void subselect_uniquesubquery_engine::exclude() ...@@ -1138,3 +1165,29 @@ void subselect_uniquesubquery_engine::exclude()
//this never should be called //this never should be called
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
{
table_map map= 0;
for(; table; table= table->next)
{
TABLE *tbl= table->table;
if (tbl && tbl->const_table)
map|= tbl->map;
}
return map;
}
table_map subselect_single_select_engine::upper_select_const_tables()
{
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
table_list.first);
}
table_map subselect_union_engine::upper_select_const_tables()
{
return calc_const_tables((TABLE_LIST *) unit->outer_select()->
table_list.first);
}
...@@ -41,11 +41,15 @@ class Item_subselect :public Item_result_field ...@@ -41,11 +41,15 @@ class Item_subselect :public Item_result_field
/* substitution instead of subselect in case of optimization */ /* substitution instead of subselect in case of optimization */
Item *substitution; Item *substitution;
/* engine that perform execution of subselect (single select or union) */ /* engine that perform execution of subselect (single select or union) */
subselect_engine *engine; subselect_engine *engine;
/* cache of used external tables */
table_map used_tables_cache;
/* allowed number of columns (1 for single value subqueries) */ /* allowed number of columns (1 for single value subqueries) */
uint max_columns; uint max_columns;
/* work with 'substitution' */ /* work with 'substitution' */
bool have_to_be_excluded; bool have_to_be_excluded;
/* cache of constante state */
bool const_item_cache;
public: public:
/* changed engine indicator */ /* changed engine indicator */
...@@ -85,6 +89,8 @@ class Item_subselect :public Item_result_field ...@@ -85,6 +89,8 @@ class Item_subselect :public Item_result_field
bool exec(); bool exec();
virtual void fix_length_and_dec(); virtual void fix_length_and_dec();
table_map used_tables() const; table_map used_tables() const;
bool const_item() const;
void update_used_tables();
void print(String *str) void print(String *str)
{ {
if (name) if (name)
...@@ -101,6 +107,8 @@ class Item_subselect :public Item_result_field ...@@ -101,6 +107,8 @@ class Item_subselect :public Item_result_field
friend class select_subselect; friend class select_subselect;
friend class Item_in_optimizer; friend class Item_in_optimizer;
friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **);
friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **);
}; };
/* single value subselect */ /* single value subselect */
...@@ -264,6 +272,8 @@ class subselect_engine: public Sql_alloc ...@@ -264,6 +272,8 @@ class subselect_engine: public Sql_alloc
enum Item_result type() { return res_type; } enum Item_result type() { return res_type; }
virtual void exclude()= 0; virtual void exclude()= 0;
bool may_be_null() { return maybe_null; }; bool may_be_null() { return maybe_null; };
virtual table_map upper_select_const_tables()= 0;
static table_map calc_const_tables(TABLE_LIST *);
}; };
...@@ -285,6 +295,7 @@ class subselect_single_select_engine: public subselect_engine ...@@ -285,6 +295,7 @@ class subselect_single_select_engine: public subselect_engine
bool dependent(); bool dependent();
bool uncacheable(); bool uncacheable();
void exclude(); void exclude();
table_map upper_select_const_tables();
}; };
...@@ -302,6 +313,7 @@ class subselect_union_engine: public subselect_engine ...@@ -302,6 +313,7 @@ class subselect_union_engine: public subselect_engine
bool dependent(); bool dependent();
bool uncacheable(); bool uncacheable();
void exclude(); void exclude();
table_map upper_select_const_tables();
}; };
...@@ -328,6 +340,7 @@ class subselect_uniquesubquery_engine: public subselect_engine ...@@ -328,6 +340,7 @@ class subselect_uniquesubquery_engine: public subselect_engine
bool dependent() { return 1; } bool dependent() { return 1; }
bool uncacheable() { return 1; } bool uncacheable() { return 1; }
void exclude(); void exclude();
table_map upper_select_const_tables() { return 0; }
}; };
......
...@@ -830,7 +830,7 @@ void key_restore(TABLE *form,byte *key,uint index,uint key_length); ...@@ -830,7 +830,7 @@ void key_restore(TABLE *form,byte *key,uint index,uint key_length);
int key_cmp(TABLE *form,const byte *key,uint index,uint key_length); int key_cmp(TABLE *form,const byte *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index); void key_unpack(String *to,TABLE *form,uint index);
bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields); bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields);
void init_errmessage(void); bool init_errmessage(void);
void sql_perror(const char *message); void sql_perror(const char *message);
void sql_print_error(const char *format,...) void sql_print_error(const char *format,...)
...@@ -1042,7 +1042,11 @@ extern String *make_datetime(String *str, TIME *l_time, ...@@ -1042,7 +1042,11 @@ extern String *make_datetime(String *str, TIME *l_time,
int test_if_number(char *str,int *res,bool allow_wildcards); int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(byte *,uint,char,char); void change_byte(byte *,uint,char,char);
#ifndef EMBEDDED_LIBRARY
extern "C" void unireg_abort(int exit_code); extern "C" void unireg_abort(int exit_code);
#else
#define unireg_abort(exit_code) DBUG_RETURN(exit_code)
#endif
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
SQL_SELECT *select, SQL_SELECT *select,
int use_record_cache, bool print_errors); int use_record_cache, bool print_errors);
......
...@@ -851,6 +851,7 @@ extern "C" sig_handler print_signal_warning(int sig) ...@@ -851,6 +851,7 @@ extern "C" sig_handler print_signal_warning(int sig)
(Mac OS X) we have to call exit() instead if pthread_exit(). (Mac OS X) we have to call exit() instead if pthread_exit().
*/ */
#ifndef EMBEDDED_LIBRARY
void unireg_end(void) void unireg_end(void)
{ {
clean_up(1); clean_up(1);
...@@ -862,7 +863,6 @@ void unireg_end(void) ...@@ -862,7 +863,6 @@ void unireg_end(void)
#endif #endif
} }
extern "C" void unireg_abort(int exit_code) extern "C" void unireg_abort(int exit_code)
{ {
DBUG_ENTER("unireg_abort"); DBUG_ENTER("unireg_abort");
...@@ -874,7 +874,7 @@ extern "C" void unireg_abort(int exit_code) ...@@ -874,7 +874,7 @@ extern "C" void unireg_abort(int exit_code)
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */ exit(exit_code); /* purecov: inspected */
} }
#endif
void clean_up(bool print_message) void clean_up(bool print_message)
{ {
...@@ -1024,6 +1024,7 @@ static void set_ports() ...@@ -1024,6 +1024,7 @@ static void set_ports()
} }
} }
#ifndef EMBEDDED_LIBRARY
/* Change to run as another user if started with --user */ /* Change to run as another user if started with --user */
static void set_user(const char *user) static void set_user(const char *user)
...@@ -1106,7 +1107,6 @@ static void set_root(const char *path) ...@@ -1106,7 +1107,6 @@ static void set_root(const char *path)
#endif #endif
} }
static void server_init(void) static void server_init(void)
{ {
struct sockaddr_in IPaddr; struct sockaddr_in IPaddr;
...@@ -1257,6 +1257,7 @@ static void server_init(void) ...@@ -1257,6 +1257,7 @@ static void server_init(void)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#endif /*!EMBEDDED_LIBRARY*/
void yyerror(const char *s) void yyerror(const char *s)
{ {
...@@ -2120,7 +2121,8 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -2120,7 +2121,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
open_files_limit= 0; /* Can't set or detect limit */ open_files_limit= 0; /* Can't set or detect limit */
#endif #endif
unireg_init(opt_specialflag); /* Set up extern variabels */ unireg_init(opt_specialflag); /* Set up extern variabels */
init_errmessage(); /* Read error messages from file */ if (init_errmessage()) /* Read error messages from file */
return 1;
init_client_errs(); init_client_errs();
lex_init(); lex_init();
item_init(); item_init();
...@@ -2233,6 +2235,7 @@ static void init_ssl() ...@@ -2233,6 +2235,7 @@ static void init_ssl()
static int init_server_components() static int init_server_components()
{ {
DBUG_ENTER("init_server_components");
table_cache_init(); table_cache_init();
hostname_cache_init(); hostname_cache_init();
query_cache_result_size_limit(query_cache_limit); query_cache_result_size_limit(query_cache_limit);
...@@ -2324,7 +2327,7 @@ Now disabling --log-slave-updates."); ...@@ -2324,7 +2327,7 @@ Now disabling --log-slave-updates.");
init_max_user_conn(); init_max_user_conn();
init_update_queries(); init_update_queries();
return 0; DBUG_RETURN(0);
} }
...@@ -5604,8 +5607,10 @@ static void get_options(int argc,char **argv) ...@@ -5604,8 +5607,10 @@ static void get_options(int argc,char **argv)
/* Set global MyISAM variables from delay_key_write_options */ /* Set global MyISAM variables from delay_key_write_options */
fix_delay_key_write((THD*) 0, OPT_GLOBAL); fix_delay_key_write((THD*) 0, OPT_GLOBAL);
#ifndef EMBEDDED_LIBRARY
if (mysqld_chroot) if (mysqld_chroot)
set_root(mysqld_chroot); set_root(mysqld_chroot);
#endif
fix_paths(); fix_paths();
/* /*
......
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