mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-on-4.1
This commit is contained in:
@ -435,7 +435,7 @@ drop temporary table t1;
|
|||||||
create table t1 select a from t1 union select a from t2;
|
create table t1 select a from t1 union select a from t2;
|
||||||
ERROR HY000: You can't specify target table 't1' for update in FROM clause
|
ERROR HY000: You can't specify target table 't1' for update in FROM clause
|
||||||
select a from t1 union select a from t2 order by t2.a;
|
select a from t1 union select a from t2 order by t2.a;
|
||||||
ERROR 42S22: Unknown column 't2.a' in 'ORDER BY'
|
ERROR 42S02: Unknown table 't2' in order clause
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
select length(version()) > 1 as `*` UNION select 2;
|
select length(version()) > 1 as `*` UNION select 2;
|
||||||
*
|
*
|
||||||
|
@ -991,14 +991,11 @@ public:
|
|||||||
|
|
||||||
/* Some usefull inline functions */
|
/* Some usefull inline functions */
|
||||||
|
|
||||||
inline Item *and_conds(THD *thd, Item *a, Item *b, TABLE_LIST *tables)
|
inline Item *and_conds(Item *a, Item *b)
|
||||||
{
|
{
|
||||||
if (!b) return a;
|
if (!b) return a;
|
||||||
if (!a) return b;
|
if (!a) return b;
|
||||||
Item *cond= new Item_cond_and(a,b);
|
return new Item_cond_and(a, b);
|
||||||
if (cond)
|
|
||||||
cond->fix_fields(thd, tables, &cond);
|
|
||||||
return cond;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *and_expressions(Item *a, Item *b, Item **org_item);
|
Item *and_expressions(Item *a, Item *b, Item **org_item);
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
Item_sum::Item_sum(List<Item> &list)
|
Item_sum::Item_sum(List<Item> &list)
|
||||||
|
:args_copy(0), arg_count(list.elements)
|
||||||
{
|
{
|
||||||
arg_count=list.elements;
|
|
||||||
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
|
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
|
||||||
{
|
{
|
||||||
uint i=0;
|
uint i=0;
|
||||||
@ -43,18 +43,51 @@ Item_sum::Item_sum(List<Item> &list)
|
|||||||
|
|
||||||
// Constructor used in processing select with temporary tebles
|
// Constructor used in processing select with temporary tebles
|
||||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
Item_result_field(thd, item), quick_group(item->quick_group)
|
Item_result_field(thd, item), arg_count(item->arg_count),
|
||||||
|
quick_group(item->quick_group)
|
||||||
{
|
{
|
||||||
arg_count= item->arg_count;
|
|
||||||
if (arg_count <= 2)
|
if (arg_count <= 2)
|
||||||
args=tmp_args;
|
args=tmp_args;
|
||||||
else
|
else
|
||||||
if (!(args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
|
if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
||||||
return;
|
return;
|
||||||
for (uint i= 0; i < arg_count; i++)
|
memcpy(args, item->args, sizeof(Item*)*arg_count);
|
||||||
args[i]= item->args[i];
|
if (item->args_copy != 0)
|
||||||
|
save_args(thd);
|
||||||
|
else
|
||||||
|
args_copy= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save copy of arguments if we are prepare prepared statement
|
||||||
|
(arguments can be rewritten in get_tmp_table_item())
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Item_sum::save_args_for_prepared_statements()
|
||||||
|
thd - thread handler
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 - OK
|
||||||
|
1 - Error
|
||||||
|
*/
|
||||||
|
bool Item_sum::save_args_for_prepared_statements(THD *thd)
|
||||||
|
{
|
||||||
|
if (thd->current_statement)
|
||||||
|
return save_args(thd->current_statement);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_sum::save_args(Statement* stmt)
|
||||||
|
{
|
||||||
|
if (!(args_copy= (Item**) stmt->alloc(sizeof(Item*)*arg_count)))
|
||||||
|
return 1;
|
||||||
|
memcpy(args_copy, args, sizeof(Item*)*arg_count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_sum::mark_as_sum_func()
|
void Item_sum::mark_as_sum_func()
|
||||||
{
|
{
|
||||||
current_thd->lex->current_select->with_sum_func= 1;
|
current_thd->lex->current_select->with_sum_func= 1;
|
||||||
@ -62,6 +95,17 @@ void Item_sum::mark_as_sum_func()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_sum::cleanup()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Item_sum::cleanup");
|
||||||
|
Item_result_field::cleanup();
|
||||||
|
if (args_copy != 0)
|
||||||
|
memcpy(args, args_copy, sizeof(Item*)*arg_count);
|
||||||
|
result_field=0;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_sum::make_field(Send_field *tmp_field)
|
void Item_sum::make_field(Send_field *tmp_field)
|
||||||
{
|
{
|
||||||
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
|
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
|
||||||
@ -165,6 +209,10 @@ bool
|
|||||||
Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 0);
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
|
||||||
|
if (save_args_for_prepared_statements(thd))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (!thd->allow_sum_func)
|
if (!thd->allow_sum_func)
|
||||||
{
|
{
|
||||||
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
|
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
|
||||||
@ -195,6 +243,10 @@ bool
|
|||||||
Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 0);
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
|
||||||
|
if (save_args_for_prepared_statements(thd))
|
||||||
|
return 1;
|
||||||
|
|
||||||
Item *item= args[0];
|
Item *item= args[0];
|
||||||
if (!thd->allow_sum_func)
|
if (!thd->allow_sum_func)
|
||||||
{
|
{
|
||||||
@ -1131,15 +1183,6 @@ void Item_sum_count_distinct::cleanup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables,
|
|
||||||
Item **ref)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(fixed == 0);
|
|
||||||
if (Item_sum_num::fix_fields(thd, tables, ref))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is used by rollup to create a separate usable copy of the function */
|
/* This is used by rollup to create a separate usable copy of the function */
|
||||||
|
|
||||||
void Item_sum_count_distinct::make_unique()
|
void Item_sum_count_distinct::make_unique()
|
||||||
@ -1705,6 +1748,11 @@ void Item_func_group_concat::cleanup()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_group_concat::cleanup");
|
DBUG_ENTER("Item_func_group_concat::cleanup");
|
||||||
Item_sum::cleanup();
|
Item_sum::cleanup();
|
||||||
|
|
||||||
|
/* fix order list */
|
||||||
|
for (uint i= 0; i < arg_count_order ; i++)
|
||||||
|
order[i]->item= &order[i]->item_ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Free table and tree if they belong to this item (if item have not pointer
|
Free table and tree if they belong to this item (if item have not pointer
|
||||||
to original item from which was made copy => it own its objects )
|
to original item from which was made copy => it own its objects )
|
||||||
@ -1821,6 +1869,10 @@ bool
|
|||||||
Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 0);
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
|
||||||
|
if (save_args_for_prepared_statements(thd))
|
||||||
|
return 1;
|
||||||
|
|
||||||
uint i; /* for loop variable */
|
uint i; /* for loop variable */
|
||||||
|
|
||||||
if (!thd->allow_sum_func)
|
if (!thd->allow_sum_func)
|
||||||
|
@ -32,40 +32,32 @@ public:
|
|||||||
UDF_SUM_FUNC, GROUP_CONCAT_FUNC
|
UDF_SUM_FUNC, GROUP_CONCAT_FUNC
|
||||||
};
|
};
|
||||||
|
|
||||||
Item **args,*tmp_args[2];
|
Item **args, *tmp_args[2];
|
||||||
|
Item **args_copy; /* copy of arguments for PS */
|
||||||
uint arg_count;
|
uint arg_count;
|
||||||
bool quick_group; /* If incremental update of fields */
|
bool quick_group; /* If incremental update of fields */
|
||||||
|
|
||||||
void mark_as_sum_func();
|
void mark_as_sum_func();
|
||||||
Item_sum() : arg_count(0),quick_group(1)
|
Item_sum() :args_copy(0), arg_count(0), quick_group(1)
|
||||||
{
|
{
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum(Item *a) :quick_group(1)
|
Item_sum(Item *a)
|
||||||
|
:args(tmp_args), args_copy(0), arg_count(1), quick_group(1)
|
||||||
{
|
{
|
||||||
arg_count=1;
|
|
||||||
args=tmp_args;
|
|
||||||
args[0]=a;
|
args[0]=a;
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum( Item *a, Item *b ) :quick_group(1)
|
Item_sum( Item *a, Item *b )
|
||||||
|
:args(tmp_args), args_copy(0), arg_count(2), quick_group(1)
|
||||||
{
|
{
|
||||||
arg_count=2;
|
|
||||||
args=tmp_args;
|
|
||||||
args[0]=a; args[1]=b;
|
args[0]=a; args[1]=b;
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum(List<Item> &list);
|
Item_sum(List<Item> &list);
|
||||||
//Copy constructor, need to perform subselects with temporary tables
|
//Copy constructor, need to perform subselects with temporary tables
|
||||||
Item_sum(THD *thd, Item_sum *item);
|
Item_sum(THD *thd, Item_sum *item);
|
||||||
void cleanup()
|
void cleanup();
|
||||||
{
|
|
||||||
DBUG_ENTER("Item_sum::cleanup");
|
|
||||||
Item_result_field::cleanup();
|
|
||||||
result_field=0;
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
inline bool reset() { clear(); return add(); };
|
inline bool reset() { clear(); return add(); };
|
||||||
@ -100,6 +92,8 @@ public:
|
|||||||
virtual bool setup(THD *thd) {return 0;}
|
virtual bool setup(THD *thd) {return 0;}
|
||||||
virtual void make_unique() {}
|
virtual void make_unique() {}
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
|
bool save_args_for_prepared_statements(THD *);
|
||||||
|
bool save_args(Statement* stmt);
|
||||||
|
|
||||||
bool walk (Item_processor processor, byte *argument);
|
bool walk (Item_processor processor, byte *argument);
|
||||||
};
|
};
|
||||||
@ -190,7 +184,6 @@ class Item_sum_count_distinct :public Item_sum_int
|
|||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
table_map used_table_cache;
|
table_map used_table_cache;
|
||||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
|
||||||
uint32 *field_lengths;
|
uint32 *field_lengths;
|
||||||
TMP_TABLE_PARAM *tmp_table_param;
|
TMP_TABLE_PARAM *tmp_table_param;
|
||||||
TREE tree_base;
|
TREE tree_base;
|
||||||
@ -236,7 +229,8 @@ class Item_sum_count_distinct :public Item_sum_int
|
|||||||
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
|
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
|
||||||
:Item_sum_int(thd, item), table(item->table),
|
:Item_sum_int(thd, item), table(item->table),
|
||||||
used_table_cache(item->used_table_cache),
|
used_table_cache(item->used_table_cache),
|
||||||
field_lengths(item->field_lengths), tmp_table_param(item->tmp_table_param),
|
field_lengths(item->field_lengths),
|
||||||
|
tmp_table_param(item->tmp_table_param),
|
||||||
tree(item->tree), original(item), key_length(item->key_length),
|
tree(item->tree), original(item), key_length(item->key_length),
|
||||||
max_elements_in_tree(item->max_elements_in_tree),
|
max_elements_in_tree(item->max_elements_in_tree),
|
||||||
rec_offset(item->rec_offset), use_tree(item->use_tree),
|
rec_offset(item->rec_offset), use_tree(item->use_tree),
|
||||||
|
@ -287,6 +287,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
|||||||
|
|
||||||
struct st_table;
|
struct st_table;
|
||||||
class THD;
|
class THD;
|
||||||
|
class Statement;
|
||||||
|
|
||||||
/* Struct to handle simple linked lists */
|
/* Struct to handle simple linked lists */
|
||||||
|
|
||||||
|
@ -2405,15 +2405,13 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
{
|
{
|
||||||
if (table->on_expr)
|
if (table->on_expr)
|
||||||
{
|
{
|
||||||
if (stmt)
|
|
||||||
thd->set_n_backup_item_arena(stmt, &backup);
|
|
||||||
/* Make a join an a expression */
|
/* Make a join an a expression */
|
||||||
thd->where="on clause";
|
thd->where="on clause";
|
||||||
|
|
||||||
if (!table->on_expr->fixed &&
|
if (!table->on_expr->fixed &&
|
||||||
table->on_expr->fix_fields(thd, tables, &table->on_expr) ||
|
table->on_expr->fix_fields(thd, tables, &table->on_expr) ||
|
||||||
table->on_expr->check_cols(1))
|
table->on_expr->check_cols(1))
|
||||||
goto err;
|
DBUG_RETURN(1);
|
||||||
thd->lex->current_select->cond_count++;
|
thd->lex->current_select->cond_count++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2425,12 +2423,16 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
!(specialflag & SPECIAL_NO_NEW_FUNC)))
|
!(specialflag & SPECIAL_NO_NEW_FUNC)))
|
||||||
{
|
{
|
||||||
table->outer_join= 0;
|
table->outer_join= 0;
|
||||||
if (!(*conds= and_conds(thd, *conds, table->on_expr, tables)))
|
if (stmt)
|
||||||
goto err;
|
thd->set_n_backup_item_arena(stmt, &backup);
|
||||||
|
*conds= and_conds(*conds, table->on_expr);
|
||||||
table->on_expr=0;
|
table->on_expr=0;
|
||||||
}
|
|
||||||
if (stmt)
|
if (stmt)
|
||||||
thd->restore_backup_item_arena(stmt, &backup);
|
thd->restore_backup_item_arena(stmt, &backup);
|
||||||
|
if ((*conds) && !(*conds)->fixed &&
|
||||||
|
(*conds)->fix_fields(thd, tables, conds))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (table->natural_join)
|
if (table->natural_join)
|
||||||
{
|
{
|
||||||
@ -2469,20 +2471,28 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
|
|
||||||
if (!table->outer_join) // Not left join
|
if (!table->outer_join) // Not left join
|
||||||
{
|
{
|
||||||
if (!(*conds= and_conds(thd, *conds, cond_and, tables)) ||
|
*conds= and_conds(*conds, cond_and);
|
||||||
(*conds && !(*conds)->fixed &&
|
// fix_fields() should be made with temporary memory pool
|
||||||
(*conds)->fix_fields(thd, tables, conds)))
|
if (stmt)
|
||||||
goto err;
|
thd->restore_backup_item_arena(stmt, &backup);
|
||||||
|
if (*conds && !(*conds)->fixed)
|
||||||
|
{
|
||||||
|
if ((*conds)->fix_fields(thd, tables, conds))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table->on_expr= and_conds(thd, table->on_expr, cond_and, tables);
|
table->on_expr= and_conds(table->on_expr, cond_and);
|
||||||
if (table->on_expr && !table->on_expr->fixed &&
|
// fix_fields() should be made with temporary memory pool
|
||||||
table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (stmt)
|
if (stmt)
|
||||||
thd->restore_backup_item_arena(stmt, &backup);
|
thd->restore_backup_item_arena(stmt, &backup);
|
||||||
|
if (table->on_expr && !table->on_expr->fixed)
|
||||||
|
{
|
||||||
|
if (table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4431,11 +4431,10 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
|
|||||||
ORDER *order;
|
ORDER *order;
|
||||||
Item **item_ptr;
|
Item **item_ptr;
|
||||||
DBUG_ENTER("add_to_list");
|
DBUG_ENTER("add_to_list");
|
||||||
if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
|
if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
item_ptr = (Item**) (order+1);
|
order->item_ptr= item;
|
||||||
*item_ptr=item;
|
order->item= &order->item_ptr;
|
||||||
order->item= item_ptr;
|
|
||||||
order->asc = asc;
|
order->asc = asc;
|
||||||
order->free_me=0;
|
order->free_me=0;
|
||||||
order->used=0;
|
order->used=0;
|
||||||
|
@ -987,6 +987,8 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
|
|||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("mysql_stmt_prepare");
|
DBUG_ENTER("mysql_stmt_prepare");
|
||||||
|
|
||||||
|
DBUG_PRINT("pquery", ("%s", packet));
|
||||||
|
|
||||||
if (stmt == 0)
|
if (stmt == 0)
|
||||||
{
|
{
|
||||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||||
@ -1076,11 +1078,11 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
|
|||||||
DBUG_ASSERT(sl->join == 0);
|
DBUG_ASSERT(sl->join == 0);
|
||||||
ORDER *order;
|
ORDER *order;
|
||||||
/* Fix GROUP list */
|
/* Fix GROUP list */
|
||||||
for (order=(ORDER *)sl->group_list.first ; order ; order=order->next)
|
for (order= (ORDER *)sl->group_list.first; order; order= order->next)
|
||||||
order->item= (Item **)(order+1);
|
order->item= &order->item_ptr;
|
||||||
/* Fix ORDER list */
|
/* Fix ORDER list */
|
||||||
for (order=(ORDER *)sl->order_list.first ; order ; order=order->next)
|
for (order= (ORDER *)sl->order_list.first; order; order= order->next)
|
||||||
order->item= (Item **)(order+1);
|
order->item= &order->item_ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: When the new table structure is ready, then have a status bit
|
TODO: When the new table structure is ready, then have a status bit
|
||||||
@ -1131,6 +1133,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "execute", SEND_ERROR)))
|
if (!(stmt= find_prepared_statement(thd, stmt_id, "execute", SEND_ERROR)))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
|
DBUG_PRINT("equery:", ("%s", stmt->query));
|
||||||
|
|
||||||
/* Check if we got an error when sending long data */
|
/* Check if we got an error when sending long data */
|
||||||
if (stmt->get_longdata_error)
|
if (stmt->get_longdata_error)
|
||||||
{
|
{
|
||||||
|
@ -3536,7 +3536,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
{
|
{
|
||||||
/* Join with outer join condition */
|
/* Join with outer join condition */
|
||||||
COND *orig_cond=sel->cond;
|
COND *orig_cond=sel->cond;
|
||||||
sel->cond=and_conds(join->thd, sel->cond, tab->on_expr, 0);
|
sel->cond= and_conds(sel->cond, tab->on_expr);
|
||||||
|
if (sel->cond && !sel->cond->fixed)
|
||||||
|
sel->cond->fix_fields(join->thd, 0, &sel->cond);
|
||||||
if (sel->test_quick_select(join->thd, tab->keys,
|
if (sel->test_quick_select(join->thd, tab->keys,
|
||||||
used_tables & ~ current_map,
|
used_tables & ~ current_map,
|
||||||
(join->select_options &
|
(join->select_options &
|
||||||
|
@ -208,19 +208,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (tmp_order= (ORDER*) global_parameters->order_list.first;
|
|
||||||
tmp_order ;
|
|
||||||
tmp_order= tmp_order->next)
|
|
||||||
{
|
|
||||||
Item *item= *tmp_order->item;
|
|
||||||
if (((item->type() == Item::FIELD_ITEM) &&
|
|
||||||
((class Item_field*) item)->table_name))
|
|
||||||
{
|
|
||||||
my_error(ER_BAD_FIELD_ERROR,MYF(0),item->full_name(),"ORDER BY");
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
// it is not single select
|
// it is not single select
|
||||||
if (first_select->next_select())
|
if (first_select->next_select())
|
||||||
|
@ -26,6 +26,7 @@ class st_select_lex_unit;
|
|||||||
typedef struct st_order {
|
typedef struct st_order {
|
||||||
struct st_order *next;
|
struct st_order *next;
|
||||||
Item **item; /* Point at item in select fields */
|
Item **item; /* Point at item in select fields */
|
||||||
|
Item *item_ptr; /* Storage for initial item */
|
||||||
bool asc; /* true if ascending */
|
bool asc; /* true if ascending */
|
||||||
bool free_me; /* true if item isn't shared */
|
bool free_me; /* true if item isn't shared */
|
||||||
bool in_field_list; /* true if in select field list */
|
bool in_field_list; /* true if in select field list */
|
||||||
|
@ -8531,6 +8531,52 @@ static void test_on()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_selecttmp()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
int rc, i;
|
||||||
|
const char *query= "select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3";
|
||||||
|
|
||||||
|
myheader("test_select_tmp");
|
||||||
|
|
||||||
|
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"CREATE TABLE t1 (a int , b int);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"create table t2 (a int, b int);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"create table t3 (a int, b int);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), \
|
||||||
|
(2,-1), (3,10);");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"insert into t3 values (3,3), (2,2), (1,1);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_prepare(mysql, query, strlen(query));
|
||||||
|
mystmt_init(stmt);
|
||||||
|
for (i= 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
rc= mysql_execute(stmt);
|
||||||
|
mystmt(stmt, rc);
|
||||||
|
assert(3 == my_process_stmt_result(stmt));
|
||||||
|
}
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -8791,6 +8837,7 @@ int main(int argc, char **argv)
|
|||||||
test_union(); /* test union with prepared statements */
|
test_union(); /* test union with prepared statements */
|
||||||
test_bug3117(); /* BUG#3117: LAST_INSERT_ID() */
|
test_bug3117(); /* BUG#3117: LAST_INSERT_ID() */
|
||||||
test_on(); /* ... join ... on(), BUG#2794 */
|
test_on(); /* ... join ... on(), BUG#2794 */
|
||||||
|
test_selecttmp(); /* temporary table used in select execution */
|
||||||
|
|
||||||
|
|
||||||
end_time= time((time_t *)0);
|
end_time= time((time_t *)0);
|
||||||
|
Reference in New Issue
Block a user