summaryrefslogtreecommitdiff
path: root/sql/sql_list.h
diff options
context:
space:
mode:
authorunknown <timour@askmonty.org>2011-04-28 17:15:05 +0300
committerunknown <timour@askmonty.org>2011-04-28 17:15:05 +0300
commit0f4236659c2af3720d57255e224b3a8bb4f1d697 (patch)
tree1dfb7d1a272788e17bda823cacfb4061cc03f659 /sql/sql_list.h
parent9d20163536dcb5a66411e33cf9f9d3e68c76fe6e (diff)
downloadmariadb-git-0f4236659c2af3720d57255e224b3a8bb4f1d697.tar.gz
Fix LP BUG#718593
Analysis: Build_equal_items_for_cond() rewrites the WHERE clause in such a way, that it may merge the list join->cond_equal->current_level with the list of child Items in an AND condition of the WHERE clause. The place where this is done is: static COND *build_equal_items_for_cond(THD *thd, COND *cond, COND_EQUAL *inherited) { ... if (and_level) { args->concat(&eq_list); args->concat((List<Item> *)&cond_equal.current_level); } ... } As a result, later transformations on the WHERE clause may change the structure of the list join->cond_equal->current_level without knowing this. Specifically in this bug, Item_in_subselect::inject_in_to_exists_cond creates a new AND of the old WHERE clause and the IN->EXISTS conditions. It then calls fix_fields() for the new AND. Among other things, fix_fields flattens all nested ANDs into one by merging the AND argument lists. When there is a cond_equal for the JOIN, its list of Item_equal objects is attached to the end of the original AND. When a lower-level AND is merged into the top-level one, the argument list of the lower-level AND is concatenated to the list of multiple equalities in the upper-level AND. As a result, when substitute_for_best_equal_field processes the multiple equalities, it turns out that the multiple equality list contains the Items from the lower-level AND which were concatenated to the end of the join->cond_equal->current_level list. This results in a crash because this list must not contain any other Items except for the previously found Item_equal ones. Solution: When performing IN->EXIST predicate injection, and the where clause is an AND, detach the list of Item_equal objects before calling fix_fields on the injected where clause. After fix_fields is done, reattach back the multiple equalities list to the end of the argument list of the new AND.
Diffstat (limited to 'sql/sql_list.h')
-rw-r--r--sql/sql_list.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 2dade14f211..e90f16aeb99 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -260,7 +260,7 @@ public:
list_node *node= first;
list_node *list_first= list->first;
elements=0;
- while (node && node != list_first)
+ while (node->info && node != list_first)
{
prev= &node->next;
node= node->next;