mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
IN subselect with ORDER BY, HAVING & sum functions
This commit is contained in:
@ -230,4 +230,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 PRIMARY searchconthardwarefr3 index NULL topic 3 NULL 2 Using index
|
1 PRIMARY searchconthardwarefr3 index NULL topic 3 NULL 2 Using index
|
||||||
2 SUBSELECT No tables used
|
2 SUBSELECT No tables used
|
||||||
3 UNION No tables used
|
3 UNION No tables used
|
||||||
|
SELECT 1 IN (SELECT 1 FROM searchconthardwarefr3 HAVING a);
|
||||||
|
Unknown column 'a' in 'having clause'
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date);
|
||||||
|
topic date pseudo
|
||||||
|
40143 2002-08-03 joce
|
||||||
|
43506 2002-10-02 joce
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date HAVING topic < 4100);
|
||||||
|
topic date pseudo
|
||||||
|
43506 2002-10-02 joce
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT SUM(topic) FROM searchconthardwarefr3);
|
||||||
|
topic date pseudo
|
||||||
drop table searchconthardwarefr3;
|
drop table searchconthardwarefr3;
|
||||||
|
@ -120,4 +120,9 @@ SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL
|
|||||||
-- error 1240
|
-- error 1240
|
||||||
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
|
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
|
||||||
EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1);
|
EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1);
|
||||||
|
-- error 1054
|
||||||
|
SELECT 1 IN (SELECT 1 FROM searchconthardwarefr3 HAVING a);
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date);
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date HAVING topic < 4100);
|
||||||
|
SELECT * from searchconthardwarefr3 where topic IN (SELECT SUM(topic) FROM searchconthardwarefr3);
|
||||||
drop table searchconthardwarefr3;
|
drop table searchconthardwarefr3;
|
10
sql/item.h
10
sql/item.h
@ -116,11 +116,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
class Item_outer_select_context_saver :public Item_wrapper
|
class Item_outer_select_context_saver :public Item_wrapper
|
||||||
{
|
{
|
||||||
Item *item;
|
|
||||||
public:
|
public:
|
||||||
Item_outer_select_context_saver(Item *i):
|
Item_outer_select_context_saver(Item *i)
|
||||||
item(i)
|
|
||||||
{
|
{
|
||||||
|
item= i;
|
||||||
}
|
}
|
||||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
||||||
};
|
};
|
||||||
@ -130,11 +129,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
class Item_asterisk_remover :public Item_wrapper
|
class Item_asterisk_remover :public Item_wrapper
|
||||||
{
|
{
|
||||||
Item *item;
|
|
||||||
public:
|
public:
|
||||||
Item_asterisk_remover(Item *i):
|
Item_asterisk_remover(Item *i)
|
||||||
item(i)
|
|
||||||
{
|
{
|
||||||
|
item= i;
|
||||||
}
|
}
|
||||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
||||||
};
|
};
|
||||||
|
@ -254,15 +254,30 @@ void Item_in_subselect::select_transformer(st_select_lex *select_lex,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
item= (Item*) sl->item_list.pop();
|
item= (Item*) sl->item_list.pop();
|
||||||
sl->item_list.empty();
|
|
||||||
sl->item_list.push_back(new Item_int(1));
|
|
||||||
left_expr= new Item_outer_select_context_saver(left_expr);
|
left_expr= new Item_outer_select_context_saver(left_expr);
|
||||||
item= new Item_asterisk_remover(item);
|
|
||||||
if (sl->where)
|
if (sl->having || sl->with_sum_func || sl->group_list.first)
|
||||||
sl->where= new Item_cond_and(sl->where,
|
{
|
||||||
new Item_func_eq(item, left_expr));
|
sl->item_list.push_back(item);
|
||||||
|
item= new Item_ref(sl->item_list.head_ref(), 0, "<result>");
|
||||||
|
if (sl->having)
|
||||||
|
sl->having= new Item_cond_and(sl->having,
|
||||||
|
new Item_func_eq(item, left_expr));
|
||||||
|
else
|
||||||
|
sl->having= new Item_func_eq(item, left_expr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sl->where= new Item_func_eq(item, left_expr);
|
{
|
||||||
|
sl->item_list.empty();
|
||||||
|
sl->item_list.push_back(new Item_int(1));
|
||||||
|
item= new Item_asterisk_remover(item);
|
||||||
|
if (sl->where)
|
||||||
|
sl->where= new Item_cond_and(sl->where,
|
||||||
|
new Item_func_eq(item, left_expr));
|
||||||
|
else
|
||||||
|
sl->where= new Item_func_eq(item, left_expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
|
|
||||||
Item_sum::Item_sum(List<Item> &list)
|
Item_sum::Item_sum(List<Item> &list)
|
||||||
{
|
{
|
||||||
arg_count=list.elements;
|
arg_count=list.elements;
|
||||||
@ -38,10 +37,14 @@ Item_sum::Item_sum(List<Item> &list)
|
|||||||
args[i++]= item;
|
args[i++]= item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
with_sum_func=1;
|
mark_as_sum_func();
|
||||||
list.empty(); // Fields are used
|
list.empty(); // Fields are used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Item_sum::mark_as_sum_func()
|
||||||
|
{
|
||||||
|
current_thd->lex.select->with_sum_func= with_sum_func= 1;
|
||||||
|
}
|
||||||
|
|
||||||
void Item_sum::make_field(Send_field *tmp_field)
|
void Item_sum::make_field(Send_field *tmp_field)
|
||||||
{
|
{
|
||||||
|
@ -34,23 +34,28 @@ public:
|
|||||||
uint arg_count;
|
uint arg_count;
|
||||||
bool quick_group; /* If incremental update of fields */
|
bool quick_group; /* If incremental update of fields */
|
||||||
|
|
||||||
Item_sum() : arg_count(0),quick_group(1) { with_sum_func=1; }
|
Item_sum() : arg_count(0),quick_group(1)
|
||||||
|
{
|
||||||
|
mark_as_sum_func();
|
||||||
|
}
|
||||||
Item_sum(Item *a) :quick_group(1)
|
Item_sum(Item *a) :quick_group(1)
|
||||||
{
|
{
|
||||||
arg_count=1;
|
arg_count=1;
|
||||||
args=tmp_args;
|
args=tmp_args;
|
||||||
args[0]=a;
|
args[0]=a;
|
||||||
with_sum_func = 1;
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum( Item *a, Item *b ) :quick_group(1)
|
Item_sum( Item *a, Item *b ) :quick_group(1)
|
||||||
{
|
{
|
||||||
arg_count=2;
|
arg_count=2;
|
||||||
args=tmp_args;
|
args=tmp_args;
|
||||||
args[0]=a; args[1]=b;
|
args[0]=a; args[1]=b;
|
||||||
with_sum_func=1;
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum(List<Item> &list);
|
Item_sum(List<Item> &list);
|
||||||
~Item_sum() { result_field=0; }
|
~Item_sum() { result_field=0; }
|
||||||
|
inline void mark_as_sum_func();
|
||||||
|
|
||||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||||
virtual enum Sumfunctype sum_func () const=0;
|
virtual enum Sumfunctype sum_func () const=0;
|
||||||
virtual void reset()=0;
|
virtual void reset()=0;
|
||||||
|
@ -935,6 +935,7 @@ void st_select_lex_node::init_select()
|
|||||||
order_list.next= (byte**) &order_list.first;
|
order_list.next= (byte**) &order_list.first;
|
||||||
select_limit= HA_POS_ERROR;
|
select_limit= HA_POS_ERROR;
|
||||||
offset_limit= 0;
|
offset_limit= 0;
|
||||||
|
with_sum_func= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex_unit::init_query()
|
void st_select_lex_unit::init_query()
|
||||||
|
@ -196,6 +196,7 @@ public:
|
|||||||
enum sub_select_type linkage;
|
enum sub_select_type linkage;
|
||||||
SQL_LIST order_list; /* ORDER clause */
|
SQL_LIST order_list; /* ORDER clause */
|
||||||
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
|
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
|
||||||
|
bool with_sum_func;
|
||||||
void init_query();
|
void init_query();
|
||||||
void init_select();
|
void init_select();
|
||||||
void include_down(st_select_lex_node *upper);
|
void include_down(st_select_lex_node *upper);
|
||||||
|
Reference in New Issue
Block a user