summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/filesort.cc6
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item.h3
-rw-r--r--sql/item_cmpfunc.cc7
-rw-r--r--sql/item_cmpfunc.h3
-rw-r--r--sql/item_func.cc1
-rw-r--r--sql/item_subselect.cc4
-rw-r--r--sql/sql_select.cc21
8 files changed, 41 insertions, 5 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 63a8515020b..38a49e24263 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -387,7 +387,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
byte *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
my_off_t record;
TABLE *sort_form;
- volatile my_bool *killed= &current_thd->killed;
+ THD *thd= current_thd;
+ volatile my_bool *killed= &thd->killed;
handler *file;
DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s",(select?select->quick?"ranges":"where":"every row")));
@@ -474,6 +475,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
else
file->unlock_row();
+ /* It does not make sense to read more keys in case of a fatal error */
+ if (thd->net.report_error)
+ DBUG_RETURN(HA_POS_ERROR);
}
(void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
if (!next_pos)
diff --git a/sql/item.cc b/sql/item.cc
index 1e8c70c6616..7d110ccdc25 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -47,6 +47,7 @@ Item::Item():
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
name= 0;
decimals= 0; max_length= 0;
+ with_subselect= 0;
/* Put item in free list so that we can free all items at end */
THD *thd= current_thd;
diff --git a/sql/item.h b/sql/item.h
index ad8bea663f1..f2136c4997a 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -142,6 +142,9 @@ public:
my_bool with_sum_func;
my_bool fixed; /* If item fixed with fix_fields */
DTCollation collation;
+ my_bool with_subselect; /* If this item is a subselect or some
+ of its arguments is or contains a
+ subselect */
// alloc & destruct is done as start of select using sql_alloc
Item();
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 859b4e0ecc1..91546c2282c 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2139,6 +2139,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
and_tables_cache&= tmp_table_map;
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
+ with_subselect|= item->with_subselect;
if (item->maybe_null)
maybe_null=1;
}
@@ -2351,7 +2352,7 @@ longlong Item_func_isnull::val_int()
Handle optimization if the argument can't be null
This has to be here because of the test in update_used_tables().
*/
- if (!used_tables_cache)
+ if (!used_tables_cache && !with_subselect)
return cached_value;
return args[0]->is_null() ? 1: 0;
}
@@ -2360,7 +2361,7 @@ longlong Item_is_not_null_test::val_int()
{
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_is_not_null_test::val_int");
- if (!used_tables_cache)
+ if (!used_tables_cache && !with_subselect)
{
owner->was_null|= (!cached_value);
DBUG_PRINT("info", ("cached :%d", cached_value));
@@ -2387,7 +2388,7 @@ void Item_is_not_null_test::update_used_tables()
else
{
args[0]->update_used_tables();
- if (!(used_tables_cache=args[0]->used_tables()))
+ if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
{
/* Remember if the value is always NULL or never NULL */
cached_value= (longlong) !args[0]->is_null();
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 0e157fd412c..4635a301c31 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -843,7 +843,8 @@ public:
else
{
args[0]->update_used_tables();
- if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())))
+ if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
+ !with_subselect)
{
/* Remember if the value is always NULL or never NULL */
cached_value= (longlong) args[0]->is_null();
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 461998477b5..92ba7520642 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -177,6 +177,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
used_tables_cache|= item->used_tables();
not_null_tables_cache|= item->not_null_tables();
const_item_cache&= item->const_item();
+ with_subselect|= item->with_subselect;
}
}
fix_length_and_dec();
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 20a092d7607..cdbcde8b56b 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -39,6 +39,7 @@ Item_subselect::Item_subselect():
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
const_item_cache(1), engine_changed(0), changed(0)
{
+ with_subselect= 1;
reset();
/*
item value is NULL if select_subselect not changed this value
@@ -201,6 +202,9 @@ bool Item_subselect::exec()
mem root
*/
thd->mem_root= &thd->main_mem_root;
+ if (thd->net.report_error)
+ /* Do not execute subselect in case of a fatal error */
+ return 1;
res= engine->exec();
thd->mem_root= old_root;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0254e8f56dc..97fa6bb7809 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -644,6 +644,13 @@ JOIN::optimize()
{
ORDER *org_order= order;
order=remove_const(this, order,conds,1, &simple_order);
+ if (thd->net.report_error)
+ {
+ error= 1;
+ DBUG_PRINT("error",("Error from remove_const"));
+ DBUG_RETURN(1);
+ }
+
/*
If we are using ORDER BY NULL or ORDER BY const_expression,
return result in any order (even if we are using a GROUP BY)
@@ -747,6 +754,12 @@ JOIN::optimize()
group_list= remove_const(this, (old_group_list= group_list), conds,
rollup.state == ROLLUP::STATE_NONE,
&simple_group);
+ if (thd->net.report_error)
+ {
+ error= 1;
+ DBUG_PRINT("error",("Error from remove_const"));
+ DBUG_RETURN(1);
+ }
if (old_group_list && !group_list)
select_distinct= 0;
}
@@ -763,6 +776,12 @@ JOIN::optimize()
{
group_list= procedure->group= remove_const(this, procedure->group, conds,
1, &simple_group);
+ if (thd->net.report_error)
+ {
+ error= 1;
+ DBUG_PRINT("error",("Error from remove_const"));
+ DBUG_RETURN(1);
+ }
calc_group_buffer(this, group_list);
}
@@ -4428,6 +4447,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
+ if (order->item[0]->with_subselect)
+ order->item[0]->val_str(&order->item[0]->str_value);
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue; // skip const item
}