summaryrefslogtreecommitdiff
path: root/sql/opt_subselect.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-09-18 13:07:31 +0200
committerSergei Golubchik <sergii@pisem.net>2013-09-18 13:07:31 +0200
commit4ec2e9d7eda78d409d1b017ef4d8928fe9055438 (patch)
tree6c3a74a740d3c1c5f3a7d1f8154d8a791b435b3f /sql/opt_subselect.cc
parent1a2a9d74fe1256554eceb09bbc6752a6376df87d (diff)
parent197bdbae4db78ba65f3668803bebd3c4a4509ae5 (diff)
downloadmariadb-git-4ec2e9d7eda78d409d1b017ef4d8928fe9055438.tar.gz
5.5 merge and fixes for compiler/test errors
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r--sql/opt_subselect.cc48
1 files changed, 46 insertions, 2 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index d862c4cdac0..f218e4c35f2 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5218,10 +5218,12 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
{
eq_cond= new Item_func_eq(subq_pred->left_expr->element_index(i),
new_sink->row[i]);
- if (!eq_cond || eq_cond->fix_fields(join->thd, &eq_cond))
+ if (!eq_cond)
DBUG_RETURN(1);
- (*join_where)= and_items(*join_where, eq_cond);
+ if (!((*join_where)= and_items(*join_where, eq_cond)) ||
+ (*join_where)->fix_fields(join->thd, join_where))
+ DBUG_RETURN(1);
}
}
else
@@ -5236,6 +5238,12 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
DBUG_RETURN(1);
table->table= dummy_table;
table->table->pos_in_table_list= table;
+ /*
+ Note: the table created above may be freed by:
+ 1. JOIN_TAB::cleanup(), when the parent join is a regular join.
+ 2. cleanup_empty_jtbm_semi_joins(), when the parent join is a
+ degenerate join (e.g. one with "Impossible where").
+ */
setup_table_map(table->table, table, table->jtbm_table_no);
}
else
@@ -5268,6 +5276,42 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
}
+/*
+ Cleanup non-merged semi-joins (JBMs) that have empty.
+
+ This function is to cleanups for a special case:
+ Consider a query like
+
+ select * from t1 where 1=2 AND t1.col IN (select max(..) ... having 1=2)
+
+ For this query, optimization of subquery will short-circuit, and
+ setup_jtbm_semi_joins() will call create_dummy_tmp_table() so that we have
+ empty, constant temp.table to stand in as materialized temp. table.
+
+ Now, suppose that the upper join is also found to be degenerate. In that
+ case, no JOIN_TAB array will be produced, and hence, JOIN::cleanup() will
+ have a problem with cleaning up empty JTBMs (non-empty ones are cleaned up
+ through Item::cleanup() calls).
+*/
+
+void cleanup_empty_jtbm_semi_joins(JOIN *join)
+{
+ List_iterator<TABLE_LIST> li(*join->join_list);
+ TABLE_LIST *table;
+ while ((table= li++))
+ {
+ if ((table->jtbm_subselect && table->jtbm_subselect->is_jtbm_const_tab))
+ {
+ if (table->table)
+ {
+ free_tmp_table(join->thd, table->table);
+ table->table= NULL;
+ }
+ }
+ }
+}
+
+
/**
Choose an optimal strategy to execute an IN/ALL/ANY subquery predicate
based on cost.