summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
authorGleb Shchepa <gshchepa@mysql.com>2010-05-31 16:52:19 +0400
committerGleb Shchepa <gshchepa@mysql.com>2010-05-31 16:52:19 +0400
commit3ca98f76695772bf8e55cac20e1d197a7b6e3615 (patch)
treea2e471c1c7859e245a55b668173deda4acb02b85 /sql/item.h
parent5c72bee9d4b935015db83ff1b8b5baf72c975e32 (diff)
downloadmariadb-git-3ca98f76695772bf8e55cac20e1d197a7b6e3615.tar.gz
Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY
when it should use index Sometimes the LEFT/RIGHT JOIN with an empty table caused an unnecessary filesort. Sample query, where t1.i1 is indexed and t3 is empty: SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 LEFT JOIN t3 ON t2.i2 = t3.i3 ORDER BY t1.i1 LIMIT 5; The server erroneously used an item of empty outer-joined table as a common constant of a Item_equal (multi-equivalence expression). By the fix for the bug 16590 the constant status of such an item has been propagated to st_table::const_key_parts map bits related to other Item_equal argument-related key parts (those are obviously not constant in our case). As far as test_if_skip_sort_order function skips constant prefixes of testing keys, this caused an ignorance of available indices, since some prefixes were marked as constant by mistake.
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/sql/item.h b/sql/item.h
index 6398e9bffb7..e441a6ff261 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1181,6 +1181,10 @@ public:
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
fix_char_length(max_char_length_arg);
}
+ /*
+ Return TRUE if the item points to a column of an outer-joined table.
+ */
+ virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
};
@@ -1694,6 +1698,11 @@ public:
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *update_value_transformer(uchar *select_arg);
virtual void print(String *str, enum_query_type query_type);
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ return field->table->pos_in_table_list->outer_join;
+ }
Field::geometry_type get_geometry_type() const
{
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
@@ -2507,6 +2516,12 @@ public:
return (*ref)->get_time(ltime);
}
virtual bool basic_const_item() const { return (*ref)->basic_const_item(); }
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ DBUG_ASSERT(ref);
+ return (*ref)->is_outer_field();
+ }
};