merging
sql/item.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/item_sum.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_class.h: Auto merged sql/sql_delete.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_list.h: Auto merged sql/sql_load.cc: Auto merged sql/sql_olap.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_table.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
commit
fbd882fca6
@ -155,21 +155,18 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
|
||||
a b
|
||||
1 7
|
||||
2 7
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 order by a limit 2) limit 3;
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
|
||||
a b
|
||||
1 7
|
||||
2 7
|
||||
3 8
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
a b
|
||||
1 7
|
||||
2 7
|
||||
3 8
|
||||
4 8
|
||||
explain (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
explain (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||
2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 Using filesort
|
||||
@ -403,19 +400,15 @@ Unknown column 'a' in 'having clause'
|
||||
SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY date);
|
||||
mot topic date pseudo
|
||||
joce 40143 2002-10-22 joce
|
||||
joce 43506 2002-10-22 joce
|
||||
SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY date HAVING topic < 4100);
|
||||
mot topic date pseudo
|
||||
joce 43506 2002-10-22 joce
|
||||
SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
|
||||
mot topic date pseudo
|
||||
SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY date);
|
||||
mot topic date pseudo
|
||||
joce 40143 2002-10-22 joce
|
||||
joce 43506 2002-10-22 joce
|
||||
SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY date HAVING topic < 4100);
|
||||
mot topic date pseudo
|
||||
joce 43506 2002-10-22 joce
|
||||
SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
|
||||
mot topic date pseudo
|
||||
SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY date);
|
||||
@ -424,6 +417,7 @@ joce 40143 2002-10-22 joce
|
||||
SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY date HAVING topic < 4100);
|
||||
mot topic date pseudo
|
||||
joce 40143 2002-10-22 joce
|
||||
joce 43506 2002-10-22 joce
|
||||
SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
|
||||
mot topic date pseudo
|
||||
SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
|
||||
|
@ -70,12 +70,9 @@ select (select a from t3), a from t2;
|
||||
select * from t2 where t2.a=(select a from t1);
|
||||
insert into t3 values (6),(7),(3);
|
||||
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 order by a limit 2) limit 3;
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
explain (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
|
||||
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
|
||||
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
explain (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
|
||||
select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||
(select * from t2 where a>1) as tt;
|
||||
@ -216,7 +213,10 @@ SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY date);
|
||||
SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY date HAVING topic < 4100);
|
||||
SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
|
||||
SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY date);
|
||||
SELECT topic FROM t2 GROUP BY date;
|
||||
SELECT topic FROM t2 GROUP BY date HAVING topic < 4100;
|
||||
SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY date HAVING topic < 4100);
|
||||
SELECT *, date as fff from t2 where not (SELECT date FROM t2 GROUP BY date HAVING topic < 4100 and fff!=date);
|
||||
SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
|
||||
SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
|
||||
drop table t1,t2;
|
||||
|
75
sql/item.cc
75
sql/item.cc
@ -46,6 +46,30 @@ Item::Item():
|
||||
loop_id= 0;
|
||||
}
|
||||
|
||||
Item::Item(Item &item):
|
||||
loop_id(0),
|
||||
str_value(item.str_value),
|
||||
name(item.name),
|
||||
max_length(item.max_length),
|
||||
marker(item.marker),
|
||||
decimals(item.decimals),
|
||||
maybe_null(item.maybe_null),
|
||||
null_value(item.null_value),
|
||||
unsigned_flag(item.unsigned_flag),
|
||||
with_sum_func(item.with_sum_func),
|
||||
fixed(item.fixed)
|
||||
{
|
||||
next=current_thd->free_list; // Put in free list
|
||||
current_thd->free_list= this;
|
||||
}
|
||||
|
||||
Item_ident::Item_ident(Item_ident &item):
|
||||
Item(item),
|
||||
db_name(item.db_name),
|
||||
table_name(item.table_name),
|
||||
field_name(item.field_name),
|
||||
depended_from(item.depended_from)
|
||||
{}
|
||||
|
||||
bool Item::check_loop(uint id)
|
||||
{
|
||||
@ -154,6 +178,11 @@ Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name)
|
||||
fixed= 1; // This item is not needed in fix_fields
|
||||
}
|
||||
|
||||
Item_field::Item_field(Item_field &item):
|
||||
Item_ident(item),
|
||||
field(item.field),
|
||||
result_field(item.result_field)
|
||||
{}
|
||||
|
||||
void Item_field::set_field(Field *field_par)
|
||||
{
|
||||
@ -265,6 +294,13 @@ table_map Item_field::used_tables() const
|
||||
return field->table->map;
|
||||
}
|
||||
|
||||
Item * Item_field::get_tmp_table_item()
|
||||
{
|
||||
Item_field *new_item= new Item_field(*this);
|
||||
if (new_item)
|
||||
new_item->field= new_item->result_field;
|
||||
return new_item;
|
||||
}
|
||||
|
||||
String *Item_int::val_str(String *str)
|
||||
{
|
||||
@ -600,6 +636,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
thd->net.last_errno= 0;
|
||||
#endif
|
||||
Item **refer= (Item **)not_found_item;
|
||||
uint counter= 0;
|
||||
// Prevent using outer fields in subselects, that is not supported now
|
||||
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
|
||||
if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
|
||||
@ -611,7 +648,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
(last= sl)->get_table_list(), &where,
|
||||
0)) != not_found_field)
|
||||
break;
|
||||
if ((refer= find_item_in_list(this, sl->item_list,
|
||||
if ((refer= find_item_in_list(this, sl->item_list, &counter,
|
||||
REPORT_EXCEPT_NOT_FOUND)) !=
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
@ -631,8 +668,16 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
}
|
||||
else if (refer != (Item **)not_found_item)
|
||||
{
|
||||
if (!(*refer)->fixed)
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Item_ref *r;
|
||||
*ref= r= new Item_ref(refer, (char *)table_name,
|
||||
*ref= r= new Item_ref(last->ref_pointer_array + counter-1
|
||||
, (char *)table_name,
|
||||
(char *)field_name);
|
||||
if (!r)
|
||||
return 1;
|
||||
@ -1045,6 +1090,7 @@ bool Item_field::send(Protocol *protocol, String *buffer)
|
||||
|
||||
bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
uint counter= 0;
|
||||
if (!ref)
|
||||
{
|
||||
TABLE_LIST *where= 0;
|
||||
@ -1059,6 +1105,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
if (outer_resolving ||
|
||||
(ref= find_item_in_list(this,
|
||||
*(thd->lex.current_select->get_item_list()),
|
||||
&counter,
|
||||
((sl &&
|
||||
thd->lex.current_select->master_unit()->
|
||||
first_select()->linkage !=
|
||||
@ -1081,7 +1128,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
for ( ; sl ; sl= sl->outer_select())
|
||||
{
|
||||
if ((ref= find_item_in_list(this, (last= sl)->item_list,
|
||||
REPORT_EXCEPT_NOT_FOUND)) !=
|
||||
&counter,
|
||||
REPORT_EXCEPT_NOT_FOUND)) !=
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
if ((tmp= find_field_in_tables(thd, this,
|
||||
@ -1102,6 +1150,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
// Call to report error
|
||||
find_item_in_list(this,
|
||||
*(thd->lex.current_select->get_item_list()),
|
||||
&counter,
|
||||
REPORT_ALL_ERRORS);
|
||||
ref= 0;
|
||||
return 1;
|
||||
@ -1118,17 +1167,35 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
}
|
||||
else
|
||||
{
|
||||
depended_from= last;
|
||||
if (!(*ref)->fixed)
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
ref= (depended_from= last)->ref_pointer_array + counter-1;
|
||||
thd->lex.current_select->mark_as_dependent(last);
|
||||
thd->add_possible_loop(this);
|
||||
}
|
||||
}
|
||||
else if (!ref)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (!(*ref)->fixed)
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
ref= thd->lex.current_select->ref_pointer_array + counter-1;
|
||||
}
|
||||
|
||||
max_length= (*ref)->max_length;
|
||||
maybe_null= (*ref)->maybe_null;
|
||||
decimals= (*ref)->decimals;
|
||||
}
|
||||
|
||||
if (((*ref)->with_sum_func &&
|
||||
(depended_from ||
|
||||
!(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE &&
|
||||
|
26
sql/item.h
26
sql/item.h
@ -52,6 +52,8 @@ public:
|
||||
|
||||
// alloc & destruct is done as start of select using sql_alloc
|
||||
Item();
|
||||
// copy constructor used by Item_field, Item_ref & agregate (sum) functions
|
||||
Item(Item &item);
|
||||
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||
void set_name(const char *str,uint length=0);
|
||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
@ -70,7 +72,8 @@ public:
|
||||
virtual double val()=0;
|
||||
virtual longlong val_int()=0;
|
||||
virtual String *val_str(String*)=0;
|
||||
virtual Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return 0; }
|
||||
virtual Field *tmp_table_field() { return 0; }
|
||||
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
|
||||
virtual const char *full_name() const { return name ? name : "???"; }
|
||||
virtual double val_result() { return val(); }
|
||||
virtual longlong val_int_result() { return val_int(); }
|
||||
@ -84,12 +87,14 @@ public:
|
||||
virtual bool const_item() const { return used_tables() == 0; }
|
||||
virtual void print(String *str_arg) { str_arg->append(full_name()); }
|
||||
virtual void update_used_tables() {}
|
||||
virtual void split_sum_func(List<Item> &fields) {}
|
||||
virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields) {}
|
||||
virtual bool get_date(TIME *ltime,bool fuzzydate);
|
||||
virtual bool get_time(TIME *ltime);
|
||||
virtual bool is_null() { return 0; };
|
||||
virtual bool check_loop(uint id);
|
||||
virtual void top_level_item() {}
|
||||
virtual Item * get_same() { return this; }
|
||||
virtual Item * get_tmp_table_item() { return get_same(); }
|
||||
|
||||
virtual bool binary() const
|
||||
{ return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
|
||||
@ -124,6 +129,8 @@ public:
|
||||
:db_name(db_name_par), table_name(table_name_par),
|
||||
field_name(field_name_par), depended_from(0), outer_resolving(0)
|
||||
{ name = (char*) field_name_par; }
|
||||
// copy constructor used by Item_field & Item_ref
|
||||
Item_ident(Item_ident &item);
|
||||
const char *full_name() const;
|
||||
void set_outer_resolving() { outer_resolving= 1; }
|
||||
};
|
||||
@ -140,6 +147,8 @@ public:
|
||||
const char *field_name_par)
|
||||
:Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0)
|
||||
{}
|
||||
// copy constructor need to process subselect with temporary tables
|
||||
Item_field(Item_field &item);
|
||||
Item_field(Field *field);
|
||||
enum Type type() const { return FIELD_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
@ -163,10 +172,12 @@ public:
|
||||
{
|
||||
return field->type();
|
||||
}
|
||||
Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg) { return result_field; }
|
||||
bool get_date(TIME *ltime,bool fuzzydate);
|
||||
bool get_time(TIME *ltime);
|
||||
bool is_null() { return field->is_null(); }
|
||||
Item * get_tmp_table_item();
|
||||
};
|
||||
|
||||
|
||||
@ -446,8 +457,13 @@ class Item_result_field :public Item /* Item with result field */
|
||||
public:
|
||||
Field *result_field; /* Save result here */
|
||||
Item_result_field() :result_field(0) {}
|
||||
Item_result_field(Item_result_field &item): Item(item)
|
||||
{
|
||||
result_field= item.result_field;
|
||||
}
|
||||
~Item_result_field() {} /* Required with gcc 2.95 */
|
||||
Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg) { return result_field; }
|
||||
table_map used_tables() const { return 1; }
|
||||
virtual void fix_length_and_dec()=0;
|
||||
};
|
||||
@ -461,6 +477,8 @@ public:
|
||||
:Item_ident(db_par,table_name_par,field_name_par),ref(0) {}
|
||||
Item_ref(Item **item, char *table_name_par,char *field_name_par)
|
||||
:Item_ident(NullS,table_name_par,field_name_par),ref(item) {}
|
||||
// copy constructor need to process subselect with temporary tables
|
||||
Item_ref(Item_ref &item): Item_ident(item), ref(item.ref) {}
|
||||
enum Type type() const { return REF_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{ return ref && (*ref)->eq(item, binary_cmp); }
|
||||
|
@ -1396,16 +1396,20 @@ void Item_func_in::update_used_tables()
|
||||
const_item_cache&=item->const_item();
|
||||
}
|
||||
|
||||
void Item_func_in::split_sum_func(List<Item> &fields)
|
||||
void Item_func_in::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||
{
|
||||
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
|
||||
item->split_sum_func(fields);
|
||||
item->split_sum_func(ref_pointer_array, fields);
|
||||
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
|
||||
{
|
||||
uint el= fields.elements;
|
||||
fields.push_front(item);
|
||||
item=new Item_ref((Item**) fields.head_ref(),0,item->name);
|
||||
ref_pointer_array[el]= item;
|
||||
item=new Item_ref(ref_pointer_array + el,
|
||||
0, item->name);
|
||||
|
||||
}
|
||||
Item_func::split_sum_func(fields);
|
||||
Item_func::split_sum_func(ref_pointer_array, fields);
|
||||
}
|
||||
|
||||
|
||||
@ -1511,7 +1515,7 @@ void Item_cond::set_outer_resolving()
|
||||
item->set_outer_resolving();
|
||||
}
|
||||
|
||||
void Item_cond::split_sum_func(List<Item> &fields)
|
||||
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
@ -1520,11 +1524,13 @@ void Item_cond::split_sum_func(List<Item> &fields)
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
|
||||
item->split_sum_func(fields);
|
||||
item->split_sum_func(ref_pointer_array, fields);
|
||||
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
|
||||
{
|
||||
uint el= fields.elements;
|
||||
fields.push_front(item);
|
||||
li.replace(new Item_ref((Item**) fields.head_ref(),0,item->name));
|
||||
ref_pointer_array[el]= item;
|
||||
li.replace(new Item_ref(ref_pointer_array + el, 0, item->name));
|
||||
}
|
||||
item->update_used_tables();
|
||||
used_tables_cache|=item->used_tables();
|
||||
|
@ -650,7 +650,7 @@ class Item_func_in :public Item_int_func
|
||||
enum Functype functype() const { return IN_FUNC; }
|
||||
const char *func_name() const { return " IN "; }
|
||||
void update_used_tables();
|
||||
void split_sum_func(List<Item> &fields);
|
||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||
bool check_loop(uint id)
|
||||
{
|
||||
DBUG_ENTER("Item_func_in::check_loop");
|
||||
@ -801,7 +801,7 @@ public:
|
||||
table_map used_tables() const;
|
||||
void update_used_tables();
|
||||
void print(String *str);
|
||||
void split_sum_func(List<Item> &fields);
|
||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
||||
bool check_loop(uint id);
|
||||
void top_level_item() { abort_on_null=1; }
|
||||
|
@ -155,17 +155,19 @@ void Item_func::set_outer_resolving()
|
||||
}
|
||||
}
|
||||
|
||||
void Item_func::split_sum_func(List<Item> &fields)
|
||||
void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
|
||||
{
|
||||
if ((*arg)->with_sum_func && (*arg)->type() != SUM_FUNC_ITEM)
|
||||
(*arg)->split_sum_func(fields);
|
||||
(*arg)->split_sum_func(ref_pointer_array, fields);
|
||||
else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM)
|
||||
{
|
||||
uint el= fields.elements;
|
||||
fields.push_front(*arg);
|
||||
*arg=new Item_ref((Item**) fields.head_ref(),0,(*arg)->name);
|
||||
ref_pointer_array[el]= *arg;
|
||||
*arg=new Item_ref(ref_pointer_array + el, 0, (*arg)->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,14 +236,11 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Field *Item_func::tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
Field *res;
|
||||
LINT_INIT(res);
|
||||
|
||||
if (!t_arg)
|
||||
return result_field;
|
||||
switch (result_type()) {
|
||||
case INT_RESULT:
|
||||
if (max_length > 11)
|
||||
@ -312,6 +311,16 @@ void Item_func::fix_num_length_and_dec()
|
||||
max_length=float_length(decimals);
|
||||
}
|
||||
|
||||
Item * Item_func::get_tmp_table_item()
|
||||
{
|
||||
if (!with_sum_func && !const_item())
|
||||
{
|
||||
return new Item_field(result_field);
|
||||
}
|
||||
else
|
||||
return get_same();
|
||||
}
|
||||
|
||||
String *Item_int_func::val_str(String *str)
|
||||
{
|
||||
longlong nr=val_int();
|
||||
|
@ -117,7 +117,7 @@ public:
|
||||
inline Item **arguments() const { return args; }
|
||||
inline uint argument_count() const { return arg_count; }
|
||||
inline void remove_arguments() { arg_count=0; }
|
||||
virtual void split_sum_func(List<Item> &fields);
|
||||
virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||
void print(String *str);
|
||||
void print_op(String *str);
|
||||
void fix_num_length_and_dec();
|
||||
@ -131,9 +131,11 @@ public:
|
||||
}
|
||||
bool is_null() { (void) val_int(); return null_value; }
|
||||
friend class udf_handler;
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg);
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving();
|
||||
Item * get_tmp_table_item();
|
||||
};
|
||||
|
||||
|
||||
|
@ -439,6 +439,8 @@ void Item_in_subselect::single_value_transformer(THD *thd,
|
||||
compare_func_creator func)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::single_value_transformer");
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (unit->global_parameters->select_limit != HA_POS_ERROR)
|
||||
{
|
||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
||||
@ -482,11 +484,15 @@ void Item_in_subselect::single_value_transformer(THD *thd,
|
||||
|
||||
sl->order_list.empty(); // no sense in ORDER BY without LIMIT
|
||||
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first)
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.elements)
|
||||
{
|
||||
sl->item_list.push_back(item);
|
||||
setup_ref_array(thd, &sl->ref_pointer_array,
|
||||
1+ select_lex->with_sum_func +
|
||||
select_lex->order_list.elements +
|
||||
select_lex->group_list.elements);
|
||||
item= (*func)(expr, new Item_ref_null_helper(this,
|
||||
sl->item_list.head_ref(),
|
||||
sl->ref_pointer_array,
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
sl->having= and_items(sl->having, item);
|
||||
@ -678,8 +684,12 @@ int subselect_single_select_engine::prepare()
|
||||
prepared= 1;
|
||||
SELECT_LEX_NODE *save_select= thd->lex.current_select;
|
||||
thd->lex.current_select= select_lex;
|
||||
if (join->prepare((TABLE_LIST*) select_lex->table_list.first,
|
||||
if (join->prepare(&select_lex->ref_pointer_array,
|
||||
(TABLE_LIST*) select_lex->table_list.first,
|
||||
select_lex->with_wild,
|
||||
select_lex->where,
|
||||
select_lex->order_list.elements +
|
||||
select_lex->group_list.elements,
|
||||
(ORDER*) select_lex->order_list.first,
|
||||
(ORDER*) select_lex->group_list.first,
|
||||
select_lex->having,
|
||||
|
@ -41,9 +41,22 @@ Item_sum::Item_sum(List<Item> &list)
|
||||
list.empty(); // Fields are used
|
||||
}
|
||||
|
||||
Item_sum::Item_sum(Item_sum &item):
|
||||
Item_result_field(item), quick_group(item.quick_group)
|
||||
{
|
||||
arg_count= item.arg_count;
|
||||
if (arg_count <= 2)
|
||||
args=tmp_args;
|
||||
else
|
||||
if (!(args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
|
||||
return;
|
||||
for(uint i= 0; i < arg_count; i++)
|
||||
args[i]= item.args[i];
|
||||
}
|
||||
|
||||
void Item_sum::mark_as_sum_func()
|
||||
{
|
||||
current_thd->lex.current_select->with_sum_func=1;
|
||||
current_thd->lex.current_select->with_sum_func++;
|
||||
with_sum_func= 1;
|
||||
}
|
||||
|
||||
@ -83,6 +96,26 @@ void Item_sum::fix_num_length_and_dec()
|
||||
max_length=float_length(decimals);
|
||||
}
|
||||
|
||||
Item * Item_sum::get_tmp_table_item()
|
||||
{
|
||||
Item_sum* sum_item= (Item_sum *) get_same();
|
||||
if (sum_item && sum_item->result_field) // If not a const sum func
|
||||
{
|
||||
Field *result_field= sum_item->result_field;
|
||||
for (uint i=0 ; i < sum_item->arg_count ; i++)
|
||||
{
|
||||
Item *arg= sum_item->args[i];
|
||||
if (!arg->const_item())
|
||||
{
|
||||
if (arg->type() == Item::FIELD_ITEM)
|
||||
((Item_field*) arg)->field= result_field++;
|
||||
else
|
||||
sum_item->args[i]= new Item_field(result_field++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum_item;
|
||||
}
|
||||
|
||||
String *
|
||||
Item_sum_num::val_str(String *str)
|
||||
@ -952,7 +985,7 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
||||
The first item->rec_offset bytes are taken care of with
|
||||
restore_record(table,2) in setup()
|
||||
*/
|
||||
memcpy(buf + item->rec_offset, key, item->tree.size_of_element);
|
||||
memcpy(buf + item->rec_offset, key, item->tree->size_of_element);
|
||||
if ((error = item->table->file->write_row(buf)))
|
||||
{
|
||||
if (error != HA_ERR_FOUND_DUPP_KEY &&
|
||||
@ -965,11 +998,14 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
||||
|
||||
Item_sum_count_distinct::~Item_sum_count_distinct()
|
||||
{
|
||||
if (table)
|
||||
free_tmp_table(current_thd, table);
|
||||
delete tmp_table_param;
|
||||
if (use_tree)
|
||||
delete_tree(&tree);
|
||||
if (!original)
|
||||
{
|
||||
if (table)
|
||||
free_tmp_table(current_thd, table);
|
||||
delete tmp_table_param;
|
||||
if (use_tree)
|
||||
delete_tree(tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1100,8 +1136,8 @@ bool Item_sum_count_distinct::setup(THD *thd)
|
||||
}
|
||||
}
|
||||
|
||||
init_tree(&tree, min(thd->variables.max_heap_table_size,
|
||||
thd->variables.sortbuff_size/16), 0,
|
||||
init_tree(tree, min(thd->variables.max_heap_table_size,
|
||||
thd->variables.sortbuff_size/16), 0,
|
||||
key_length, compare_key, 0, NULL, cmp_arg);
|
||||
use_tree = 1;
|
||||
|
||||
@ -1113,6 +1149,12 @@ bool Item_sum_count_distinct::setup(THD *thd)
|
||||
*/
|
||||
max_elements_in_tree = ((key_length) ?
|
||||
thd->variables.max_heap_table_size/key_length : 1);
|
||||
|
||||
}
|
||||
if (original)
|
||||
{
|
||||
original->table= table;
|
||||
original->use_tree= use_tree;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1122,10 +1164,10 @@ int Item_sum_count_distinct::tree_to_myisam()
|
||||
{
|
||||
if (create_myisam_from_heap(current_thd, table, tmp_table_param,
|
||||
HA_ERR_RECORD_FILE_FULL, 1) ||
|
||||
tree_walk(&tree, (tree_walk_action)&dump_leaf, (void*)this,
|
||||
tree_walk(tree, (tree_walk_action)&dump_leaf, (void*)this,
|
||||
left_root_right))
|
||||
return 1;
|
||||
delete_tree(&tree);
|
||||
delete_tree(tree);
|
||||
use_tree = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -1133,7 +1175,7 @@ int Item_sum_count_distinct::tree_to_myisam()
|
||||
void Item_sum_count_distinct::reset()
|
||||
{
|
||||
if (use_tree)
|
||||
reset_tree(&tree);
|
||||
reset_tree(tree);
|
||||
else if (table)
|
||||
{
|
||||
table->file->extra(HA_EXTRA_NO_CACHE);
|
||||
@ -1161,13 +1203,13 @@ bool Item_sum_count_distinct::add()
|
||||
If the tree got too big, convert to MyISAM, otherwise insert into the
|
||||
tree.
|
||||
*/
|
||||
if (tree.elements_in_tree > max_elements_in_tree)
|
||||
if (tree->elements_in_tree > max_elements_in_tree)
|
||||
{
|
||||
if (tree_to_myisam())
|
||||
return 1;
|
||||
}
|
||||
else if (!tree_insert(&tree, table->record[0] + rec_offset, 0,
|
||||
tree.custom_arg))
|
||||
else if (!tree_insert(tree, table->record[0] + rec_offset, 0,
|
||||
tree->custom_arg))
|
||||
return 1;
|
||||
}
|
||||
else if ((error=table->file->write_row(table->record[0])))
|
||||
@ -1189,7 +1231,7 @@ longlong Item_sum_count_distinct::val_int()
|
||||
if (!table) // Empty query
|
||||
return LL(0);
|
||||
if (use_tree)
|
||||
return tree.elements_in_tree;
|
||||
return tree->elements_in_tree;
|
||||
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||
return table->file->records;
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
mark_as_sum_func();
|
||||
}
|
||||
Item_sum(List<Item> &list);
|
||||
//Copy constructor, need to perform subselects with temporary tables
|
||||
Item_sum(Item_sum &item);
|
||||
~Item_sum() { result_field=0; }
|
||||
|
||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||
@ -75,6 +77,7 @@ public:
|
||||
void print(String *str);
|
||||
void fix_num_length_and_dec();
|
||||
virtual bool setup(THD *thd) {return 0;}
|
||||
Item * get_tmp_table_item();
|
||||
};
|
||||
|
||||
|
||||
@ -85,6 +88,7 @@ public:
|
||||
Item_sum_num(Item *item_par) :Item_sum(item_par) {}
|
||||
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
|
||||
Item_sum_num(List<Item> &list) :Item_sum(list) {}
|
||||
Item_sum_num(Item_sum_num &item) :Item_sum(item) {}
|
||||
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||
longlong val_int() { return (longlong) val(); } /* Real as default */
|
||||
String *val_str(String*str);
|
||||
@ -100,6 +104,7 @@ class Item_sum_int :public Item_sum_num
|
||||
public:
|
||||
Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
|
||||
Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
|
||||
Item_sum_int(Item_sum_int &item) :Item_sum_num(item) {}
|
||||
double val() { return (double) val_int(); }
|
||||
String *val_str(String*str);
|
||||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
@ -113,6 +118,7 @@ class Item_sum_sum :public Item_sum_num
|
||||
|
||||
public:
|
||||
Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {}
|
||||
Item_sum_sum(Item_sum_sum &item) :Item_sum_num(item), sum(item.sum) {}
|
||||
enum Sumfunctype sum_func () const {return SUM_FUNC;}
|
||||
void reset();
|
||||
bool add();
|
||||
@ -120,6 +126,7 @@ class Item_sum_sum :public Item_sum_num
|
||||
void reset_field();
|
||||
void update_field(int offset);
|
||||
const char *func_name() const { return "sum"; }
|
||||
Item * get_same() { return new Item_sum_sum(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -132,6 +139,10 @@ class Item_sum_count :public Item_sum_int
|
||||
Item_sum_count(Item *item_par)
|
||||
:Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
|
||||
{}
|
||||
Item_sum_count(Item_sum_count &item): Item_sum_int(item),
|
||||
count(item.count),
|
||||
used_table_cache(item.used_table_cache)
|
||||
{}
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
bool const_item() const { return !used_table_cache; }
|
||||
enum Sumfunctype sum_func () const { return COUNT_FUNC; }
|
||||
@ -142,6 +153,7 @@ class Item_sum_count :public Item_sum_int
|
||||
void reset_field();
|
||||
void update_field(int offset);
|
||||
const char *func_name() const { return "count"; }
|
||||
Item * get_same() { return new Item_sum_count(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -154,7 +166,14 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||
uint32 *field_lengths;
|
||||
TMP_TABLE_PARAM *tmp_table_param;
|
||||
TREE tree;
|
||||
TREE tree_base;
|
||||
TREE *tree;
|
||||
/*
|
||||
Following is 0 normal object and pointer to original one for copy
|
||||
(to correctly free resources)
|
||||
*/
|
||||
Item_sum_count_distinct *original;
|
||||
|
||||
uint key_length;
|
||||
CHARSET_INFO *key_charset;
|
||||
|
||||
@ -183,9 +202,19 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||
|
||||
public:
|
||||
Item_sum_count_distinct(List<Item> &list)
|
||||
:Item_sum_int(list),table(0),used_table_cache(~(table_map) 0),
|
||||
tmp_table_param(0),use_tree(0),always_null(0)
|
||||
{ quick_group=0; }
|
||||
:Item_sum_int(list), table(0), used_table_cache(~(table_map) 0),
|
||||
tmp_table_param(0), tree(&tree_base), original(0), use_tree(0),
|
||||
always_null(0)
|
||||
{ quick_group= 0; }
|
||||
Item_sum_count_distinct(Item_sum_count_distinct &item):
|
||||
Item_sum_int(item), table(item.table),
|
||||
used_table_cache(item.used_table_cache),
|
||||
field_lengths(item.field_lengths), tmp_table_param(item.tmp_table_param),
|
||||
tree(item.tree), original(&item), key_length(item.key_length),
|
||||
max_elements_in_tree(item.max_elements_in_tree),
|
||||
rec_offset(item.rec_offset), use_tree(item.use_tree),
|
||||
always_null(item.always_null)
|
||||
{}
|
||||
~Item_sum_count_distinct();
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
|
||||
@ -196,6 +225,7 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||
void update_field(int offset) { return ; } // Never called
|
||||
const char *func_name() const { return "count_distinct"; }
|
||||
bool setup(THD *thd);
|
||||
Item * get_same() { return new Item_sum_count_distinct(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -227,6 +257,8 @@ class Item_sum_avg :public Item_sum_num
|
||||
|
||||
public:
|
||||
Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
Item_sum_avg(Item_sum_avg &item)
|
||||
:Item_sum_num(item), sum(item.sum), count(item.count) {}
|
||||
enum Sumfunctype sum_func () const {return AVG_FUNC;}
|
||||
void reset();
|
||||
bool add();
|
||||
@ -236,6 +268,7 @@ class Item_sum_avg :public Item_sum_num
|
||||
Item *result_item(Field *field)
|
||||
{ return new Item_avg_field(this); }
|
||||
const char *func_name() const { return "avg"; }
|
||||
Item * get_same() { return new Item_sum_avg(*this); }
|
||||
};
|
||||
|
||||
class Item_sum_variance;
|
||||
@ -276,6 +309,9 @@ class Item_sum_variance : public Item_sum_num
|
||||
|
||||
public:
|
||||
Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
Item_sum_variance(Item_sum_variance &item):
|
||||
Item_sum_num(item), sum(item.sum), sum_sqr(item.sum_sqr),
|
||||
count(item.count) {}
|
||||
enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
|
||||
void reset();
|
||||
bool add();
|
||||
@ -285,6 +321,7 @@ class Item_sum_variance : public Item_sum_num
|
||||
Item *result_item(Field *field)
|
||||
{ return new Item_variance_field(this); }
|
||||
const char *func_name() const { return "variance"; }
|
||||
Item * get_same() { return new Item_sum_variance(*this); }
|
||||
};
|
||||
|
||||
class Item_sum_std;
|
||||
@ -295,22 +332,6 @@ public:
|
||||
Item_std_field(Item_sum_std *item);
|
||||
enum Type type() const { return FIELD_STD_ITEM; }
|
||||
double val();
|
||||
};
|
||||
|
||||
/*
|
||||
standard_deviation(a) = sqrt(variance(a))
|
||||
*/
|
||||
|
||||
class Item_sum_std :public Item_sum_variance
|
||||
{
|
||||
public:
|
||||
Item_sum_std(Item *item_par) :Item_sum_variance(item_par){}
|
||||
enum Sumfunctype sum_func () const { return STD_FUNC; }
|
||||
double val();
|
||||
Item *result_item(Field *field)
|
||||
{ return new Item_std_field(this); }
|
||||
const char *func_name() const { return "std"; }
|
||||
};
|
||||
|
||||
// This class is a string or number function depending on num_func
|
||||
|
||||
@ -329,6 +350,10 @@ class Item_sum_hybrid :public Item_sum
|
||||
Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
|
||||
used_table_cache(~(table_map) 0)
|
||||
{}
|
||||
Item_sum_hybrid(Item_sum_hybrid &item):
|
||||
Item_sum(item), value(item.value), tmp_value(item.tmp_value),
|
||||
sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type),
|
||||
cmp_sign(item.cmp_sign), used_table_cache(used_table_cache) {}
|
||||
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
bool const_item() const { return !used_table_cache; }
|
||||
@ -360,10 +385,12 @@ class Item_sum_min :public Item_sum_hybrid
|
||||
{
|
||||
public:
|
||||
Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
|
||||
Item_sum_min(Item_sum_min &item) :Item_sum_hybrid(item) {}
|
||||
enum Sumfunctype sum_func () const {return MIN_FUNC;}
|
||||
|
||||
bool add();
|
||||
const char *func_name() const { return "min"; }
|
||||
Item * get_same() { return new Item_sum_min(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -371,10 +398,12 @@ class Item_sum_max :public Item_sum_hybrid
|
||||
{
|
||||
public:
|
||||
Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
|
||||
Item_sum_max(Item_sum_max &item) :Item_sum_hybrid(item) {}
|
||||
enum Sumfunctype sum_func () const {return MAX_FUNC;}
|
||||
|
||||
bool add();
|
||||
const char *func_name() const { return "max"; }
|
||||
Item * get_same() { return new Item_sum_max(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -386,6 +415,8 @@ class Item_sum_bit :public Item_sum_int
|
||||
public:
|
||||
Item_sum_bit(Item *item_par,ulonglong reset_arg)
|
||||
:Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
|
||||
Item_sum_bit(Item_sum_bit &item):
|
||||
Item_sum_int(item), reset_bits(item.reset_bits), bits(item.bits) {}
|
||||
enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
|
||||
void reset();
|
||||
longlong val_int();
|
||||
@ -397,9 +428,11 @@ class Item_sum_or :public Item_sum_bit
|
||||
{
|
||||
public:
|
||||
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
|
||||
Item_sum_or(Item_sum_or &item) :Item_sum_bit(item) {}
|
||||
bool add();
|
||||
void update_field(int offset);
|
||||
const char *func_name() const { return "bit_or"; }
|
||||
Item * get_same() { return new Item_sum_or(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -407,9 +440,11 @@ class Item_sum_and :public Item_sum_bit
|
||||
{
|
||||
public:
|
||||
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
|
||||
Item_sum_and(Item_sum_and &item) :Item_sum_bit(item) {}
|
||||
bool add();
|
||||
void update_field(int offset);
|
||||
const char *func_name() const { return "bit_and"; }
|
||||
Item * get_same() { return new Item_sum_and(*this); }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -427,6 +462,7 @@ public:
|
||||
Item_udf_sum( udf_func *udf_arg, List<Item> &list )
|
||||
:Item_sum( list ), udf(udf_arg)
|
||||
{ quick_group=0;}
|
||||
Item_udf_sum(Item_udf_sum &item) :Item_sum(item), udf(item.udf) {}
|
||||
~Item_udf_sum() {}
|
||||
const char *func_name() const { return udf.name(); }
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
@ -450,11 +486,13 @@ class Item_sum_udf_float :public Item_udf_sum
|
||||
Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_float(Item_sum_udf_float &item): Item_udf_sum(item) {}
|
||||
~Item_sum_udf_float() {}
|
||||
longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
|
||||
double val();
|
||||
String *val_str(String*str);
|
||||
void fix_length_and_dec() { fix_num_length_and_dec(); }
|
||||
Item * get_same() { return new Item_sum_udf_float(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -464,12 +502,14 @@ public:
|
||||
Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_int(Item_sum_udf_int &item): Item_udf_sum(item) {}
|
||||
~Item_sum_udf_int() {}
|
||||
longlong val_int();
|
||||
double val() { return (double) Item_sum_udf_int::val_int(); }
|
||||
String *val_str(String*str);
|
||||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
void fix_length_and_dec() { decimals=0; max_length=21; }
|
||||
Item * get_same() { return new Item_sum_udf_int(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -479,6 +519,7 @@ public:
|
||||
Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_str(Item_sum_udf_str &item): Item_udf_sum(item) {}
|
||||
~Item_sum_udf_str() {}
|
||||
String *val_str(String *);
|
||||
double val()
|
||||
@ -496,6 +537,7 @@ public:
|
||||
}
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
void fix_length_and_dec();
|
||||
Item * get_same() { return new Item_sum_udf_str(*this); }
|
||||
};
|
||||
|
||||
#else /* Dummy functions to get sql_yacc.cc compiled */
|
||||
@ -505,12 +547,14 @@ class Item_sum_udf_float :public Item_sum_num
|
||||
public:
|
||||
Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_float(Item_sum_udf_float &item): Item_sum_num(item) {}
|
||||
~Item_sum_udf_float() {}
|
||||
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
||||
double val() { return 0.0; }
|
||||
void reset() {}
|
||||
bool add() { return 0; }
|
||||
void update_field(int offset) {}
|
||||
Item * get_same() { return new Item_sum_udf_float(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -519,6 +563,7 @@ class Item_sum_udf_int :public Item_sum_num
|
||||
public:
|
||||
Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_int(Item_sum_udf_int &item): Item_sum_num(item) {}
|
||||
~Item_sum_udf_int() {}
|
||||
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
||||
longlong val_int() { return 0; }
|
||||
@ -526,6 +571,7 @@ public:
|
||||
void reset() {}
|
||||
bool add() { return 0; }
|
||||
void update_field(int offset) {}
|
||||
Item * get_same() { return new Item_sum_udf_int(*this); }
|
||||
};
|
||||
|
||||
|
||||
@ -534,6 +580,7 @@ class Item_sum_udf_str :public Item_sum_num
|
||||
public:
|
||||
Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_str(Item_sum_udf_str &item): Item_sum_num(item) {}
|
||||
~Item_sum_udf_str() {}
|
||||
String *val_str(String *) { null_value=1; return 0; }
|
||||
double val() { null_value=1; return 0.0; }
|
||||
@ -544,6 +591,7 @@ public:
|
||||
void reset() {}
|
||||
bool add() { return 0; }
|
||||
void update_field(int offset) {}
|
||||
Item * get_same() { return new Item_sum_udf_str(*this); }
|
||||
};
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
|
@ -327,9 +327,10 @@ public:
|
||||
max_length=10*thd_charset()->mbmaxlen;
|
||||
}
|
||||
int save_in_field(Field *to, bool no_conversions);
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg, thd_charset());
|
||||
return (new Field_date(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -341,10 +342,10 @@ public:
|
||||
Item_date_func(Item *a) :Item_str_func(a) {}
|
||||
Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field : new Field_datetime(maybe_null, name,
|
||||
t_arg, thd_charset());
|
||||
return (new Field_datetime(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -364,10 +365,10 @@ public:
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "curtime"; }
|
||||
void fix_length_and_dec();
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field :
|
||||
new Field_time(maybe_null, name, t_arg, thd_charset());
|
||||
return (new Field_time(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -462,10 +463,10 @@ public:
|
||||
}
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
const char *func_name() const { return "sec_to_time"; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field :
|
||||
new Field_time(maybe_null, name, t_arg, thd_charset());
|
||||
return (new Field_time(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -556,10 +557,10 @@ public:
|
||||
Item_date_typecast(Item *a) :Item_typecast(a) {}
|
||||
const char *func_name() const { return "date"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field :
|
||||
new Field_date(maybe_null, name, t_arg, thd_charset());
|
||||
return (new Field_date(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -570,10 +571,10 @@ public:
|
||||
Item_time_typecast(Item *a) :Item_typecast(a) {}
|
||||
const char *func_name() const { return "time"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field :
|
||||
new Field_time(maybe_null, name, t_arg, thd_charset());
|
||||
return (new Field_time(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -584,9 +585,9 @@ public:
|
||||
Item_datetime_typecast(Item *a) :Item_typecast(a) {}
|
||||
const char *func_name() const { return "datetime"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (!t_arg) ? result_field : new Field_datetime(maybe_null, name,
|
||||
t_arg, thd_charset());
|
||||
return (new Field_datetime(maybe_null, name, t_arg, thd_charset()));
|
||||
}
|
||||
};
|
||||
|
@ -37,6 +37,7 @@ class Item_sum_unique_users :public Item_sum_num
|
||||
public:
|
||||
Item_sum_unique_users(Item *name_arg,int start,int end,Item *item_arg)
|
||||
:Item_sum_num(item_arg) {}
|
||||
Item_sum_unique_users(Item_sum_unique_users &item): Item_sum_num(item) {}
|
||||
double val() { return 0.0; }
|
||||
enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;}
|
||||
void reset() {}
|
||||
@ -48,4 +49,5 @@ public:
|
||||
fixed= 1;
|
||||
return 0;
|
||||
}
|
||||
Item_sum * get_same() { return new Item_sum_unique_users(*this); }
|
||||
};
|
||||
|
@ -390,18 +390,21 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
|
||||
bool check_simple_select();
|
||||
|
||||
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
|
||||
int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
|
||||
List <Item> &all_fields, ORDER *order);
|
||||
int setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||
List<Item> &all_fields, ORDER *order,
|
||||
int setup_ref_array(THD *thd, Item ***rref_pointer_array, uint elements);
|
||||
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
List<Item> &fields, List <Item> &all_fields, ORDER *order);
|
||||
int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
List<Item> &fields, List<Item> &all_fields, ORDER *order,
|
||||
bool *hidden_group_fields);
|
||||
|
||||
int handle_select(THD *thd, LEX *lex, select_result *result);
|
||||
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
|
||||
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
|
||||
ulong select_type,select_result *result,
|
||||
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
|
||||
bool fake_select_lex);
|
||||
int mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
TABLE_LIST *tables, uint wild_num, List<Item> &list,
|
||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||
Item *having, ORDER *proc_param, ulong select_type,
|
||||
select_result *result, SELECT_LEX_UNIT *unit,
|
||||
SELECT_LEX *select_lex, bool fake_select_lex);
|
||||
void free_ulderlayed_joins(THD *thd, SELECT_LEX *select);
|
||||
void fix_tables_pointers(SELECT_LEX *select_lex);
|
||||
int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
||||
select_result *result);
|
||||
@ -428,7 +431,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
ORDER *order,
|
||||
uint order_num, ORDER *order,
|
||||
bool drop_primary,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
|
||||
@ -447,7 +450,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
||||
List<Alter_drop> &drop_list);
|
||||
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||
List<Item> &values,COND *conds,
|
||||
ORDER *order, ha_rows limit,
|
||||
uint order_num, ORDER *order, ha_rows limit,
|
||||
enum enum_duplicates handle_duplicates);
|
||||
int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
|
||||
List<Item> *fields, List<Item> *values,
|
||||
@ -567,15 +570,17 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||
enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_ERRORS};
|
||||
extern const Item **not_found_item;
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items,
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
|
||||
find_item_error_report_type report_error);
|
||||
bool insert_fields(THD *thd,TABLE_LIST *tables,
|
||||
const char *db_name, const char *table_name,
|
||||
List_iterator<Item> *it);
|
||||
bool setup_tables(TABLE_LIST *tables);
|
||||
int setup_fields(THD *thd,TABLE_LIST *tables,List<Item> &item,
|
||||
bool set_query_id,List<Item> *sum_func_list,
|
||||
bool allow_sum_func);
|
||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||
List<Item> *sum_func_list, uint wild_num);
|
||||
int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
||||
List<Item> &item, bool set_query_id,
|
||||
List<Item> *sum_func_list, bool allow_sum_func);
|
||||
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
||||
int setup_ftfuncs(SELECT_LEX* select);
|
||||
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
|
||||
|
@ -1807,11 +1807,15 @@ const Item **not_found_item= (const Item**) 0x1;
|
||||
|
||||
/*
|
||||
Find Item in list of items (find_field_in_tables analog)
|
||||
|
||||
|
||||
TODO
|
||||
is it better return only counter?
|
||||
|
||||
SYNOPSIS
|
||||
find_item_in_list()
|
||||
find - item to find
|
||||
items - list of items
|
||||
counter - to return number of found item
|
||||
report_error
|
||||
REPORT_ALL_ERRORS - report errors, return 0 if error
|
||||
REPORT_EXCEPT_NOT_FOUND - do not report 'not found' error and return not_ found_item, report other errors, return 0
|
||||
@ -1828,7 +1832,7 @@ const Item **not_found_item= (const Item**) 0x1;
|
||||
*/
|
||||
|
||||
Item **
|
||||
find_item_in_list(Item *find, List<Item> &items,
|
||||
find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
||||
find_item_error_report_type report_error)
|
||||
{
|
||||
List_iterator<Item> li(items);
|
||||
@ -1841,8 +1845,10 @@ find_item_in_list(Item *find, List<Item> &items,
|
||||
table_name= ((Item_ident*) find)->table_name;
|
||||
}
|
||||
|
||||
uint i= 0;
|
||||
while ((item=li++))
|
||||
{
|
||||
i++;
|
||||
if (field_name && item->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
if (!my_strcasecmp(system_charset_info,
|
||||
@ -1859,11 +1865,13 @@ find_item_in_list(Item *find, List<Item> &items,
|
||||
find->full_name(), current_thd->where);
|
||||
return (Item**) 0;
|
||||
}
|
||||
found=li.ref();
|
||||
found= li.ref();
|
||||
*counter= i;
|
||||
}
|
||||
else if (!strcmp(((Item_field*) item)->table_name,table_name))
|
||||
{
|
||||
found=li.ref();
|
||||
found= li.ref();
|
||||
*counter= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1873,7 +1881,8 @@ find_item_in_list(Item *find, List<Item> &items,
|
||||
!my_strcasecmp(system_charset_info,
|
||||
item->name,find->name)))
|
||||
{
|
||||
found=li.ref();
|
||||
found= li.ref();
|
||||
*counter= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1891,30 +1900,26 @@ find_item_in_list(Item *find, List<Item> &items,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** Check that all given fields exists and fill struct with current data
|
||||
** Expand all '*' in given fields
|
||||
****************************************************************************/
|
||||
|
||||
int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||
bool set_query_id, List<Item> *sum_func_list,
|
||||
bool allow_sum_func)
|
||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||
List<Item> *sum_func_list,
|
||||
uint wild_num)
|
||||
{
|
||||
if (!wild_num)
|
||||
return 0;
|
||||
reg2 Item *item;
|
||||
List_iterator<Item> it(fields);
|
||||
DBUG_ENTER("setup_fields");
|
||||
|
||||
thd->set_query_id=set_query_id;
|
||||
thd->allow_sum_func= allow_sum_func;
|
||||
thd->where="field list";
|
||||
|
||||
while ((item=it++))
|
||||
{
|
||||
while ( wild_num && (item= it++))
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name &&
|
||||
((Item_field*) item)->field_name[0] == '*')
|
||||
{
|
||||
uint elem= fields.elements;
|
||||
if (insert_fields(thd,tables,((Item_field*) item)->db_name,
|
||||
((Item_field*) item)->table_name, &it))
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
return (-1);
|
||||
if (sum_func_list)
|
||||
{
|
||||
/*
|
||||
@ -1924,22 +1929,44 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||
*/
|
||||
sum_func_list->elements+= fields.elements - elem;
|
||||
}
|
||||
wild_num--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->fix_fields(thd, tables, it.ref()) || item->check_cols(1))
|
||||
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 &&
|
||||
sum_func_list)
|
||||
item->split_sum_func(*sum_func_list);
|
||||
thd->used_tables|=item->used_tables();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** Check that all given fields exists and fill struct with current data
|
||||
****************************************************************************/
|
||||
|
||||
int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
List<Item> &fields, bool set_query_id,
|
||||
List<Item> *sum_func_list, bool allow_sum_func)
|
||||
{
|
||||
reg2 Item *item;
|
||||
List_iterator<Item> it(fields);
|
||||
DBUG_ENTER("setup_fields");
|
||||
|
||||
thd->set_query_id=set_query_id;
|
||||
thd->allow_sum_func= allow_sum_func;
|
||||
thd->where="field list";
|
||||
|
||||
for (uint i= 0; (item= it++); i++)
|
||||
{
|
||||
if (item->fix_fields(thd, tables, it.ref()) ||
|
||||
item->check_cols(1))
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
item= *(it.ref()); //Item can be chenged in fix fields
|
||||
if (ref_pointer_array)
|
||||
ref_pointer_array[i]= item;
|
||||
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
|
||||
sum_func_list)
|
||||
item->split_sum_func(ref_pointer_array, *sum_func_list);
|
||||
thd->used_tables|=item->used_tables();
|
||||
}
|
||||
DBUG_RETURN(test(thd->fatal_error || thd->net.report_error));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Remap table numbers if INSERT ... SELECT
|
||||
Check also that the 'used keys' and 'ignored keys' exists and set up the
|
||||
@ -2254,7 +2281,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
||||
create_info.table_charset=default_charset_info;
|
||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list,
|
||||
fields, keys, drop, alter, (ORDER*)0, FALSE,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0, FALSE,
|
||||
DUP_ERROR));
|
||||
}
|
||||
|
||||
@ -2271,7 +2298,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
|
||||
create_info.table_charset=default_charset_info;
|
||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list,
|
||||
fields, keys, drop, alter, (ORDER*)0, FALSE,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0, FALSE,
|
||||
DUP_ERROR));
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ struct system_variables
|
||||
CHARSET_INFO *thd_charset;
|
||||
};
|
||||
|
||||
|
||||
void free_tmp_table(THD *thd, TABLE *entry);
|
||||
/*
|
||||
For each client connection we create a separate thread with THD serving as
|
||||
a thread/connection descriptor
|
||||
@ -507,6 +507,7 @@ public:
|
||||
USER_CONN *user_connect;
|
||||
CHARSET_INFO *db_charset;
|
||||
List<Item> *possible_loops; // Items that may cause loops in subselects
|
||||
List<TABLE> temporary_tables_should_be_free; // list of temporary tables
|
||||
List <MYSQL_ERROR> warn_list;
|
||||
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
||||
uint total_warn_count, old_total_warn_count;
|
||||
@ -662,6 +663,17 @@ public:
|
||||
#endif
|
||||
|
||||
void add_possible_loop(Item *);
|
||||
void free_tmp_tables()
|
||||
{
|
||||
if (temporary_tables_should_be_free.elements)
|
||||
{
|
||||
List_iterator_fast<TABLE> lt(temporary_tables_should_be_free);
|
||||
TABLE *table;
|
||||
while ((table= lt++))
|
||||
free_tmp_table(this,table);
|
||||
temporary_tables_should_be_free.empty();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -92,6 +92,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
|
||||
if ((select && select->check_quick(safe_update, limit)) || !limit)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
send_ok(thd,0L);
|
||||
DBUG_RETURN(0); // Nothing to delete
|
||||
}
|
||||
@ -103,6 +104,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
|
||||
if (safe_update && !using_limit)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -124,7 +126,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
|
||||
|
||||
table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
if (setup_order(thd, &tables, fields, all_fields, order) ||
|
||||
if (setup_order(thd, 0, &tables, fields, all_fields, order) ||
|
||||
!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
(table->found_records = filesort(thd, table, sortorder, length,
|
||||
(SQL_SELECT *) 0, HA_POS_ERROR,
|
||||
@ -132,6 +134,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
|
||||
== HA_POS_ERROR)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1); // This will force out message
|
||||
}
|
||||
}
|
||||
@ -207,6 +210,7 @@ cleanup:
|
||||
thd->lock=0;
|
||||
}
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
if (error >= 0 || thd->net.report_error)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
|
||||
else
|
||||
|
@ -99,21 +99,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
|
||||
if (!(res=open_and_lock_tables(thd,tables)))
|
||||
{
|
||||
if (is_union)
|
||||
{
|
||||
/*
|
||||
The following code is a re-do of fix_tables_pointers() found
|
||||
in sql_select.cc for UNION's within derived tables. The only
|
||||
difference is in navigation, as in derived tables we care for
|
||||
this level only.
|
||||
|
||||
*/
|
||||
for (SELECT_LEX *sel= sl; sel; sel= sel->next_select())
|
||||
relink_tables(sel);
|
||||
}
|
||||
|
||||
lex->current_select= sl;
|
||||
if (setup_fields(thd,tables,item_list,0,0,1))
|
||||
if (setup_wild(thd, tables, item_list, 0, sl->with_wild) ||
|
||||
setup_fields(thd, 0, tables, item_list, 0, 0, 1))
|
||||
{
|
||||
res= -1;
|
||||
goto exit;
|
||||
@ -144,12 +131,14 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
if (is_union)
|
||||
res= mysql_union(thd,lex,derived_result,unit);
|
||||
else
|
||||
res= mysql_select(thd, tables, sl->item_list,
|
||||
sl->where, (ORDER *) sl->order_list.first,
|
||||
(ORDER*) sl->group_list.first,
|
||||
sl->having, (ORDER*) NULL,
|
||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||
derived_result, unit, sl, 0);
|
||||
res= mysql_select(thd, &sl->ref_pointer_array, tables, sl->with_wild,
|
||||
sl->item_list, sl->where,
|
||||
sl->order_list.elements+sl->group_list.elements,
|
||||
(ORDER *) sl->order_list.first,
|
||||
(ORDER *) sl->group_list.first,
|
||||
sl->having, (ORDER*) NULL,
|
||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||
derived_result, unit, sl, 0);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
@ -181,12 +170,12 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
delete derived_result;
|
||||
}
|
||||
if (res)
|
||||
free_tmp_table(thd, table);
|
||||
else
|
||||
{
|
||||
table->next= thd->derived_tables;
|
||||
thd->derived_tables= table;
|
||||
}
|
||||
mp_table(thd, table);
|
||||
|
||||
|
||||
>next= thd->derived_tables
|
||||
erived_tables= table;
|
||||
|
||||
exit:
|
||||
lex->current_select= save_current_select;
|
||||
close_thread_tables(thd, 0, 1);
|
||||
|
@ -25,7 +25,7 @@ int mysql_do(THD *thd, List<Item> &values)
|
||||
List_iterator<Item> li(values);
|
||||
Item *value;
|
||||
DBUG_ENTER("mysql_do");
|
||||
if (setup_fields(thd,0, values, 0, 0, 0))
|
||||
if (setup_fields(thd, 0, 0, values, 0, 0, 0))
|
||||
DBUG_RETURN(-1);
|
||||
while ((value = li++))
|
||||
value->val_int();
|
||||
|
@ -81,7 +81,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
|
||||
|
||||
thd->dupp_field=0;
|
||||
if (setup_tables(&table_list) ||
|
||||
setup_fields(thd,&table_list,fields,1,0,0))
|
||||
setup_fields(thd, 0, &table_list,fields,1,0,0))
|
||||
return -1;
|
||||
if (thd->dupp_field)
|
||||
{
|
||||
@ -171,10 +171,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
values= its++;
|
||||
if (check_insert_fields(thd,table,fields,*values,1) ||
|
||||
setup_tables(insert_table_list) ||
|
||||
setup_fields(thd, insert_table_list, *values, 0, 0, 0) ||
|
||||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
|
||||
(duplic == DUP_UPDATE &&
|
||||
(setup_fields(thd, insert_table_list, update_fields, 0, 0, 0) ||
|
||||
setup_fields(thd, insert_table_list, update_values, 0, 0, 0))))
|
||||
(setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) ||
|
||||
setup_fields(thd, 0, insert_table_list, update_values, 0, 0, 0))))
|
||||
goto abort;
|
||||
if (find_real_table_in_list(table_list->next,
|
||||
table_list->db, table_list->real_name))
|
||||
@ -194,7 +194,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
MYF(0),counter);
|
||||
goto abort;
|
||||
}
|
||||
if (setup_fields(thd,insert_table_list,*values,0,0,0))
|
||||
if (setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0))
|
||||
goto abort;
|
||||
}
|
||||
its.rewind ();
|
||||
@ -376,11 +376,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->cuted_fields);
|
||||
::send_ok(thd,info.copied+info.deleted,(ulonglong)id,buff);
|
||||
}
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(0);
|
||||
|
||||
abort:
|
||||
if (lock_type == TL_WRITE_DELAYED)
|
||||
end_delayed_insert(thd);
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
|
@ -996,6 +996,7 @@ int yylex(void *arg, void *yythd)
|
||||
void st_select_lex_node::init_query()
|
||||
{
|
||||
no_table_names_allowed= dependent= 0;
|
||||
ref_pointer_array= 0;
|
||||
}
|
||||
|
||||
void st_select_lex_node::init_select()
|
||||
@ -1019,6 +1020,8 @@ void st_select_lex_unit::init_query()
|
||||
union_option= 0;
|
||||
prepared= optimized= executed= 0;
|
||||
item= 0;
|
||||
union_result= 0;
|
||||
table= 0;
|
||||
}
|
||||
|
||||
void st_select_lex::init_query()
|
||||
@ -1031,6 +1034,7 @@ void st_select_lex::init_query()
|
||||
join= 0;
|
||||
olap= UNSPECIFIED_OLAP_TYPE;
|
||||
having_fix_field= 0;
|
||||
with_wild= 0;
|
||||
}
|
||||
|
||||
void st_select_lex::init_select()
|
||||
@ -1160,12 +1164,12 @@ bool st_select_lex_node::add_item_to_list(THD *thd, Item *item)
|
||||
|
||||
bool st_select_lex_node::add_group_to_list(THD *thd, Item *item, bool asc)
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool st_select_lex_node::add_order_to_list(THD *thd, Item *item, bool asc)
|
||||
{
|
||||
return add_to_list(thd, order_list,item,asc);
|
||||
{
|
||||
return add_to_list(thd, order_list, item, asc);
|
||||
}
|
||||
|
||||
bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func)
|
||||
|
@ -210,8 +210,11 @@ public:
|
||||
List<List_item> expr_list;
|
||||
List<List_item> when_list; /* WHEN clause (expression) */
|
||||
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
|
||||
bool with_sum_func;
|
||||
bool create_refs;
|
||||
// Arrays of pointers to top elements of all_fields list
|
||||
Item **ref_pointer_array;
|
||||
|
||||
uint with_sum_func; /* sum function indicator and number of it */
|
||||
bool create_refs;
|
||||
bool dependent; /* dependent from outer select subselect */
|
||||
bool no_table_names_allowed; /* used for global order by */
|
||||
|
||||
@ -274,11 +277,10 @@ class select_union;
|
||||
class st_select_lex_unit: public st_select_lex_node {
|
||||
protected:
|
||||
List<Item> item_list;
|
||||
List<JOIN*> joins; /* list of *JOINs, to delete it in cleanup() */
|
||||
TABLE_LIST result_table_list;
|
||||
select_union *union_result;
|
||||
TABLE *table; /* temporary table using for appending UNION results */
|
||||
THD *thd;
|
||||
|
||||
select_result *result;
|
||||
int res;
|
||||
bool describe, found_rows_for_union,
|
||||
@ -295,6 +297,8 @@ public:
|
||||
ha_rows select_limit_cnt, offset_limit_cnt;
|
||||
/* not NULL if union used in subselect, point to subselect item */
|
||||
Item_subselect *item;
|
||||
THD *thd;
|
||||
|
||||
uint union_option;
|
||||
|
||||
void init_query();
|
||||
@ -342,6 +346,7 @@ public:
|
||||
ulong table_join_options;
|
||||
uint in_sum_expr;
|
||||
uint select_number; /* number of select (used for EXPLAIN) */
|
||||
uint with_wild; /* item list contain '*' */
|
||||
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
|
||||
/* TRUE when having fix field called in processing of this SELECT */
|
||||
bool having_fix_field;
|
||||
|
@ -155,12 +155,20 @@ protected:
|
||||
|
||||
class base_list_iterator
|
||||
{
|
||||
protected:
|
||||
base_list *list;
|
||||
list_node **el,**prev,*current;
|
||||
void sublist(base_list &ls, uint elm)
|
||||
{
|
||||
ls.first= *el;
|
||||
ls.last= list->last;
|
||||
ls.elements= elm;
|
||||
}
|
||||
public:
|
||||
base_list_iterator(base_list &list_par) :list(&list_par),el(&list_par.first),
|
||||
prev(0),current(0)
|
||||
base_list_iterator(base_list &list_par)
|
||||
:list(&list_par), el(&list_par.first), prev(0), current(0)
|
||||
{}
|
||||
|
||||
inline void *next(void)
|
||||
{
|
||||
prev=el;
|
||||
@ -220,7 +228,6 @@ public:
|
||||
friend class error_list_iterator;
|
||||
};
|
||||
|
||||
|
||||
template <class T> class List :public base_list
|
||||
{
|
||||
public:
|
||||
@ -268,6 +275,10 @@ public:
|
||||
List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
|
||||
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
|
||||
inline void rewind(void) { base_list_iterator::rewind(); }
|
||||
void sublist(List<T> &list, uint el)
|
||||
{
|
||||
base_list_iterator::sublist(list, el);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -119,7 +119,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
else
|
||||
{ // Part field list
|
||||
thd->dupp_field=0;
|
||||
if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0))
|
||||
if (setup_tables(table_list) ||
|
||||
setup_fields(thd, 0, table_list, fields, 1, 0, 0))
|
||||
DBUG_RETURN(-1);
|
||||
if (thd->dupp_field)
|
||||
{
|
||||
|
@ -164,8 +164,10 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
|
||||
|
||||
|
||||
if (setup_tables((TABLE_LIST *)select_lex->table_list.first) ||
|
||||
setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,select_lex->item_list,1,&all_fields,1) ||
|
||||
setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,item_list_copy,1,&all_fields,1))
|
||||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||
select_lex->item_list, 1, &all_fields,1) ||
|
||||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||
item_list_copy, 1, &all_fields, 1))
|
||||
return -1;
|
||||
|
||||
if (select_lex->olap == CUBE_TYPE)
|
||||
|
@ -2041,6 +2041,7 @@ mysql_execute_command(THD *thd)
|
||||
&lex->create_info,
|
||||
tables, lex->create_list,
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->drop_primary, lex->duplicates,
|
||||
lex->alter_keys_onoff, lex->simple_alter);
|
||||
@ -2154,8 +2155,8 @@ mysql_execute_command(THD *thd)
|
||||
res= mysql_alter_table(thd, NullS, NullS, &create_info,
|
||||
tables, lex->create_list,
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
(ORDER *) 0,
|
||||
0,DUP_ERROR);
|
||||
0, (ORDER *) 0,
|
||||
0, DUP_ERROR);
|
||||
}
|
||||
else
|
||||
res = mysql_optimize_table(thd, tables, &lex->check_opt);
|
||||
@ -2175,6 +2176,7 @@ mysql_execute_command(THD *thd)
|
||||
select_lex->item_list,
|
||||
lex->value_list,
|
||||
select_lex->where,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
select_lex->select_limit,
|
||||
lex->duplicates);
|
||||
@ -2376,10 +2378,12 @@ mysql_execute_command(THD *thd)
|
||||
if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables,
|
||||
table_count)))
|
||||
{
|
||||
res= mysql_select(thd,select_lex->get_table_list(),
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
select_lex->get_table_list(),
|
||||
select_lex->with_wild,
|
||||
select_lex->item_list,
|
||||
select_lex->where,
|
||||
(ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
|
||||
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
|
||||
(ORDER *)NULL,
|
||||
select_lex->options | thd->options |
|
||||
SELECT_NO_JOIN_CACHE,
|
||||
@ -2883,6 +2887,7 @@ mysql_execute_command(THD *thd)
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
thd->free_tmp_tables();
|
||||
thd->proc_info="query end"; // QQ
|
||||
if (res < 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
@ -3130,6 +3135,7 @@ mysql_init_query(THD *thd)
|
||||
LEX *lex=&thd->lex;
|
||||
lex->unit.init_query();
|
||||
lex->unit.init_select();
|
||||
lex->unit.thd= thd;
|
||||
lex->select_lex.init_query();
|
||||
lex->value_list.empty();
|
||||
lex->param_list.empty();
|
||||
@ -3191,6 +3197,7 @@ mysql_new_select(LEX *lex, bool move_down)
|
||||
return 1;
|
||||
unit->init_query();
|
||||
unit->init_select();
|
||||
unit->thd= lex->thd;
|
||||
unit->include_down(lex->current_select);
|
||||
unit->link_next= 0;
|
||||
unit->link_prev= 0;
|
||||
|
@ -437,6 +437,7 @@ static bool setup_params_data(PREP_STMT *stmt)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Validate the following information for INSERT statement:
|
||||
- field existance
|
||||
- fields count
|
||||
@ -504,8 +505,9 @@ static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0) ||
|
||||
setup_conds(thd,table_list,&conds) || thd->net.report_error)
|
||||
if (setup_tables(table_list) ||
|
||||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
|
||||
setup_conds(thd, table_list, &conds) || thd->net.report_error)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -119,8 +119,10 @@ class TMP_TABLE_PARAM :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
List<Item> copy_funcs;
|
||||
List<Item> save_copy_funcs;
|
||||
List_iterator_fast<Item> copy_funcs_it;
|
||||
Copy_field *copy_field, *copy_field_end;
|
||||
Copy_field *save_copy_field, *save_copy_field_end;
|
||||
byte *group_buff;
|
||||
Item_result_field **funcs;
|
||||
MI_COLUMNDEF *recinfo,*start_recinfo;
|
||||
@ -166,10 +168,13 @@ class JOIN :public Sql_alloc
|
||||
List<Item> *fields;
|
||||
List<Item_buff> group_fields;
|
||||
TABLE *tmp_table;
|
||||
// used to store 2 possible tmp table of SELECT
|
||||
TABLE *exec_tmp_table1, *exec_tmp_table2;
|
||||
THD *thd;
|
||||
Item_sum **sum_funcs;
|
||||
Procedure *procedure;
|
||||
Item *having;
|
||||
Item *tmp_having; // To store Having when processed tenporary table
|
||||
uint select_options;
|
||||
select_result *result;
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
@ -178,6 +183,8 @@ class JOIN :public Sql_alloc
|
||||
SELECT_LEX_UNIT *unit;
|
||||
// select that processed
|
||||
SELECT_LEX *select_lex;
|
||||
|
||||
JOIN *tmp_join; // copy of this JOIN to be used with temporary tables
|
||||
|
||||
bool select_distinct, //Is select distinct?
|
||||
no_order, simple_order, simple_group,
|
||||
@ -186,7 +193,11 @@ class JOIN :public Sql_alloc
|
||||
buffer_result;
|
||||
DYNAMIC_ARRAY keyuse;
|
||||
Item::cond_result cond_value;
|
||||
List<Item> all_fields;
|
||||
List<Item> all_fields; // to store all fields that used in query
|
||||
//Above list changed to use temporary table
|
||||
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
|
||||
//Part, shared with list above, emulate following list
|
||||
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
|
||||
List<Item> & fields_list; // hold field list passed to mysql_select
|
||||
int error;
|
||||
|
||||
@ -194,11 +205,14 @@ class JOIN :public Sql_alloc
|
||||
COND *conds; // ---"---
|
||||
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_selec
|
||||
SQL_SELECT *select; //created in optimisation phase
|
||||
TABLE *exec_tmp_table; //used in 'exec' to hold temporary
|
||||
|
||||
Item **ref_pointer_array; //used pointer reference for this select
|
||||
// Copy of above to be used with different lists
|
||||
Item **items0, **items1, **items2, **items3;
|
||||
uint ref_pointer_array_size; // size of above in bytes
|
||||
const char *zero_result_cause; // not 0 if exec must return zero result
|
||||
|
||||
my_bool union_part; // this subselect is part of union
|
||||
bool union_part; // this subselect is part of union
|
||||
bool optimized; // flag to avoid double optimization in EXPLAIN
|
||||
|
||||
JOIN(THD *thd, List<Item> &fields,
|
||||
ulong select_options, select_result *result):
|
||||
@ -208,14 +222,16 @@ class JOIN :public Sql_alloc
|
||||
sort_and_group(0), first_record(0),
|
||||
do_send_rows(1),
|
||||
send_records(0), found_records(0), examined_rows(0),
|
||||
exec_tmp_table1(0), exec_tmp_table2(0),
|
||||
thd(thd),
|
||||
sum_funcs(0),
|
||||
procedure(0),
|
||||
having(0),
|
||||
having(0), tmp_having(0),
|
||||
select_options(select_options),
|
||||
result(result),
|
||||
lock(thd->lock),
|
||||
select_lex(0), //for safety
|
||||
tmp_join(0),
|
||||
select_distinct(test(select_options & SELECT_DISTINCT)),
|
||||
no_order(0), simple_order(0), simple_group(0), skip_sort_order(0),
|
||||
need_tmp(0),
|
||||
@ -226,8 +242,10 @@ class JOIN :public Sql_alloc
|
||||
fields_list(fields),
|
||||
error(0),
|
||||
select(0),
|
||||
exec_tmp_table(0),
|
||||
zero_result_cause(0)
|
||||
ref_pointer_array(0), items0(0), items1(0), items2(0), items3(0),
|
||||
ref_pointer_array_size(0),
|
||||
zero_result_cause(0),
|
||||
optimized(0)
|
||||
{
|
||||
fields_list = fields;
|
||||
bzero((char*) &keyuse,sizeof(keyuse));
|
||||
@ -235,16 +253,23 @@ class JOIN :public Sql_alloc
|
||||
tmp_table_param.end_write_records= HA_POS_ERROR;
|
||||
}
|
||||
|
||||
int prepare(TABLE_LIST *tables,
|
||||
COND *conds, ORDER *order, ORDER *group, Item *having,
|
||||
ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit,
|
||||
bool fake_select_lex);
|
||||
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||
Item *having, ORDER *proc_param, SELECT_LEX *select,
|
||||
SELECT_LEX_UNIT *unit, bool fake_select_lex);
|
||||
int optimize();
|
||||
int global_optimize();
|
||||
int reinit();
|
||||
void exec();
|
||||
int cleanup(THD *thd);
|
||||
bool check_loop(uint id);
|
||||
void restore_tmp();
|
||||
|
||||
inline void init_items_ref_array()
|
||||
{
|
||||
items0= ref_pointer_array + all_fields.elements;
|
||||
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
|
||||
memcpy(items0, ref_pointer_array, ref_pointer_array_size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -263,7 +288,10 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
void free_tmp_table(THD *thd, TABLE *entry);
|
||||
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||
bool reset_with_sum_func);
|
||||
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,List<Item> &fields);
|
||||
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
Item **ref_pointer_array,
|
||||
List<Item> &new_list1, List<Item> &new_list2,
|
||||
uint elements, List<Item> &fields);
|
||||
void copy_fields(TMP_TABLE_PARAM *param);
|
||||
void copy_funcs(Item_result_field **func_ptr);
|
||||
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
||||
|
@ -36,7 +36,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
|
||||
static int copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
List<create_field> &create,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
ORDER *order,
|
||||
uint order_num, ORDER *order,
|
||||
ha_rows *copied,ha_rows *deleted);
|
||||
|
||||
/*****************************************************************************
|
||||
@ -1572,7 +1572,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
ORDER *order,
|
||||
uint order_num, ORDER *order,
|
||||
bool drop_primary,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
@ -2034,7 +2034,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (!new_table->is_view)
|
||||
error=copy_data_between_tables(table,new_table,create_list,
|
||||
handle_duplicates,
|
||||
order, &copied, &deleted);
|
||||
order_num, order, &copied, &deleted);
|
||||
thd->last_insert_id=next_insert_id; // Needed for correct log
|
||||
thd->count_cuted_fields=0; // Don`t calc cuted fields
|
||||
new_table->time_stamp=save_time_stamp;
|
||||
@ -2244,7 +2244,7 @@ static int
|
||||
copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
List<create_field> &create,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
ORDER *order,
|
||||
uint order_num, ORDER *order,
|
||||
ha_rows *copied,
|
||||
ha_rows *deleted)
|
||||
{
|
||||
@ -2292,7 +2292,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
tables.db = from->table_cache_key;
|
||||
error=1;
|
||||
|
||||
if (setup_order(thd, &tables, fields, all_fields, order) ||
|
||||
if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
|
||||
order_num)||
|
||||
setup_order(thd, thd->lex.select_lex.ref_pointer_array,
|
||||
&tables, fields, all_fields, order) ||
|
||||
!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
(from->found_records = filesort(thd, from, sortorder, length,
|
||||
(SQL_SELECT *) 0, HA_POS_ERROR,
|
||||
|
@ -107,7 +107,6 @@ bool select_union::flush()
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef JOIN * JOIN_P;
|
||||
int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
||||
{
|
||||
DBUG_ENTER("st_select_lex_unit::prepare");
|
||||
@ -115,11 +114,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
||||
if (prepared)
|
||||
DBUG_RETURN(0);
|
||||
prepared= 1;
|
||||
union_result=0;
|
||||
res= 0;
|
||||
found_rows_for_union= 0;
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
this->thd= thd;
|
||||
this->result= result;
|
||||
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
|
||||
SELECT_LEX *sl;
|
||||
@ -143,7 +140,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
||||
while ((item= it++))
|
||||
if (item_list.push_back(item))
|
||||
goto err;
|
||||
if (setup_fields(thd,first_table,item_list,0,0,1))
|
||||
if (setup_wild(thd, first_table, item_list, 0,
|
||||
first_select()->with_wild) ||
|
||||
setup_fields(thd, 0, first_table, item_list, 0, 0, 1))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -169,13 +168,11 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
||||
union_result->tmp_table_param=&tmp_table_param;
|
||||
|
||||
// prepare selects
|
||||
joins.empty();
|
||||
for (sl= first_select(); sl; sl= sl->next_select())
|
||||
{
|
||||
JOIN *join= new JOIN(thd, sl->item_list,
|
||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||
union_result);
|
||||
joins.push_back(new JOIN_P(join));
|
||||
thd->lex.current_select= sl;
|
||||
offset_limit_cnt= sl->offset_limit;
|
||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
||||
@ -184,8 +181,11 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
||||
if (select_limit_cnt == HA_POS_ERROR)
|
||||
sl->options&= ~OPTION_FOUND_ROWS;
|
||||
|
||||
res= join->prepare((TABLE_LIST*) sl->table_list.first,
|
||||
res= join->prepare(&sl->ref_pointer_array,
|
||||
(TABLE_LIST*) sl->table_list.first, sl->with_wild,
|
||||
sl->where,
|
||||
((sl->braces) ? sl->order_list.elements : 0) +
|
||||
sl->group_list.elements,
|
||||
(sl->braces) ?
|
||||
(ORDER *)sl->order_list.first : (ORDER *) 0,
|
||||
(ORDER*) sl->group_list.first,
|
||||
@ -287,8 +287,9 @@ int st_select_lex_unit::exec()
|
||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||
if (select_limit_cnt == HA_POS_ERROR)
|
||||
thd->options&= ~OPTION_FOUND_ROWS;
|
||||
res= mysql_select(thd,&result_table_list,
|
||||
item_list, NULL,
|
||||
res= mysql_select(thd, &ref_pointer_array, &result_table_list,
|
||||
0, item_list, NULL,
|
||||
global_parameters->order_list.elements,
|
||||
(ORDER*)global_parameters->order_list.first,
|
||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||
thd->options, result, this, first_select(), 1);
|
||||
@ -304,20 +305,24 @@ int st_select_lex_unit::exec()
|
||||
int st_select_lex_unit::cleanup()
|
||||
{
|
||||
DBUG_ENTER("st_select_lex_unit::cleanup");
|
||||
|
||||
int error= 0;
|
||||
|
||||
if (union_result)
|
||||
{
|
||||
delete union_result;
|
||||
free_tmp_table(thd,table);
|
||||
if (table)
|
||||
free_tmp_table(thd, table);
|
||||
table= 0; // Safety
|
||||
}
|
||||
List_iterator<JOIN*> j(joins);
|
||||
JOIN** join;
|
||||
while ((join= j++))
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
{
|
||||
(*join)->cleanup(thd);
|
||||
delete *join;
|
||||
delete join;
|
||||
JOIN *join;
|
||||
if ((join= sl->join))
|
||||
{
|
||||
error|= sl->join->cleanup(thd);
|
||||
delete join;
|
||||
}
|
||||
}
|
||||
joins.empty();
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ int mysql_update(THD *thd,
|
||||
List<Item> &fields,
|
||||
List<Item> &values,
|
||||
COND *conds,
|
||||
ORDER *order,
|
||||
uint order_num, ORDER *order,
|
||||
ha_rows limit,
|
||||
enum enum_duplicates handle_duplicates)
|
||||
{
|
||||
@ -109,7 +109,7 @@ int mysql_update(THD *thd,
|
||||
|
||||
/* Check the fields we are going to modify */
|
||||
table->grant.want_privilege=want_privilege;
|
||||
if (setup_fields(thd,update_table_list,fields,1,0,0))
|
||||
if (setup_fields(thd, 0, update_table_list, fields, 1, 0, 0))
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
if (table->timestamp_field)
|
||||
{
|
||||
@ -122,8 +122,9 @@ int mysql_update(THD *thd,
|
||||
|
||||
/* Check values */
|
||||
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
|
||||
if (setup_fields(thd,update_table_list,values,0,0,0))
|
||||
if (setup_fields(thd, 0, update_table_list, values, 0, 0, 0))
|
||||
{
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
@ -134,6 +135,7 @@ int mysql_update(THD *thd,
|
||||
(select && select->check_quick(safe_update, limit)) || !limit)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
if (error)
|
||||
{
|
||||
DBUG_RETURN(-1); // Error in where
|
||||
@ -148,6 +150,7 @@ int mysql_update(THD *thd,
|
||||
if (safe_update && !using_limit)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -175,6 +178,7 @@ int mysql_update(THD *thd,
|
||||
DISK_BUFFER_SIZE, MYF(MY_WME)))
|
||||
{
|
||||
delete select; /* purecov: inspected */
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (old_used_keys & ((key_map) 1 << used_index))
|
||||
@ -197,7 +201,10 @@ int mysql_update(THD *thd,
|
||||
|
||||
table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
if (setup_order(thd, &tables, fields, all_fields, order) ||
|
||||
if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
|
||||
order_num)||
|
||||
setup_order(thd, thd->lex.select_lex.ref_pointer_array,
|
||||
&tables, fields, all_fields, order) ||
|
||||
!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
(table->found_records = filesort(thd, table, sortorder, length,
|
||||
(SQL_SELECT *) 0,
|
||||
@ -205,6 +212,7 @@ int mysql_update(THD *thd,
|
||||
== HA_POS_ERROR)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
@ -259,6 +267,7 @@ int mysql_update(THD *thd,
|
||||
if (error >= 0)
|
||||
{
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
@ -344,6 +353,7 @@ int mysql_update(THD *thd,
|
||||
}
|
||||
|
||||
delete select;
|
||||
free_ulderlayed_joins(thd, &thd->lex.select_lex);
|
||||
if (error >= 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
|
||||
else
|
||||
@ -358,6 +368,7 @@ int mysql_update(THD *thd,
|
||||
}
|
||||
thd->count_cuted_fields=0; /* calc cuted fields */
|
||||
free_io_cache(table);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -389,7 +400,7 @@ int mysql_multi_update(THD *thd,
|
||||
DBUG_RETURN(res);
|
||||
|
||||
thd->select_limit=HA_POS_ERROR;
|
||||
if (setup_fields(thd, table_list, *fields, 1, 0, 0))
|
||||
if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
@ -412,8 +423,9 @@ int mysql_multi_update(THD *thd,
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
List<Item> total_list;
|
||||
res= mysql_select(thd,table_list,total_list,
|
||||
conds, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
table_list, select_lex->with_wild, total_list,
|
||||
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
|
||||
(ORDER *)NULL,
|
||||
options | SELECT_NO_JOIN_CACHE,
|
||||
result, unit, select_lex, 0);
|
||||
@ -466,7 +478,7 @@ int multi_update::prepare(List<Item> ¬_used_values, SELECT_LEX_UNIT *unit)
|
||||
reference tables
|
||||
*/
|
||||
|
||||
if (setup_fields(thd, all_tables, *values, 1,0,0))
|
||||
if (setup_fields(thd, 0, all_tables, *values, 1, 0, 0))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
|
@ -1825,8 +1825,10 @@ select_item_list:
|
||||
| select_item
|
||||
| '*'
|
||||
{
|
||||
if (add_item_to_list(YYTHD, new Item_field(NULL,NULL,"*")))
|
||||
THD *thd= YYTHD;
|
||||
if (add_item_to_list(thd, new Item_field(NULL, NULL, "*")))
|
||||
YYABORT;
|
||||
(thd->lex.current_select->select_lex()->with_wild)++;
|
||||
};
|
||||
|
||||
|
||||
@ -3732,10 +3734,19 @@ insert_ident:
|
||||
| table_wild { $$=$1; };
|
||||
|
||||
table_wild:
|
||||
ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); }
|
||||
ident '.' '*'
|
||||
{
|
||||
$$ = new Item_field(NullS,$1.str,"*");
|
||||
Lex->current_select->select_lex()->with_wild++;
|
||||
}
|
||||
| ident '.' ident '.' '*'
|
||||
{ $$ = new Item_field((YYTHD->client_capabilities &
|
||||
CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); };
|
||||
{
|
||||
$$ = new Item_field((YYTHD->client_capabilities &
|
||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||
$3.str,"*");
|
||||
Lex->current_select->select_lex()->with_wild++;
|
||||
}
|
||||
;
|
||||
|
||||
order_ident:
|
||||
expr { $$=$1; };
|
||||
|
Loading…
x
Reference in New Issue
Block a user