Commit 5f80c353 authored by unknown's avatar unknown

Merge mysql.com:/home/pz/mysql/mysql-4.1-root

into mysql.com:/home/pz/mysql/mysql-4.1


sql/mysql_priv.h:
  Auto merged
parents 4b85d31b 83b4c4d6
SELECT 1 FROM (SELECT 1) GROUP BY SUM(1);
Invalid use of group function
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
CREATE TABLE t1 ( CREATE TABLE t1 (
spID int(10) unsigned, spID int(10) unsigned,
......
This diff is collapsed.
-- error 1111
SELECT 1 FROM (SELECT 1) GROUP BY SUM(1);
# #
# Test of group (Failed for Lars Hoss <lh@pbm.de>) # Test of group (Failed for Lars Hoss <lh@pbm.de>)
# #
......
This diff is collapsed.
...@@ -126,10 +126,12 @@ public: ...@@ -126,10 +126,12 @@ public:
Field *tmp= (Field*) memdup_root(root,(char*) this,size_of()); Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
if (tmp) if (tmp)
{ {
tmp->table=new_table; tmp->table= new_table;
tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0; tmp->key_start= tmp->part_of_key= tmp->part_of_sortkey= 0;
tmp->unireg_check=Field::NONE; tmp->unireg_check=Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | ENUM_FLAG | SET_FLAG); tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
ZEROFILL_FLAG | ENUM_FLAG | SET_FLAG);
tmp->table_name= new_table->table_name;
tmp->reset_fields(); tmp->reset_fields();
} }
return tmp; return tmp;
......
...@@ -468,11 +468,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -468,11 +468,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
(last= sl)->get_table_list(), (last= sl)->get_table_list(),
0)) != not_found_field) 0)) != not_found_field)
break; break;
if((refer= find_item_in_list(this, (last= sl)->item_list, if ((refer= find_item_in_list(this, sl->item_list,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **)not_found_item) (Item **)not_found_item)
break; break;
if (sl->linkage == DERIVED_TABLE_TYPE)
break; // do not look over derived table
} }
if (!tmp) if (!tmp)
return -1; return -1;
...@@ -487,7 +488,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -487,7 +488,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
else if (refer != (Item **)not_found_item) else if (refer != (Item **)not_found_item)
{ {
Item_ref *r; Item_ref *r;
*ref= r= new Item_ref((char *)db_name, (char *)table_name, *ref= r= new Item_ref(refer, (char *)table_name,
(char *)field_name); (char *)field_name);
if (!r) if (!r)
return 1; return 1;
...@@ -867,6 +868,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -867,6 +868,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
REPORT_ALL_ERRORS))) == REPORT_ALL_ERRORS))) ==
(Item **)not_found_item) (Item **)not_found_item)
{ {
Field *tmp= (Field*) not_found_field;
/* /*
We can't find table field in table list of current select, We can't find table field in table list of current select,
consequently we have to find it in outer subselect(s). consequently we have to find it in outer subselect(s).
...@@ -878,16 +880,23 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -878,16 +880,23 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
*/ */
SELECT_LEX *last=0; SELECT_LEX *last=0;
for ( ; sl ; sl= sl->outer_select()) for ( ; sl ; sl= sl->outer_select())
if((ref= find_item_in_list(this, (last= sl)->item_list, {
if ((ref= find_item_in_list(this, (last= sl)->item_list,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **)not_found_item) (Item **)not_found_item)
break; break;
if ((tmp= find_field_in_tables(thd, this,
sl->get_table_list(),
0)) != not_found_field);
if (sl->linkage == DERIVED_TABLE_TYPE)
break; // do not look over derived table
}
if (!ref) if (!ref)
{
return 1; return 1;
} else if (!tmp)
else if (ref == (Item **)not_found_item) return -1;
else if (ref == (Item **)not_found_item && tmp == not_found_field)
{ {
// Call to report error // Call to report error
find_item_in_list(this, find_item_in_list(this,
...@@ -896,6 +905,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -896,6 +905,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
ref= 0; ref= 0;
return 1; return 1;
} }
else if (tmp != not_found_field)
{
ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item
Item_field* f;
if (!((*reference)= f= new Item_field(tmp)))
return 1;
f->depended_from= last;
thd->lex.current_select->mark_as_dependent(last);
return 0;
}
else else
{ {
depended_from= last; depended_from= last;
......
...@@ -81,6 +81,7 @@ void Item_subselect::make_field (Send_field *tmp_field) ...@@ -81,6 +81,7 @@ void Item_subselect::make_field (Send_field *tmp_field)
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
char const *save_where= thd->where;
int res= engine->prepare(); int res= engine->prepare();
if (!res) if (!res)
{ {
...@@ -93,6 +94,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -93,6 +94,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
fix_length_and_dec(); fix_length_and_dec();
} }
fixed= 1; fixed= 1;
thd->where= save_where;
return res; return res;
} }
...@@ -312,11 +314,13 @@ void subselect_union_engine::fix_length_and_dec() ...@@ -312,11 +314,13 @@ void subselect_union_engine::fix_length_and_dec()
int subselect_single_select_engine::exec() int subselect_single_select_engine::exec()
{ {
DBUG_ENTER("subselect_single_select_engine::exec"); DBUG_ENTER("subselect_single_select_engine::exec");
char const *save_where= join->thd->where;
if (!optimized) if (!optimized)
{ {
optimized=1; optimized=1;
if (join->optimize()) if (join->optimize())
{ {
join->thd->where= save_where;
executed= 1; executed= 1;
DBUG_RETURN(join->error?join->error:1); DBUG_RETURN(join->error?join->error:1);
} }
...@@ -324,7 +328,10 @@ int subselect_single_select_engine::exec() ...@@ -324,7 +328,10 @@ int subselect_single_select_engine::exec()
if (select_lex->dependent && executed) if (select_lex->dependent && executed)
{ {
if (join->reinit()) if (join->reinit())
{
join->thd->where= save_where;
DBUG_RETURN(1); DBUG_RETURN(1);
}
item->assign_null(); item->assign_null();
item->assigned((executed= 0)); item->assigned((executed= 0));
} }
...@@ -335,14 +342,19 @@ int subselect_single_select_engine::exec() ...@@ -335,14 +342,19 @@ int subselect_single_select_engine::exec()
join->exec(); join->exec();
join->thd->lex.current_select= save_select; join->thd->lex.current_select= save_select;
executed= 1; executed= 1;
join->thd->where= save_where;
DBUG_RETURN(join->error||thd->fatal_error); DBUG_RETURN(join->error||thd->fatal_error);
} }
join->thd->where= save_where;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int subselect_union_engine::exec() int subselect_union_engine::exec()
{ {
return unit->exec(); char const *save_where= unit->thd->where;
int res= unit->exec();
unit->thd->where= save_where;
return res;
} }
uint subselect_single_select_engine::cols() uint subselect_single_select_engine::cols()
......
...@@ -464,7 +464,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock); ...@@ -464,7 +464,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock);
bool drop_locked_tables(THD *thd,const char *db, const char *table_name); bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
void abort_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name);
extern const Field *not_found_field; extern const Field *not_found_field;
Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
bool report_error); bool report_error);
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
bool check_grant,bool allow_rowid); bool check_grant,bool allow_rowid);
......
...@@ -932,7 +932,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, ...@@ -932,7 +932,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
String tmp(buff1,sizeof(buff1),default_charset_info),*res; String tmp(buff1,sizeof(buff1),default_charset_info),*res;
uint length,offset,min_length,max_length; uint length,offset,min_length,max_length;
if (!field->optimize_range((uint) key_part->key)) if (!field->optimize_range(param->real_keynr[key_part->key]))
DBUG_RETURN(0); // Can't optimize this DBUG_RETURN(0); // Can't optimize this
if (!(res= value->val_str(&tmp))) if (!(res= value->val_str(&tmp)))
DBUG_RETURN(&null_element); DBUG_RETURN(&null_element);
...@@ -1002,7 +1002,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, ...@@ -1002,7 +1002,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
DBUG_RETURN(tree); DBUG_RETURN(tree);
} }
if (!field->optimize_range((uint) key_part->key) && if (!field->optimize_range(param->real_keynr[key_part->key]) &&
type != Item_func::EQ_FUNC && type != Item_func::EQ_FUNC &&
type != Item_func::EQUAL_FUNC) type != Item_func::EQUAL_FUNC)
DBUG_RETURN(0); // Can't optimize this DBUG_RETURN(0); // Can't optimize this
......
...@@ -1861,7 +1861,7 @@ const Field *not_found_field= (Field*) 0x1; ...@@ -1861,7 +1861,7 @@ const Field *not_found_field= (Field*) 0x1;
*/ */
Field * Field *
find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
bool report_error) bool report_error)
{ {
Field *found=0; Field *found=0;
...@@ -2061,9 +2061,9 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -2061,9 +2061,9 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
if (item->type() == Item::FIELD_ITEM && if (item->type() == Item::FIELD_ITEM &&
((Item_field*) item)->field_name[0] == '*') ((Item_field*) item)->field_name[0] == '*')
{ {
uint elem=fields.elements; uint elem= fields.elements;
if (insert_fields(thd,tables,((Item_field*) item)->db_name, if (insert_fields(thd,tables,((Item_field*) item)->db_name,
((Item_field*) item)->table_name,&it)) ((Item_field*) item)->table_name, &it))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (sum_func_list) if (sum_func_list)
{ {
...@@ -2079,6 +2079,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -2079,6 +2079,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
{ {
if (item->fix_fields(thd, tables, it.ref())) if (item->fix_fields(thd, tables, it.ref()))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
item= *(it.ref()); //Item can be chenged in fix fields
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
sum_func_list) sum_func_list)
item->split_sum_func(*sum_func_list); item->split_sum_func(*sum_func_list);
...@@ -2227,8 +2228,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2227,8 +2228,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
thd->set_query_id=1; thd->set_query_id=1;
thd->cond_count= 0; thd->cond_count= 0;
bool save_allow_sum_func= thd->allow_sum_func;
thd->allow_sum_func= 0;
if (*conds) if (*conds)
{ {
thd->where="where clause"; thd->where="where clause";
...@@ -2301,7 +2300,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2301,7 +2300,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
table->on_expr=and_conds(table->on_expr,cond_and); table->on_expr=and_conds(table->on_expr,cond_and);
} }
} }
thd->allow_sum_func= save_allow_sum_func;
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error));
} }
......
...@@ -294,6 +294,7 @@ public: ...@@ -294,6 +294,7 @@ public:
int cleanup(); int cleanup();
friend void mysql_init_query(THD *thd); friend void mysql_init_query(THD *thd);
friend int subselect_union_engine::exec();
private: private:
bool create_total_list_n_last_return(THD *thd, st_lex *lex, bool create_total_list_n_last_return(THD *thd, st_lex *lex,
TABLE_LIST ***result); TABLE_LIST ***result);
......
...@@ -199,6 +199,26 @@ void fix_tables_pointers(SELECT_LEX *select_lex) ...@@ -199,6 +199,26 @@ void fix_tables_pointers(SELECT_LEX *select_lex)
} }
} }
/*
Inline function to setup clauses without sum functions
*/
inline int setup_without_group(THD *thd, TABLE_LIST *tables,
List<Item> &fields,
List<Item> &all_fields,
COND **conds,
ORDER *order,
ORDER *group, bool *hidden_group_fields)
{
bool save_allow_sum_func= thd->allow_sum_func;
thd->allow_sum_func= 0;
int res= (setup_conds(thd,tables, conds) ||
setup_order(thd,tables, fields, all_fields, order) ||
setup_group(thd,tables, fields, all_fields, group,
hidden_group_fields));
thd->allow_sum_func= save_allow_sum_func;
return res;
}
/***************************************************************************** /*****************************************************************************
Check fields, find best join, do the select and output fields. Check fields, find best join, do the select and output fields.
mysql_select assumes that all tables are already opened mysql_select assumes that all tables are already opened
...@@ -233,10 +253,8 @@ JOIN::prepare(TABLE_LIST *tables_init, ...@@ -233,10 +253,8 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (setup_tables(tables_list) || if (setup_tables(tables_list) ||
setup_fields(thd,tables_list,fields_list,1,&all_fields,1) || setup_fields(thd,tables_list,fields_list,1,&all_fields,1) ||
setup_conds(thd,tables_list,&conds) || setup_without_group(thd, tables_list, fields_list, all_fields,
setup_order(thd,tables_list,fields_list,all_fields,order) || &conds, order, group_list, &hidden_group_fields))
setup_group(thd,tables_list,fields_list,all_fields,group_list,
&hidden_group_fields))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (having) if (having)
......
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