summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorChad MILLER <chad@mysql.com>2008-07-10 14:47:53 -0400
committerChad MILLER <chad@mysql.com>2008-07-10 14:47:53 -0400
commit06756c19c5a27a5240dc1dd7c243c32db04ccf00 (patch)
treed78d316822f255f22093dc0cc26ea8943b5f91d4 /sql/sql_select.cc
parent93aba6a8835210d6065ccb2f74114b64502a702b (diff)
parentac15eee942b492764690b634570ca32bda446b6c (diff)
downloadmariadb-git-06756c19c5a27a5240dc1dd7c243c32db04ccf00.tar.gz
Merge chunk from trunk.
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc51
1 files changed, 29 insertions, 22 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3c33bbf5d7c..9ef1823978e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -217,6 +217,7 @@ static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
bool distinct, const char *message=NullS);
static Item *remove_additional_cond(Item* conds);
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
+static bool test_if_ref(Item_field *left_item,Item *right_item);
/*
@@ -681,9 +682,6 @@ err:
without "checking NULL", remove the predicates that were pushed down
into the subquery.
- We can remove the equalities that will be guaranteed to be true by the
- fact that subquery engine will be using index lookup.
-
If the subquery compares scalar values, we can remove the condition that
was wrapped into trig_cond (it will be checked when needed by the subquery
engine)
@@ -693,6 +691,12 @@ err:
and non-NULL values, we'll do a full table scan and will rely on the
equalities corresponding to non-NULL parts of left tuple to filter out
non-matching records.
+
+ TODO: We can remove the equalities that will be guaranteed to be true by the
+ fact that subquery engine will be using index lookup. This must be done only
+ for cases where there are no conversion errors of significance, e.g. 257
+ that is searched in a byte. But this requires homogenization of the return
+ codes of all Field*::store() methods.
*/
void JOIN::remove_subq_pushed_predicates(Item **where)
@@ -700,17 +704,13 @@ void JOIN::remove_subq_pushed_predicates(Item **where)
if (conds->type() == Item::FUNC_ITEM &&
((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
- ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM)
+ ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
+ test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
+ ((Item_func *)conds)->arguments()[0]))
{
*where= 0;
return;
}
- if (conds->type() == Item::COND_ITEM &&
- ((class Item_func *)this->conds)->functype() ==
- Item_func::COND_AND_FUNC)
- {
- *where= remove_additional_cond(conds);
- }
}
@@ -888,13 +888,6 @@ JOIN::optimize()
DBUG_PRINT("error",("Error from opt_sum_query"));
DBUG_RETURN(1);
}
- if (res < 0)
- {
- DBUG_PRINT("info",("No matching min/max row"));
- zero_result_cause= "No matching min/max row";
- error=0;
- DBUG_RETURN(0);
- }
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
tables_list= 0; // All tables resolved
@@ -1244,7 +1237,7 @@ JOIN::optimize()
{
if (!having)
{
- Item *where= 0;
+ Item *where= conds;
if (join_tab[0].type == JT_EQ_REF &&
join_tab[0].ref.items[0]->name == in_left_expr_name)
{
@@ -2351,6 +2344,11 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
{
int error;
DBUG_ENTER("get_quick_record_count");
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
+ char buff[STACK_BUFF_ALLOC];
+#endif
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
+ DBUG_RETURN(0); // Fatal error flag is set
if (select)
{
select->head=table;
@@ -3705,7 +3703,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
found_eq_constant=0;
for (i=0 ; i < keyuse->elements-1 ; i++,use++)
{
- if (!use->used_tables)
+ if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
use->table->const_key_parts[use->key]|= use->keypart_map;
if (use->keypart != FT_KEYPART)
{
@@ -5393,7 +5391,8 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
(keyuse->val->type() == Item::REF_ITEM &&
((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
- Item_ref::DIRECT_REF) )
+ Item_ref::DIRECT_REF &&
+ keyuse->val->real_item()->type() == Item::FIELD_ITEM))
return new store_key_field(thd,
key_part->field,
key_buff + maybe_null,
@@ -9055,6 +9054,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
*((*copy_func)++) = item; // Save for copy_funcs
if (modify_item)
item->set_result_field(new_field);
+ if (item->type() == Item::NULL_ITEM)
+ new_field->is_created_from_null_item= TRUE;
return new_field;
}
@@ -10321,7 +10322,8 @@ Next_select_func setup_end_select_func(JOIN *join)
/* Set up select_end */
if (table)
{
- if (table->group && tmp_tbl->sum_func_count)
+ if (table->group && tmp_tbl->sum_func_count &&
+ !tmp_tbl->precomputed_group_by)
{
if (table->s->keys)
{
@@ -11952,8 +11954,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item,1))
{
+ right_item= right_item->real_item();
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
+ /* remove equalities injected by IN->EXISTS transformation */
+ else if (right_item->type() == Item::CACHE_ITEM)
+ return ((Item_cache *)right_item)->eq_def (field);
if (right_item->const_item() && !(right_item->is_null()))
{
/*
@@ -15392,7 +15398,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{
if (tab->use_quick == 2)
{
- char buf[MAX_KEY/8+1];
+ /* 4 bits per 1 hex digit + terminating '\0' */
+ char buf[MAX_KEY / 4 + 1];
extra.append(STRING_WITH_LEN("; Range checked for each "
"record (index map: 0x"));
extra.append(tab->keys.print(buf));