diff options
author | Sreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com> | 2015-10-01 07:45:27 +0530 |
---|---|---|
committer | Sreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com> | 2015-10-01 07:45:27 +0530 |
commit | 415faa122b9c683661dafac82fff414fa6864151 (patch) | |
tree | 9c2c434f3d7aee19a50a28fcdd9de82f23d54bf7 /sql/item_subselect.cc | |
parent | f83d9e4217827b4d0b078bc93dff7d8f173adbef (diff) | |
download | mariadb-git-415faa122b9c683661dafac82fff414fa6864151.tar.gz |
Bug #19434916: FATAL_SIGNAL IN ADD_KEY_EQUAL_FIELDS() WITH
UPDATE VIEW USING OUTER SUBQUERY
Issue:
-----
While resolving a column which refers to a table/view in an
outer query, it's respecitve item object is marked with the
outer query's select_lex object. But when the column refers
to a view or if the column is part of a subquery in the
HAVING clause, an Item_ref object is created. While the
reference to the outer query is stored by the Item_ref
object, the same is not stored in it's real_item.
This creates a problem with the IN-TO-EXISTS optmization.
When there is an index over the column in the inner query,
it will be considered since the column's real_item object
will be mistaken for a local field. This will lead to a
crash.
SOLUTION:
---------
Under the current design, the only way to fix this issue is
to check the reginfo.join_tab for a NULL value. If yes, the
query should not be worrying about the key use.
The testcase and comments added as part of the fix for
Bug#17766653 have been backported.
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c9c625db083..43af0b5a3f6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1072,6 +1072,27 @@ Item_in_subselect::single_value_transformer(JOIN *join, runtime created Ref item which is deleted at the end of the statement. Thus one of 'substitution' arguments can be broken in case of PS. + + @todo + Why do we use real_item()/substitutional_item() instead of the plain + left_expr? + Because left_expr might be a rollbackable item, and we fail to properly + rollback all copies of left_expr at end of execution, so we want to + avoid creating copies of left_expr as much as possible, so we use + real_item() instead. + Doing a proper rollback is difficult: the change was registered for the + original item which was the left argument of IN. Then this item was + copied to left_expr, which is copied below to substitution->args[0]. To + do a proper rollback, we would have to restore the content + of both copies as well as the original item. There might be more copies, + if AND items have been constructed. + The same applies to the right expression. + However, using real_item()/substitutional_item() brings its own + problems: for example, we lose information that the item is an outer + reference; the item can thus wrongly be considered for a Keyuse (causing + bug#17766653). + When WL#6570 removes the "rolling back" system, all + real_item()/substitutional_item() in this file should be removed. */ substitution= func->create(left_expr->real_item(), subs); DBUG_RETURN(RES_OK); @@ -1157,6 +1178,9 @@ Item_in_subselect::single_value_transformer(JOIN *join, } else { + /* + Grep for "WL#6570" to see the relevant comment about real_item. + */ Item *item= (Item*) select_lex->item_list.head()->real_item(); if (select_lex->table_list.elements) |