Commit e87583f5 authored by lenz@mysql.com's avatar lenz@mysql.com

Merge lgrimmer@work.mysql.com:/home/bk/mysql-4.0

into mysql.com:/space/my/mysql-4.0
parents 9c838763 e6347704
DROP TABLE IF EXISTS t1;
SELECT IF(NULL AND 1, 1, 2), IF(1 AND NULL, 1, 2);
IF(NULL AND 1, 1, 2) IF(1 AND NULL, 1, 2)
2 2
SELECT NULL AND 1, 1 AND NULL, 0 AND NULL, NULL and 0;
NULL AND 1 1 AND NULL 0 AND NULL NULL and 0
NULL NULL 0 0
create table t1 (a int);
insert into t1 values (0),(1),(NULL);
SELECT * FROM t1 WHERE IF(a AND 1, 0, 1);
a
0
NULL
SELECT * FROM t1 WHERE IF(1 AND a, 0, 1);
a
0
NULL
SELECT * FROM t1 where NOT(a AND 1);
a
0
SELECT * FROM t1 where NOT(1 AND a);
a
0
SELECT * FROM t1 where (a AND 1)=0;
a
0
SELECT * FROM t1 where (1 AND a)=0;
a
0
SELECT * FROM t1 where (1 AND a)=1;
a
1
SELECT * FROM t1 where (1 AND a) IS NULL;
a
NULL
SET @a=0, @b=0;
SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
a
SELECT * FROM t1 WHERE NOT(a>=0 AND NULL AND (@b:=@b+1));
a
SELECT * FROM t1 WHERE a=2 OR (NULL AND (@a:=@a+1));
a
SELECT * FROM t1 WHERE NOT(a=2 OR (NULL AND (@b:=@b+1)));
a
SELECT @a, @b;
@a @b
0 6
DROP TABLE t1;
...@@ -84,6 +84,12 @@ select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', y ...@@ -84,6 +84,12 @@ select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', y
select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006'; select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
2000 2001 2002 2003 2004 2005 2006 2000 2001 2002 2003 2004 2005 2006
200001 200101 200201 200302 200402 200501 200601 200001 200101 200201 200302 200402 200501 200601
select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
week(19981231,2) week(19981231,3) week(20000101,2) week(20000101,3)
52 53 52 52
select week(20001231,2),week(20001231,3);
week(20001231,2) week(20001231,3)
1 52
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v'); select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v') date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
1998-53 1998-53 1998-53 1998-53
......
...@@ -30,7 +30,7 @@ SELECT (NULL OR NULL) IS NULL; ...@@ -30,7 +30,7 @@ SELECT (NULL OR NULL) IS NULL;
1 1
select NULL AND 0, 0 and NULL; select NULL AND 0, 0 and NULL;
NULL AND 0 0 and NULL NULL AND 0 0 and NULL
NULL 0 0 0
select inet_ntoa(null),inet_aton(null),inet_aton("122.256"),inet_aton("122.226."),inet_aton(""); select inet_ntoa(null),inet_aton(null),inet_aton("122.256"),inet_aton("122.226."),inet_aton("");
inet_ntoa(null) inet_aton(null) inet_aton("122.256") inet_aton("122.226.") inet_aton("") inet_ntoa(null) inet_aton(null) inet_aton("122.256") inet_aton("122.226.") inet_aton("")
NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
......
#
# Test of boolean operations with NULL
#
DROP TABLE IF EXISTS t1;
SELECT IF(NULL AND 1, 1, 2), IF(1 AND NULL, 1, 2);
SELECT NULL AND 1, 1 AND NULL, 0 AND NULL, NULL and 0;
create table t1 (a int);
insert into t1 values (0),(1),(NULL);
SELECT * FROM t1 WHERE IF(a AND 1, 0, 1);
SELECT * FROM t1 WHERE IF(1 AND a, 0, 1);
SELECT * FROM t1 where NOT(a AND 1);
SELECT * FROM t1 where NOT(1 AND a);
SELECT * FROM t1 where (a AND 1)=0;
SELECT * FROM t1 where (1 AND a)=0;
SELECT * FROM t1 where (1 AND a)=1;
SELECT * FROM t1 where (1 AND a) IS NULL;
# Verify that NULL optimisation works in AND clause:
SET @a=0, @b=0;
SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
SELECT * FROM t1 WHERE NOT(a>=0 AND NULL AND (@b:=@b+1));
SELECT * FROM t1 WHERE a=2 OR (NULL AND (@a:=@a+1));
SELECT * FROM t1 WHERE NOT(a=2 OR (NULL AND (@b:=@b+1)));
SELECT @a, @b;
DROP TABLE t1;
...@@ -34,6 +34,9 @@ select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', y ...@@ -34,6 +34,9 @@ select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', y
select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006'; select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006'; select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006'; select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
select week(20001231,2),week(20001231,3);
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v'); select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v'); select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
......
...@@ -4,7 +4,7 @@ use Getopt::Long; ...@@ -4,7 +4,7 @@ use Getopt::Long;
use POSIX qw(strftime); use POSIX qw(strftime);
$|=1; $|=1;
$VER="2.4"; $VER="2.5";
$opt_config_file = undef(); $opt_config_file = undef();
$opt_example = 0; $opt_example = 0;
...@@ -212,6 +212,7 @@ sub start_mysqlds() ...@@ -212,6 +212,7 @@ sub start_mysqlds()
} }
else else
{ {
$options[$j]=~ s/;/\\;/g;
$tmp.= " $options[$j]"; $tmp.= " $options[$j]";
} }
} }
......
...@@ -204,7 +204,7 @@ else ...@@ -204,7 +204,7 @@ else
fi fi
USER_OPTION="" USER_OPTION=""
if test "x$USER" = "xroot" if test -w / -o "$USER" = "root"
then then
if test "$user" != "root" -o $SET_USER = 1 if test "$user" != "root" -o $SET_USER = 1
then then
......
...@@ -85,6 +85,7 @@ class Item { ...@@ -85,6 +85,7 @@ class Item {
virtual bool get_time(TIME *ltime); virtual bool get_time(TIME *ltime);
virtual bool is_null() { return 0; } virtual bool is_null() { return 0; }
virtual unsigned int size_of()= 0; virtual unsigned int size_of()= 0;
virtual void top_level_item() {}
}; };
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
/* /*
Test functions Test functions
These returns 0LL if false and 1LL if true and null if some arg is null Most of these returns 0LL if false and 1LL if true and
'AND' and 'OR' never return null NULL if some arg is NULL.
*/ */
longlong Item_func_not::val_int() longlong Item_func_not::val_int()
...@@ -1121,6 +1121,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -1121,6 +1121,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
#endif #endif
item= *li.ref(); // new current item item= *li.ref(); // new current item
} }
if (abort_on_null)
item->top_level_item();
if (item->fix_fields(thd,tables)) if (item->fix_fields(thd,tables))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
...@@ -1196,28 +1198,41 @@ void Item_cond::print(String *str) ...@@ -1196,28 +1198,41 @@ void Item_cond::print(String *str)
str->append(')'); str->append(')');
} }
/*
Evalution of AND(expr, expr, expr ...)
NOTES:
abort_if_null is set for AND expressions for which we don't care if the
result is NULL or 0. This is set for:
- WHERE clause
- HAVING clause
- IF(expression)
RETURN VALUES
1 If all expressions are true
0 If all expressions are false or if we find a NULL expression and
'abort_on_null' is set.
NULL if all expression are either 1 or NULL
*/
longlong Item_cond_and::val_int() longlong Item_cond_and::val_int()
{ {
List_iterator_fast<Item> li(list); List_iterator_fast<Item> li(list);
Item *item; Item *item;
null_value= 0;
while ((item=li++)) while ((item=li++))
{ {
if (item->val_int() == 0) if (item->val_int() == 0)
{ {
/* if (abort_on_null || !(null_value= item->null_value))
TODO: In case of NULL, ANSI would require us to continue evaluation return 0; // return FALSE
until we get a FALSE value or run out of values; This would
require a lot of unnecessary evaluation, which we skip for now
*/
null_value=item->null_value;
return 0;
} }
} }
null_value=0; return null_value ? 0 : 1;
return 1;
} }
longlong Item_cond_or::val_int() longlong Item_cond_or::val_int()
{ {
List_iterator_fast<Item> li(list); List_iterator_fast<Item> li(list);
...@@ -1260,15 +1275,15 @@ longlong Item_cond_or::val_int() ...@@ -1260,15 +1275,15 @@ longlong Item_cond_or::val_int()
Item *and_expressions(Item *a, Item *b, Item **org_item) Item *and_expressions(Item *a, Item *b, Item **org_item)
{ {
if (!a) if (!a)
return (*org_item= (Item*) b); return (*org_item= b);
if (a == *org_item) if (a == *org_item)
{ {
Item_cond *res; Item_cond *res;
if ((res= new Item_cond_and(a, (Item*) b))) if ((res= new Item_cond_and(a, b)))
res->used_tables_cache= a->used_tables() | b->used_tables(); res->used_tables_cache= a->used_tables() | b->used_tables();
return res; return res;
} }
if (((Item_cond_and*) a)->add((Item*) b)) if (((Item_cond_and*) a)->add(b))
return 0; return 0;
((Item_cond_and*) a)->used_tables_cache|= b->used_tables(); ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
return a; return a;
......
...@@ -216,6 +216,11 @@ class Item_func_if :public Item_func ...@@ -216,6 +216,11 @@ class Item_func_if :public Item_func
longlong val_int(); longlong val_int();
String *val_str(String *str); String *val_str(String *str);
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd,struct st_table_list *tlist)
{
args[0]->top_level_item();
return Item_func::fix_fields(thd,tlist);
}
void fix_length_and_dec(); void fix_length_and_dec();
const char *func_name() const { return "if"; } const char *func_name() const { return "if"; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
...@@ -560,10 +565,12 @@ class Item_cond :public Item_bool_func ...@@ -560,10 +565,12 @@ class Item_cond :public Item_bool_func
{ {
protected: protected:
List<Item> list; List<Item> list;
bool abort_on_null;
public: public:
Item_cond() : Item_bool_func() { const_item_cache=0; } /* Item_cond() is only used to create top level items */
Item_cond(Item *i1,Item *i2) :Item_bool_func() Item_cond() : Item_bool_func(), abort_on_null(1) { const_item_cache=0; }
{ list.push_back(i1); list.push_back(i2); } Item_cond(Item *i1,Item *i2) :Item_bool_func(), abort_on_null(0)
{ list.push_back(i1); list.push_back(i2); }
~Item_cond() { list.delete_elements(); } ~Item_cond() { list.delete_elements(); }
bool add(Item *item) { return list.push_back(item); } bool add(Item *item) { return list.push_back(item); }
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *,struct st_table_list *);
...@@ -576,6 +583,7 @@ class Item_cond :public Item_bool_func ...@@ -576,6 +583,7 @@ class Item_cond :public Item_bool_func
void split_sum_func(List<Item> &fields); void split_sum_func(List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
void top_level_item() { abort_on_null=1; }
}; };
......
...@@ -175,15 +175,28 @@ longlong Item_func_second::val_int() ...@@ -175,15 +175,28 @@ longlong Item_func_second::val_int()
} }
// Returns the week of year in the range of 0 - 53 /*
Returns the week of year.
The bits in week_format has the following meaning:
0 If not set: USA format: Sunday is first day of week
If set: ISO format: Monday is first day of week
1 If not set: Week is in range 0-53
If set Week is in range 1-53.
*/
longlong Item_func_week::val_int() longlong Item_func_week::val_int()
{ {
uint year; uint year;
uint week_format;
TIME ltime; TIME ltime;
if (get_arg0_date(&ltime,0)) if (get_arg0_date(&ltime,0))
return 0; return 0;
return (longlong) calc_week(&ltime, 0, args[1]->val_int() == 0, &year); week_format= args[1]->val_int();
return (longlong) calc_week(&ltime,
(week_format & 2) != 0,
(week_format & 1) == 0,
&year);
} }
...@@ -193,7 +206,7 @@ longlong Item_func_yearweek::val_int() ...@@ -193,7 +206,7 @@ longlong Item_func_yearweek::val_int()
TIME ltime; TIME ltime;
if (get_arg0_date(&ltime,0)) if (get_arg0_date(&ltime,0))
return 0; return 0;
week=calc_week(&ltime, 1, args[1]->val_int() == 0, &year); week=calc_week(&ltime, 1, (args[1]->val_int() & 1) == 0, &year);
return week+year*100; return week+year*100;
} }
......
...@@ -2003,6 +2003,8 @@ int main(int argc, char **argv) ...@@ -2003,6 +2003,8 @@ int main(int argc, char **argv)
if (ha_init()) if (ha_init())
{ {
sql_print_error("Can't init databases"); sql_print_error("Can't init databases");
if (unix_sock != INVALID_SOCKET)
unlink(mysql_unix_port);
exit(1); exit(1);
} }
ha_key_cache(); ha_key_cache();
...@@ -2038,6 +2040,8 @@ int main(int argc, char **argv) ...@@ -2038,6 +2040,8 @@ int main(int argc, char **argv)
pthread_key_create(&THR_MALLOC,NULL)) pthread_key_create(&THR_MALLOC,NULL))
{ {
sql_print_error("Can't create thread-keys"); sql_print_error("Can't create thread-keys");
if (unix_sock != INVALID_SOCKET)
unlink(mysql_unix_port);
exit(1); exit(1);
} }
start_signal_handler(); // Creates pidfile start_signal_handler(); // Creates pidfile
...@@ -2050,6 +2054,8 @@ int main(int argc, char **argv) ...@@ -2050,6 +2054,8 @@ int main(int argc, char **argv)
if (!opt_bootstrap) if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
#endif #endif
if (unix_sock != INVALID_SOCKET)
unlink(mysql_unix_port);
exit(1); exit(1);
} }
if (!opt_noacl) if (!opt_noacl)
...@@ -4467,8 +4473,8 @@ fn_format_relative_to_data_home(my_string to, const char *name, ...@@ -4467,8 +4473,8 @@ fn_format_relative_to_data_home(my_string to, const char *name,
static void fix_paths(void) static void fix_paths(void)
{ {
char buff[FN_REFLEN]; char buff[FN_REFLEN];
(void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
convert_dirname(mysql_home,mysql_home,NullS); convert_dirname(mysql_home,mysql_home,NullS);
my_realpath(mysql_home,mysql_home,MYF(0));
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
convert_dirname(language,language,NullS); convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
......
...@@ -376,14 +376,14 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, ...@@ -376,14 +376,14 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
if (!found) if (!found)
if_wait_for_refresh=0; // Nothing to wait for if_wait_for_refresh=0; // Nothing to wait for
} }
if (!tables)
kill_delayed_threads();
if (if_wait_for_refresh) if (if_wait_for_refresh)
{ {
/* /*
If there is any table that has a lower refresh_version, wait until If there is any table that has a lower refresh_version, wait until
this is closed (or this thread is killed) before returning this is closed (or this thread is killed) before returning
*/ */
if (!tables)
kill_delayed_threads();
thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Flushing tables"; thd->proc_info="Flushing tables";
...@@ -1976,6 +1976,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -1976,6 +1976,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
Item_cond_and *cond_and=new Item_cond_and(); Item_cond_and *cond_and=new Item_cond_and();
if (!cond_and) // If not out of memory if (!cond_and) // If not out of memory
DBUG_RETURN(1); DBUG_RETURN(1);
cond_and->top_level_item();
uint i,j; uint i,j;
for (i=0 ; i < t1->fields ; i++) for (i=0 ; i < t1->fields ; i++)
......
...@@ -3324,12 +3324,16 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) ...@@ -3324,12 +3324,16 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
void add_join_on(TABLE_LIST *b,Item *expr) void add_join_on(TABLE_LIST *b,Item *expr)
{ {
if (!b->on_expr) if (expr)
b->on_expr=expr;
else
{ {
// This only happens if you have both a right and left join if (!b->on_expr)
b->on_expr=new Item_cond_and(b->on_expr,expr); b->on_expr=expr;
else
{
// This only happens if you have both a right and left join
b->on_expr=new Item_cond_and(b->on_expr,expr);
}
b->on_expr->top_level_item();
} }
} }
......
...@@ -359,6 +359,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -359,6 +359,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{ {
conds->fix_fields(thd,tables); conds->fix_fields(thd,tables);
conds->change_ref_to_fields(thd,tables); conds->change_ref_to_fields(thd,tables);
conds->top_level_item();
having=0; having=0;
} }
} }
...@@ -868,6 +869,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -868,6 +869,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
sort_table_cond))) sort_table_cond)))
goto err; goto err;
table->select_cond=table->select->cond; table->select_cond=table->select->cond;
table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(table->select->cond, DBUG_EXECUTE("where",print_where(table->select->cond,
"select and having");); "select and having"););
having=make_cond_for_table(having,~ (table_map) 0,~used_tables); having=make_cond_for_table(having,~ (table_map) 0,~used_tables);
...@@ -5384,6 +5386,7 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table) ...@@ -5384,6 +5386,7 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
{ {
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{ {
/* Create new top level AND item */
Item_cond_and *new_cond=new Item_cond_and; Item_cond_and *new_cond=new Item_cond_and;
if (!new_cond) if (!new_cond)
return (COND*) 0; // OOM /* purecov: inspected */ return (COND*) 0; // OOM /* purecov: inspected */
...@@ -5421,7 +5424,8 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table) ...@@ -5421,7 +5424,8 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
new_cond->argument_list()->push_back(fix); new_cond->argument_list()->push_back(fix);
} }
new_cond->used_tables_cache=((Item_cond_or*) cond)->used_tables_cache; new_cond->used_tables_cache=((Item_cond_or*) cond)->used_tables_cache;
return new_cond; new_cond->top_level_item();
DBUG_RETURN(new_cond);
} }
} }
...@@ -5772,6 +5776,7 @@ static bool fix_having(JOIN *join, Item **having) ...@@ -5772,6 +5776,7 @@ static bool fix_having(JOIN *join, Item **having)
sort_table_cond))) sort_table_cond)))
return 1; return 1;
table->select_cond=table->select->cond; table->select_cond=table->select->cond;
table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(table->select_cond, DBUG_EXECUTE("where",print_where(table->select_cond,
"select and having");); "select and having"););
*having=make_cond_for_table(*having,~ (table_map) 0,~used_tables); *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
......
...@@ -2178,15 +2178,25 @@ opt_table_alias: ...@@ -2178,15 +2178,25 @@ opt_table_alias:
where_clause: where_clause:
/* empty */ { Select->where= 0; } /* empty */ { Select->where= 0; }
| WHERE expr { Select->where= $2; }; | WHERE expr
{
Select->where= $2;
if ($2)
$2->top_level_item();
}
;
having_clause: having_clause:
/* empty */ /* empty */
| HAVING { Select->create_refs=1; } expr | HAVING { Select->create_refs=1; } expr
{ {
SELECT_LEX *sel=Select; SELECT_LEX *sel=Select;
sel->having= $3; sel->create_refs=0; sel->having= $3;
}; sel->create_refs=0;
if ($3)
$3->top_level_item();
}
;
opt_escape: opt_escape:
ESCAPE_SYM TEXT_STRING { $$= $2.str; } ESCAPE_SYM TEXT_STRING { $$= $2.str; }
......
...@@ -24,7 +24,7 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \ ...@@ -24,7 +24,7 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \
insert_and_repair.pl \ insert_and_repair.pl \
grant.pl grant.res test_delayed_insert.pl \ grant.pl grant.res test_delayed_insert.pl \
pmail.pl mail_to_db.pl table_types.pl \ pmail.pl mail_to_db.pl table_types.pl \
udf_test udf_test.res udf_test udf_test.res myisam-big-rows.tst
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
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