summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <holyfoot/hf@hfmain.(none)>2007-03-22 12:20:51 +0400
committerunknown <holyfoot/hf@hfmain.(none)>2007-03-22 12:20:51 +0400
commitd152debde52cf1a8c3690a05fc6fe54f613fc008 (patch)
treeeddfd478f114ee98f384a977c9aee7847e9376e4 /sql
parent8ed9a54008fae160d63dc27fa02b9ae4348238e7 (diff)
parent9f9e2f2df02ba7cbeb075ea345f979eb244f97a6 (diff)
downloadmariadb-git-d152debde52cf1a8c3690a05fc6fe54f613fc008.tar.gz
Merge bk@192.168.21.1:mysql-5.1
into mysql.com:/home/hf/work/mrg/mysql-5.1-opt libmysqld/lib_sql.cc: Auto merged sql/item.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_yacc.yy: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/item.h5
-rw-r--r--sql/item_cmpfunc.cc3
-rw-r--r--sql/item_sum.cc37
-rw-r--r--sql/item_sum.h59
-rw-r--r--sql/opt_range.cc6
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_class.h5
-rw-r--r--sql/sql_insert.cc6
-rw-r--r--sql/sql_select.cc22
-rw-r--r--sql/sql_yacc.yy2
10 files changed, 101 insertions, 49 deletions
diff --git a/sql/item.h b/sql/item.h
index dce03299929..87380b53bfb 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2004,6 +2004,11 @@ public:
{
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
}
+ void update_used_tables()
+ {
+ if (!depended_from)
+ (*ref)->update_used_tables();
+ }
table_map not_null_tables() const { return (*ref)->not_null_tables(); }
void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 7e5df8fdbbf..20bbee2f930 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2458,7 +2458,8 @@ void in_decimal::set(uint pos, Item *item)
dec->len= DECIMAL_BUFF_LENGTH;
dec->fix_buffer_pointer();
my_decimal *res= item->val_decimal(dec);
- if (res != dec)
+ /* if item->val_decimal() is evaluated to NULL then res == 0 */
+ if (!item->null_value && res != dec)
my_decimal2decimal(res, dec);
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index f34fc008186..f38950c95c3 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -61,6 +61,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
/* Save a pointer to object to be used in items for nested set functions */
thd->lex->in_sum_func= this;
nest_level= thd->lex->current_select->nest_level;
+ nest_level_tables_count= thd->lex->current_select->join->tables;
ref_by= 0;
aggr_level= -1;
max_arg_level= -1;
@@ -176,6 +177,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
*/
set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
}
+ update_used_tables();
thd->lex->in_sum_func= in_sum_func;
return FALSE;
}
@@ -267,12 +269,13 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1;
}
+ thd->lex->current_select->mark_as_dependent(aggr_sl);
return FALSE;
}
-Item_sum::Item_sum(List<Item> &list)
- :arg_count(list.elements)
+Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
+ forced_const(FALSE)
{
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
@@ -296,7 +299,10 @@ Item_sum::Item_sum(List<Item> &list)
Item_sum::Item_sum(THD *thd, Item_sum *item):
Item_result_field(thd, item), arg_count(item->arg_count),
- quick_group(item->quick_group)
+ nest_level(item->nest_level), aggr_level(item->aggr_level),
+ quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
+ forced_const(item->forced_const),
+ nest_level_tables_count(item->nest_level_tables_count)
{
if (arg_count <= 2)
args=tmp_args;
@@ -429,6 +435,26 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
}
+void Item_sum::update_used_tables ()
+{
+ if (!forced_const)
+ {
+ used_tables_cache= 0;
+ for (uint i=0 ; i < arg_count ; i++)
+ {
+ args[i]->update_used_tables();
+ used_tables_cache|= args[i]->used_tables();
+ }
+
+ used_tables_cache&= PSEUDO_TABLE_BITS;
+
+ /* the aggregate function is aggregated into its local context */
+ if (aggr_level == nest_level)
+ used_tables_cache |= (1 << nest_level_tables_count) - 1;
+ }
+}
+
+
String *
Item_sum_num::val_str(String *str)
{
@@ -488,7 +514,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
- used_table_cache(item->used_table_cache), was_values(item->was_values)
+ was_values(item->was_values)
{
/* copy results from old value */
switch (hybrid_type) {
@@ -1082,7 +1108,6 @@ void Item_sum_count::cleanup()
DBUG_ENTER("Item_sum_count::cleanup");
count= 0;
Item_sum_int::cleanup();
- used_table_cache= ~(table_map) 0;
DBUG_VOID_RETURN;
}
@@ -1572,7 +1597,7 @@ void Item_sum_hybrid::cleanup()
{
DBUG_ENTER("Item_sum_hybrid::cleanup");
Item_sum::cleanup();
- used_table_cache= ~(table_map) 0;
+ forced_const= FALSE;
/*
by default it is TRUE to avoid TRUE reporting by
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 4cf16fc79af..5756402c1b1 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -215,7 +215,9 @@
TODO: to catch queries where the limit is exceeded to make the
code clean here.
-*/
+*/
+
+class st_select_lex;
class Item_sum :public Item_result_field
{
@@ -237,19 +239,26 @@ public:
int8 max_sum_func_level;/* max level of aggregation for embedded functions */
bool quick_group; /* If incremental update of fields */
+protected:
+ table_map used_tables_cache;
+ bool forced_const;
+ byte nest_level_tables_count;
+
+public:
+
void mark_as_sum_func();
- Item_sum() :arg_count(0), quick_group(1)
+ Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE)
{
mark_as_sum_func();
}
- Item_sum(Item *a)
- :args(tmp_args), arg_count(1), quick_group(1)
+ Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
+ forced_const(FALSE)
{
args[0]=a;
mark_as_sum_func();
}
- Item_sum( Item *a, Item *b )
- :args(tmp_args), arg_count(2), quick_group(1)
+ Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1),
+ forced_const(FALSE)
{
args[0]=a; args[1]=b;
mark_as_sum_func();
@@ -319,10 +328,20 @@ public:
virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
{ return new Item_field(field); }
- table_map used_tables() const { return ~(table_map) 0; } /* Not used */
- bool const_item() const { return 0; }
+ table_map used_tables() const { return used_tables_cache; }
+ void update_used_tables ();
+ void cleanup()
+ {
+ Item::cleanup();
+ forced_const= FALSE;
+ }
bool is_null() { return null_value; }
- void update_used_tables() { }
+ void make_const ()
+ {
+ used_tables_cache= 0;
+ forced_const= TRUE;
+ }
+ virtual bool const_item() const { return forced_const; }
void make_field(Send_field *field);
void print(String *str);
void fix_num_length_and_dec();
@@ -509,23 +528,23 @@ public:
class Item_sum_count :public Item_sum_int
{
longlong count;
- table_map used_table_cache;
public:
Item_sum_count(Item *item_par)
- :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
+ :Item_sum_int(item_par),count(0)
{}
Item_sum_count(THD *thd, Item_sum_count *item)
- :Item_sum_int(thd, item), count(item->count),
- used_table_cache(item->used_table_cache)
+ :Item_sum_int(thd, item), count(item->count)
{}
- 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; }
void clear();
void no_rows_in_result() { count=0; }
bool add();
- void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
+ void make_const(longlong count_arg)
+ {
+ count=count_arg;
+ Item_sum::make_const();
+ }
longlong val_int();
void reset_field();
void cleanup();
@@ -805,28 +824,22 @@ protected:
Item_result hybrid_type;
enum_field_types hybrid_field_type;
int cmp_sign;
- table_map used_table_cache;
bool was_values; // Set if we have found at least one row (for max/min only)
public:
Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), sum(0.0), sum_int(0),
hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
- cmp_sign(sign), used_table_cache(~(table_map) 0),
- was_values(TRUE)
+ cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
bool fix_fields(THD *, Item **);
- table_map used_tables() const { return used_table_cache; }
- bool const_item() const { return !used_table_cache; }
-
void clear();
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
void reset_field();
String *val_str(String *);
- void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; }
enum enum_field_types field_type() const { return hybrid_field_type; }
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 52faaf25b42..03d97a294ad 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -8985,7 +8985,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else
DBUG_RETURN(NULL);
- Item *expr= min_max_item->args[0]; /* The argument of MIN/MAX. */
+ /* The argument of MIN/MAX. */
+ Item *expr= min_max_item->args[0]->real_item();
if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
{
if (! min_max_arg_item)
@@ -9356,6 +9357,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_ENTER("check_group_min_max_predicates");
DBUG_ASSERT(cond && min_max_arg_item);
+ cond= cond->real_item();
Item::Type cond_type= cond->type();
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
{
@@ -9393,7 +9395,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
{
- cur_arg= arguments[arg_idx];
+ cur_arg= arguments[arg_idx]->real_item();
DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
if (cur_arg->type() == Item::FIELD_ITEM)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e0b60b875d5..4d7c2c485ab 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -5772,11 +5772,13 @@ bool setup_tables_and_check_access(THD *thd,
TABLE_LIST *leaves_tmp= NULL;
bool first_table= true;
+ thd->leaf_count= 0;
if (setup_tables(thd, context, from_clause, tables,
&leaves_tmp, select_insert))
return TRUE;
- *leaves= leaves_tmp;
+ if (leaves)
+ *leaves= leaves_tmp;
for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
{
@@ -5788,6 +5790,7 @@ bool setup_tables_and_check_access(THD *thd,
return TRUE;
}
first_table= 0;
+ thd->leaf_count++;
}
return FALSE;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 11bf0f05d13..a9915fce4ef 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1411,7 +1411,10 @@ public:
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *work_part_info;
#endif
-
+
+ /* pass up the count of "leaf" tables in a JOIN out of setup_tables() */
+ byte leaf_count;
+
THD();
~THD();
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index d24230eb379..773383c2c2d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2466,12 +2466,14 @@ bool mysql_insert_select_prepare(THD *thd)
DBUG_ASSERT(select_lex->leaf_tables != 0);
lex->leaf_tables_insert= select_lex->leaf_tables;
/* skip all leaf tables belonged to view where we are insert */
- for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
+ for (first_select_leaf_table= select_lex->leaf_tables->next_leaf,
+ thd->leaf_count --;
first_select_leaf_table &&
first_select_leaf_table->belong_to_view &&
first_select_leaf_table->belong_to_view ==
lex->leaf_tables_insert->belong_to_view;
- first_select_leaf_table= first_select_leaf_table->next_leaf)
+ first_select_leaf_table= first_select_leaf_table->next_leaf,
+ thd->leaf_count --)
{}
select_lex->leaf_tables= first_select_leaf_table;
DBUG_RETURN(FALSE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e7ade996d87..582df11c8c1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -408,12 +408,14 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */
- if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
- setup_tables_and_check_access(thd, &select_lex->context, join_list,
- tables_list,
- &select_lex->leaf_tables, FALSE,
- SELECT_ACL, SELECT_ACL)) ||
- setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
+ if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
+ setup_tables_and_check_access(thd, &select_lex->context, join_list,
+ tables_list, &select_lex->leaf_tables,
+ FALSE, SELECT_ACL, SELECT_ACL))
+ DBUG_RETURN(-1);
+ tables= thd->leaf_count;
+
+ if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
&all_fields, 1) ||
@@ -518,11 +520,6 @@ JOIN::prepare(Item ***rref_pointer_array,
DBUG_RETURN(-1);
}
}
- TABLE_LIST *table_ptr;
- for (table_ptr= select_lex->leaf_tables;
- table_ptr;
- table_ptr= table_ptr->next_leaf)
- tables++;
}
{
/* Caclulate the number of groups */
@@ -6635,7 +6632,8 @@ static void update_depend_map(JOIN *join, ORDER *order)
order->item[0]->update_used_tables();
order->depend_map=depend_map=order->item[0]->used_tables();
// Not item_sum(), RAND() and no reference to table outside of sub select
- if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)))
+ if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
+ && !order->item[0]->with_sum_func)
{
for (JOIN_TAB **tab=join->map2table;
depend_map ;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 963146f3cb4..779c5ded95a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -11075,7 +11075,7 @@ union_list:
UNION_SYM union_option
{
LEX *lex=Lex;
- if (lex->exchange)
+ if (lex->result)
{
/* Only the last SELECT can have INTO...... */
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");