mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-536: LP:1050806 - different result for a query using subquery, and
MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed: backport the fix developed for SHOW EXPLAIN: revision-id: psergey@askmonty.org-20120719115219-212cxmm6qvf0wlrb branch nick: 5.5-show-explain-r21 timestamp: Thu 2012-07-19 15:52:19 +0400 BUG#992942 & MDEV-325: Pre-liminary commit for testing and adjust it so that it handles DS-MRR scans correctly.
This commit is contained in:
@ -180,6 +180,32 @@ SET optimizer_switch=@tmp_optimizer_switch;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
#
|
#
|
||||||
|
# MDEV-536: LP:1050806 - different result for a query using subquery
|
||||||
|
#
|
||||||
|
DROP TABLE IF EXISTS `t1`;
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 't1'
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`node_uid` bigint(20) unsigned DEFAULT NULL,
|
||||||
|
`date` datetime DEFAULT NULL,
|
||||||
|
`mirror_date` datetime DEFAULT NULL,
|
||||||
|
KEY `date` (`date`)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
node_uid date mirror_date result
|
||||||
|
2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
|
# MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a int, b int, INDEX idx(a));
|
CREATE TABLE t1 (a int, b int, INDEX idx(a));
|
||||||
@ -197,5 +223,76 @@ a b
|
|||||||
1 0
|
1 0
|
||||||
1 1
|
1 1
|
||||||
1 3
|
1 3
|
||||||
DROP TABLE t1, t2, t3;
|
set @tmp_mdev567=@@optimizer_switch;
|
||||||
|
set optimizer_switch='mrr=off';
|
||||||
|
SELECT * FROM t3
|
||||||
|
WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2
|
||||||
|
WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
|
||||||
|
AND t3.b = t1.b
|
||||||
|
GROUP BY t1.b);
|
||||||
|
a b
|
||||||
|
1 0
|
||||||
|
1 1
|
||||||
|
1 3
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
set optimizer_switch=@tmp_mdev567;
|
||||||
|
#
|
||||||
|
# MDEV-614, also MDEV-536, also LP:1050806:
|
||||||
|
# different result for a query using subquery between 5.5.25 and 5.5.27
|
||||||
|
#
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`node_uid` bigint(20) unsigned DEFAULT NULL,
|
||||||
|
`date` datetime DEFAULT NULL,
|
||||||
|
`mirror_date` datetime DEFAULT NULL,
|
||||||
|
KEY `date` (`date`)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
explain
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 range date date 9 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
node_uid date mirror_date result
|
||||||
|
2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
set @tmp_mdev614=@@optimizer_switch;
|
||||||
|
set optimizer_switch='mrr=off';
|
||||||
|
explain
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 range date date 9 NULL 2 Using index condition; Using where; Using filesort
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
node_uid date mirror_date result
|
||||||
|
2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
|
||||||
|
set optimizer_switch=@tmp_mdev614;
|
||||||
|
DROP TABLE t1;
|
||||||
set optimizer_switch=@subselect2_test_tmp;
|
set optimizer_switch=@subselect2_test_tmp;
|
||||||
|
@ -203,6 +203,32 @@ SET optimizer_switch=@tmp_optimizer_switch;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-536: LP:1050806 - different result for a query using subquery
|
||||||
|
--echo #
|
||||||
|
DROP TABLE IF EXISTS `t1`;
|
||||||
|
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`node_uid` bigint(20) unsigned DEFAULT NULL,
|
||||||
|
`date` datetime DEFAULT NULL,
|
||||||
|
`mirror_date` datetime DEFAULT NULL,
|
||||||
|
KEY `date` (`date`)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
|
--echo # MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
|
||||||
--echo #
|
--echo #
|
||||||
@ -220,7 +246,75 @@ SELECT * FROM t3
|
|||||||
WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
|
WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
|
||||||
AND t3.b = t1.b
|
AND t3.b = t1.b
|
||||||
GROUP BY t1.b);
|
GROUP BY t1.b);
|
||||||
DROP TABLE t1, t2, t3;
|
|
||||||
|
|
||||||
|
set @tmp_mdev567=@@optimizer_switch;
|
||||||
|
set optimizer_switch='mrr=off';
|
||||||
|
SELECT * FROM t3
|
||||||
|
WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2
|
||||||
|
WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
|
||||||
|
AND t3.b = t1.b
|
||||||
|
GROUP BY t1.b);
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
set optimizer_switch=@tmp_mdev567;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-614, also MDEV-536, also LP:1050806:
|
||||||
|
--echo # different result for a query using subquery between 5.5.25 and 5.5.27
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`node_uid` bigint(20) unsigned DEFAULT NULL,
|
||||||
|
`date` datetime DEFAULT NULL,
|
||||||
|
`mirror_date` datetime DEFAULT NULL,
|
||||||
|
KEY `date` (`date`)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
|
||||||
|
|
||||||
|
explain
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
|
||||||
|
set @tmp_mdev614=@@optimizer_switch;
|
||||||
|
set optimizer_switch='mrr=off';
|
||||||
|
explain
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT node_uid, date, mirror_date, @result := 0 AS result
|
||||||
|
FROM t1
|
||||||
|
WHERE date < '2012-12-12 12:12:12'
|
||||||
|
AND node_uid in (2085, 2084)
|
||||||
|
ORDER BY mirror_date ASC
|
||||||
|
) AS calculated_result;
|
||||||
|
|
||||||
|
set optimizer_switch=@tmp_mdev614;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
set optimizer_switch=@subselect2_test_tmp;
|
set optimizer_switch=@subselect2_test_tmp;
|
||||||
|
|
||||||
|
@ -10944,6 +10944,13 @@ int QUICK_RANGE_SELECT::reset()
|
|||||||
DBUG_ENTER("QUICK_RANGE_SELECT::reset");
|
DBUG_ENTER("QUICK_RANGE_SELECT::reset");
|
||||||
last_range= NULL;
|
last_range= NULL;
|
||||||
cur_range= (QUICK_RANGE**) ranges.buffer;
|
cur_range= (QUICK_RANGE**) ranges.buffer;
|
||||||
|
|
||||||
|
if (file->inited == handler::RND)
|
||||||
|
{
|
||||||
|
/* Handler could be left in this state by MRR */
|
||||||
|
if ((error= file->ha_rnd_end()))
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
if (file->inited == handler::NONE)
|
if (file->inited == handler::NONE)
|
||||||
{
|
{
|
||||||
|
@ -10603,9 +10603,22 @@ void JOIN::cleanup(bool full)
|
|||||||
|
|
||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
|
JOIN_TAB *sort_tab= first_linear_tab(this, WITHOUT_CONST_TABLES);
|
||||||
|
if (pre_sort_join_tab)
|
||||||
|
{
|
||||||
|
if (sort_tab && sort_tab->select == pre_sort_join_tab->select)
|
||||||
|
{
|
||||||
|
pre_sort_join_tab->select= NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
clean_pre_sort_join_tab();
|
||||||
|
}
|
||||||
|
|
||||||
for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
|
for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
|
||||||
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
|
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
|
||||||
|
{
|
||||||
tab->cleanup();
|
tab->cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -18849,6 +18862,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
TABLE *table;
|
TABLE *table;
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
JOIN_TAB *tab;
|
JOIN_TAB *tab;
|
||||||
|
int err= 0;
|
||||||
|
bool quick_created= FALSE;
|
||||||
DBUG_ENTER("create_sort_index");
|
DBUG_ENTER("create_sort_index");
|
||||||
|
|
||||||
if (join->table_count == join->const_tables)
|
if (join->table_count == join->const_tables)
|
||||||
@ -18856,18 +18871,61 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
tab= join->join_tab + join->const_tables;
|
tab= join->join_tab + join->const_tables;
|
||||||
table= tab->table;
|
table= tab->table;
|
||||||
select= tab->select;
|
select= tab->select;
|
||||||
|
|
||||||
|
JOIN_TAB *save_pre_sort_join_tab= NULL;
|
||||||
|
if (join->pre_sort_join_tab)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
we've already been in this function, and stashed away the original access
|
||||||
|
method in join->pre_sort_join_tab, restore it now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* First, restore state of the handler */
|
||||||
|
if (join->pre_sort_index != MAX_KEY)
|
||||||
|
{
|
||||||
|
if (table->file->ha_index_or_rnd_end())
|
||||||
|
goto err;
|
||||||
|
if (join->pre_sort_idx_pushed_cond)
|
||||||
|
{
|
||||||
|
table->file->idx_cond_push(join->pre_sort_index,
|
||||||
|
join->pre_sort_idx_pushed_cond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (table->file->ha_index_or_rnd_end() ||
|
||||||
|
table->file->ha_rnd_init(TRUE))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second, restore access method parameters */
|
||||||
|
tab->records= join->pre_sort_join_tab->records;
|
||||||
|
tab->select= join->pre_sort_join_tab->select;
|
||||||
|
tab->select_cond= join->pre_sort_join_tab->select_cond;
|
||||||
|
tab->type= join->pre_sort_join_tab->type;
|
||||||
|
tab->read_first_record= join->pre_sort_join_tab->read_first_record;
|
||||||
|
|
||||||
|
save_pre_sort_join_tab= join->pre_sort_join_tab;
|
||||||
|
join->pre_sort_join_tab= NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Save index #, save index condition. Do it right now, because MRR may
|
||||||
|
*/
|
||||||
|
if (table->file->inited == handler::INDEX)
|
||||||
|
{
|
||||||
|
join->pre_sort_index= table->file->active_index;
|
||||||
|
join->pre_sort_idx_pushed_cond= table->file->pushed_idx_cond;
|
||||||
|
// no need to save key_read
|
||||||
|
}
|
||||||
|
else
|
||||||
|
join->pre_sort_index= MAX_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Currently ORDER BY ... LIMIT is not supported in subqueries. */
|
/* Currently ORDER BY ... LIMIT is not supported in subqueries. */
|
||||||
DBUG_ASSERT(join->group_list || !join->is_in_subquery());
|
DBUG_ASSERT(join->group_list || !join->is_in_subquery());
|
||||||
|
|
||||||
/*
|
|
||||||
If we have a select->quick object that is created outside of
|
|
||||||
create_sort_index() and this is part of a subquery that
|
|
||||||
potentially can be executed multiple times then we should not
|
|
||||||
delete the quick object on exit from this function.
|
|
||||||
*/
|
|
||||||
bool keep_quick= select && select->quick && join->join_tab_save;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
|
When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
|
||||||
and thus force sorting on disk unless a group min-max optimization
|
and thus force sorting on disk unless a group min-max optimization
|
||||||
@ -18919,7 +18977,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
get_quick_select_for_ref(thd, table, &tab->ref,
|
get_quick_select_for_ref(thd, table, &tab->ref,
|
||||||
tab->found_records))))
|
tab->found_records))))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_ASSERT(!keep_quick);
|
quick_created= TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18935,7 +18993,27 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
table->sort.found_records=filesort(thd, table,join->sortorder, length,
|
table->sort.found_records=filesort(thd, table,join->sortorder, length,
|
||||||
select, filesort_limit, 0,
|
select, filesort_limit, 0,
|
||||||
&examined_rows);
|
&examined_rows);
|
||||||
|
|
||||||
|
if (quick_created)
|
||||||
|
{
|
||||||
|
/* This will delete the quick select. */
|
||||||
|
select->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!join->pre_sort_join_tab)
|
||||||
|
{
|
||||||
|
if (save_pre_sort_join_tab)
|
||||||
|
join->pre_sort_join_tab= save_pre_sort_join_tab;
|
||||||
|
else if (!(join->pre_sort_join_tab= (JOIN_TAB*)thd->alloc(sizeof(JOIN_TAB))))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(join->pre_sort_join_tab)= *tab;
|
||||||
|
|
||||||
|
/*TODO: here, close the index scan, cancel index-only read. */
|
||||||
tab->records= table->sort.found_records; // For SQL_CALC_ROWS
|
tab->records= table->sort.found_records; // For SQL_CALC_ROWS
|
||||||
|
#if 0
|
||||||
|
/* MariaDB doesn't need the following: */
|
||||||
if (select)
|
if (select)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -18952,6 +19030,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
tablesort_result_cache= table->sort.io_cache;
|
tablesort_result_cache= table->sort.io_cache;
|
||||||
table->sort.io_cache= NULL;
|
table->sort.io_cache= NULL;
|
||||||
|
|
||||||
|
// select->cleanup(); // filesort did select
|
||||||
/*
|
/*
|
||||||
If a quick object was created outside of create_sort_index()
|
If a quick object was created outside of create_sort_index()
|
||||||
that might be reused, then do not call select->cleanup() since
|
that might be reused, then do not call select->cleanup() since
|
||||||
@ -18974,18 +19053,61 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||||||
// Restore the output resultset
|
// Restore the output resultset
|
||||||
table->sort.io_cache= tablesort_result_cache;
|
table->sort.io_cache= tablesort_result_cache;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
tab->select=NULL;
|
||||||
tab->set_select_cond(NULL, __LINE__);
|
tab->set_select_cond(NULL, __LINE__);
|
||||||
tab->last_inner= 0;
|
|
||||||
tab->first_unmatched= 0;
|
|
||||||
tab->type=JT_ALL; // Read with normal read_record
|
tab->type=JT_ALL; // Read with normal read_record
|
||||||
tab->read_first_record= join_init_read_record;
|
tab->read_first_record= join_init_read_record;
|
||||||
|
tab->table->file->ha_index_or_rnd_end();
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto err;
|
||||||
|
|
||||||
tab->join->examined_rows+=examined_rows;
|
tab->join->examined_rows+=examined_rows;
|
||||||
table->disable_keyread(); // Restore if we used indexes
|
|
||||||
DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
|
DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
|
||||||
err:
|
err:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JOIN::clean_pre_sort_join_tab()
|
||||||
|
{
|
||||||
|
//TABLE *table= pre_sort_join_tab->table;
|
||||||
|
/*
|
||||||
|
Note: we can come here for fake_select_lex object. That object will have
|
||||||
|
the table already deleted by st_select_lex_unit::cleanup().
|
||||||
|
We rely on that fake_select_lex didn't have quick select.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
if (pre_sort_join_tab->select && pre_sort_join_tab->select->quick)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We need to preserve tablesort's output resultset here, because
|
||||||
|
QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT (called by
|
||||||
|
SQL_SELECT::cleanup()) may free it assuming it's the result of the quick
|
||||||
|
select operation that we no longer need. Note that all the other parts of
|
||||||
|
this data structure are cleaned up when
|
||||||
|
QUICK_INDEX_MERGE_SELECT::get_next encounters end of data, so the next
|
||||||
|
SQL_SELECT::cleanup() call changes sort.io_cache alone.
|
||||||
|
*/
|
||||||
|
IO_CACHE *tablesort_result_cache;
|
||||||
|
|
||||||
|
tablesort_result_cache= table->sort.io_cache;
|
||||||
|
table->sort.io_cache= NULL;
|
||||||
|
pre_sort_join_tab->select->cleanup();
|
||||||
|
table->quick_keys.clear_all(); // as far as we cleanup select->quick
|
||||||
|
table->intersect_keys.clear_all();
|
||||||
|
table->sort.io_cache= tablesort_result_cache;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//table->disable_keyread(); // Restore if we used indexes
|
||||||
|
if (pre_sort_join_tab->select && pre_sort_join_tab->select->quick)
|
||||||
|
{
|
||||||
|
pre_sort_join_tab->select->cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Remove duplicates from tmp table
|
Remove duplicates from tmp table
|
||||||
This should be recoded to add a unique index to the table and remove
|
This should be recoded to add a unique index to the table and remove
|
||||||
|
@ -897,6 +897,14 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
JOIN_TAB *join_tab, **best_ref;
|
JOIN_TAB *join_tab, **best_ref;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Saved join_tab for pre_sorting. create_sort_index() will save here..
|
||||||
|
*/
|
||||||
|
JOIN_TAB *pre_sort_join_tab;
|
||||||
|
uint pre_sort_index;
|
||||||
|
Item *pre_sort_idx_pushed_cond;
|
||||||
|
void clean_pre_sort_join_tab();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For "Using temporary+Using filesort" queries, JOIN::join_tab can point to
|
For "Using temporary+Using filesort" queries, JOIN::join_tab can point to
|
||||||
@ -1279,6 +1287,8 @@ public:
|
|||||||
outer_ref_cond= pseudo_bits_cond= NULL;
|
outer_ref_cond= pseudo_bits_cond= NULL;
|
||||||
in_to_exists_where= NULL;
|
in_to_exists_where= NULL;
|
||||||
in_to_exists_having= NULL;
|
in_to_exists_having= NULL;
|
||||||
|
|
||||||
|
pre_sort_join_tab= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
||||||
|
Reference in New Issue
Block a user