maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #03470
bzr commit into file:///home/tsk/mprog/src/5.3-mwl89/ branch (timour:2802)
#At file:///home/tsk/mprog/src/5.3-mwl89/ based on revid:timour@xxxxxxxxxxxx-20100716105202-8narq4tzhka2n1a5
2802 timour@xxxxxxxxxxxx 2010-07-16 [merge]
Merge main 5.3 into 5.3-mwl89.
added:
mysql-test/r/optimizer_switch.result
mysql-test/t/optimizer_switch.test
modified:
.bzrignore
configure.in
include/queues.h
include/thr_alarm.h
mysql-test/r/index_merge_myisam.result
mysql-test/r/myisam_mrr.result
mysql-test/r/order_by.result
mysql-test/r/subselect_mat.result
mysql-test/r/subselect_no_mat.result
mysql-test/r/subselect_no_opts.result
mysql-test/r/subselect_no_semijoin.result
mysql-test/r/subselect_sj.result
mysql-test/r/subselect_sj_jcl6.result
mysql-test/t/index_merge_myisam.test
mysql-test/t/myisam_mrr.test
mysql-test/t/order_by.test
mysql-test/t/subselect_mat.test
mysql-test/t/subselect_no_mat.test
mysql-test/t/subselect_no_opts.test
mysql-test/t/subselect_no_semijoin.test
mysql-test/t/subselect_sj.test
mysys/queues.c
mysys/thr_alarm.c
sql/create_options.cc
sql/event_queue.cc
sql/filesort.cc
sql/ha_partition.cc
sql/ha_partition.h
sql/item_cmpfunc.cc
sql/item_subselect.cc
sql/mysqld.cc
sql/net_serv.cc
sql/opt_range.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_union.cc
sql/uniques.cc
storage/maria/ma_ft_boolean_search.c
storage/maria/ma_ft_nlq_search.c
storage/maria/ma_sort.c
storage/maria/maria_pack.c
storage/myisam/ft_boolean_search.c
storage/myisam/ft_nlq_search.c
storage/myisam/mi_test_all.sh
storage/myisam/myisampack.c
storage/myisam/sort.c
storage/myisammrg/myrg_queue.c
storage/myisammrg/myrg_rnext.c
storage/myisammrg/myrg_rnext_same.c
storage/myisammrg/myrg_rprev.c
=== modified file '.bzrignore'
--- a/.bzrignore 2010-06-26 10:05:41 +0000
+++ b/.bzrignore 2010-07-16 07:33:01 +0000
@@ -1940,3 +1940,4 @@ sql/client_plugin.c
*.dgcov
libmysqld/create_options.cc
storage/pbxt/bin/xtstat
+libmysqld/sql_expression_cache.cc
=== modified file 'configure.in'
--- a/configure.in 2010-06-26 19:55:33 +0000
+++ b/configure.in 2010-07-16 08:02:05 +0000
@@ -17,7 +17,7 @@ dnl When merging new MySQL releases, upd
dnl MySQL version number.
dnl
dnl Note: the following line must be parseable by win/configure.js:GetVersion()
-AC_INIT([MariaDB Server], [5.2.1-MariaDB-beta], [], [mysql])
+AC_INIT([MariaDB Server], [5.3.0-MariaDB-alpha], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
=== modified file 'include/queues.h'
--- a/include/queues.h 2007-11-14 18:20:31 +0000
+++ b/include/queues.h 2010-07-16 07:33:01 +0000
@@ -1,23 +1,31 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2010 Monty Program Ab
+ 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
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
/*
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
- Copyright Monty Program KB.
- By monty.
*/
#ifndef _queues_h
@@ -31,30 +39,34 @@ typedef struct st_queue {
void *first_cmp_arg;
uint elements;
uint max_elements;
- uint offset_to_key; /* compare is done on element+offset */
+ uint offset_to_key; /* compare is done on element+offset */
+ uint offset_to_queue_pos; /* If we want to store position in element */
+ uint auto_extent;
int max_at_top; /* Normally 1, set to -1 if queue_top gives max */
int (*compare)(void *, uchar *,uchar *);
- uint auto_extent;
} QUEUE;
+#define queue_first_element(queue) 1
+#define queue_last_element(queue) (queue)->elements
#define queue_top(queue) ((queue)->root[1])
-#define queue_element(queue,index) ((queue)->root[index+1])
+#define queue_element(queue,index) ((queue)->root[index])
#define queue_end(queue) ((queue)->root[(queue)->elements])
-#define queue_replaced(queue) _downheap(queue,1)
+#define queue_replace(queue, idx) _downheap(queue, idx, (queue)->root[idx])
+#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1])
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
(queue)->max_at_top= set_arg ? -1 : 1
+#define queue_remove_top(queue_arg) queue_remove((queue_arg), queue_first_element(queue_arg))
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
-int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
- void *first_cmp_arg, uint auto_extent);
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent);
int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,uchar *element);
@@ -62,7 +74,7 @@ int queue_insert_safe(QUEUE *queue, ucha
uchar *queue_remove(QUEUE *queue,uint idx);
#define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
-void _downheap(QUEUE *queue,uint idx);
+void _downheap(QUEUE *queue, uint idx, uchar *element);
void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
=== modified file 'include/thr_alarm.h'
--- a/include/thr_alarm.h 2008-04-28 16:24:05 +0000
+++ b/include/thr_alarm.h 2010-07-16 07:33:01 +0000
@@ -34,7 +34,7 @@ extern "C" {
typedef struct st_alarm_info
{
- ulong next_alarm_time;
+ time_t next_alarm_time;
uint active_alarms;
uint max_used_alarms;
} ALARM_INFO;
@@ -78,10 +78,11 @@ typedef int thr_alarm_entry;
typedef thr_alarm_entry* thr_alarm_t;
typedef struct st_alarm {
- ulong expire_time;
+ time_t expire_time;
thr_alarm_entry alarmed; /* set when alarm is due */
pthread_t thread;
my_thread_id thread_id;
+ uint index_in_queue;
my_bool malloced;
} ALARM;
=== modified file 'mysql-test/r/index_merge_myisam.result'
--- a/mysql-test/r/index_merge_myisam.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/index_merge_myisam.result 2010-07-16 08:58:24 +0000
@@ -1413,66 +1413,6 @@ WHERE
`RUNID`= '' AND `SUBMITNR`= '' AND `ORDERNR`='' AND `PROGRAMM`='' AND
`TESTID`='' AND `UCCHECK`='';
drop table t1;
-#
-# Generic @@optimizer_switch tests (move those into a separate file if
-# we get another @@optimizer_switch user)
-#
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='index_merge=off,index_merge_union=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='index_merge_union=on';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,index_merge_sort_union=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch=4;
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
-set optimizer_switch=NULL;
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL'
-set optimizer_switch='default,index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
-set optimizer_switch='index_merge=index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=index_merge'
-set optimizer_switch='index_merge=on,but...';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'but...'
-set optimizer_switch='index_merge=';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge='
-set optimizer_switch='index_merge';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
-set optimizer_switch='on';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'on'
-set optimizer_switch='index_merge=on,index_merge=off';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off'
-set optimizer_switch='index_merge_union=on,index_merge_union=default';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge_union=default'
-set optimizer_switch='default,index_merge=on,index_merge=off,default';
-ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off,default'
-set optimizer_switch=default;
-set optimizer_switch='index_merge=off,index_merge_union=off,default';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch=default;
-select @@global.optimizer_switch;
-@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set @@global.optimizer_switch=default;
-select @@global.optimizer_switch;
-@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-#
-# Check index_merge's @@optimizer_switch flags
-#
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, c int, filler char(100),
@@ -1580,7 +1520,4 @@ explain select * from t1 where a=10 and
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
set optimizer_switch=default;
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
drop table t0, t1;
=== modified file 'mysql-test/r/myisam_mrr.result'
--- a/mysql-test/r/myisam_mrr.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/myisam_mrr.result 2010-07-16 08:58:24 +0000
@@ -392,9 +392,9 @@ drop table t0, t1;
# Part of MWL#67: DS-MRR backport: add an @@optimizer_switch flag for
# index_condition pushdown:
# - engine_condition_pushdown does not affect ICP
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+select @@optimizer_switch like '%index_condition_pushdown=on%';
+@@optimizer_switch like '%index_condition_pushdown=on%'
+1
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, key(a));
=== added file 'mysql-test/r/optimizer_switch.result'
--- a/mysql-test/r/optimizer_switch.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/optimizer_switch.result 2010-07-16 08:58:24 +0000
@@ -0,0 +1,99 @@
+#
+# Generic @@optimizer_switch tests
+#
+#
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='index_merge=off,index_merge_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='index_merge_union=on';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,index_merge_sort_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch=4;
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
+set optimizer_switch=NULL;
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL'
+set optimizer_switch='default,index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
+set optimizer_switch='index_merge=index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=index_merge'
+set optimizer_switch='index_merge=on,but...';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'but...'
+set optimizer_switch='index_merge=';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge='
+set optimizer_switch='index_merge';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
+set optimizer_switch='on';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'on'
+set optimizer_switch='index_merge=on,index_merge=off';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off'
+set optimizer_switch='index_merge_union=on,index_merge_union=default';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge_union=default'
+set optimizer_switch='default,index_merge=on,index_merge=off,default';
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=off,default'
+set optimizer_switch=default;
+set optimizer_switch='index_merge=off,index_merge_union=off,default';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set @@global.optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+#
+# Check index_merge's @@optimizer_switch flags
+#
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+
+BUG#37120 optimizer_switch allowable values not according to specification
+
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,semijoin=off,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,materialization=off,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,semijoin=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch='default,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+set optimizer_switch=default;
=== modified file 'mysql-test/r/order_by.result'
--- a/mysql-test/r/order_by.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/order_by.result 2010-07-15 14:07:01 +0000
@@ -607,9 +607,14 @@ FieldKey LongVal StringVal
1 0 2
1 1 3
1 2 1
-EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because
+DS-MRR: records_in_range/read_time return the same numbers for all three indexes
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 38 NULL 4 Using index condition; Using where; Using MRR; Using filesort
+1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Using MRR; Using filesort
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range StringField StringField 38 NULL 4 Using where; Using filesort
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
FieldKey LongVal StringVal
3 1 2
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result 2010-07-16 10:52:02 +0000
+++ b/mysql-test/r/subselect_mat.result 2010-07-16 12:10:55 +0000
@@ -1246,3 +1246,29 @@ i
4
set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
=== modified file 'mysql-test/r/subselect_no_mat.result'
--- a/mysql-test/r/subselect_no_mat.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/subselect_no_mat.result 2010-07-16 08:58:24 +0000
@@ -1,6 +1,6 @@
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
set optimizer_switch='materialization=off';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
set @save_optimizer_switch=@@optimizer_switch;
@@ -4925,6 +4925,6 @@ DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
set optimizer_switch=default;
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
=== modified file 'mysql-test/r/subselect_no_opts.result'
--- a/mysql-test/r/subselect_no_opts.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/subselect_no_opts.result 2010-07-16 08:58:24 +0000
@@ -1,6 +1,3 @@
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
set optimizer_switch='materialization=off,semijoin=off';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
set @save_optimizer_switch=@@optimizer_switch;
@@ -4925,6 +4922,3 @@ DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
set optimizer_switch=default;
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result 2010-07-16 08:58:24 +0000
@@ -1,6 +1,3 @@
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
set optimizer_switch='semijoin=off';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
set @save_optimizer_switch=@@optimizer_switch;
@@ -4925,6 +4922,3 @@ DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
set optimizer_switch=default;
-show variables like 'optimizer_switch';
-Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
=== modified file 'mysql-test/r/subselect_sj.result'
--- a/mysql-test/r/subselect_sj.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/subselect_sj.result 2010-07-16 08:58:24 +0000
@@ -197,45 +197,6 @@ id select_type table type possible_keys
1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3))
-
-BUG#37120 optimizer_switch allowable values not according to specification
-
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,materialization=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off,semijoin=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch=default;
drop table t0, t1, t2;
drop table t10, t11, t12;
=== modified file 'mysql-test/r/subselect_sj_jcl6.result'
--- a/mysql-test/r/subselect_sj_jcl6.result 2010-07-10 10:37:30 +0000
+++ b/mysql-test/r/subselect_sj_jcl6.result 2010-07-16 08:58:24 +0000
@@ -201,45 +201,6 @@ id select_type table type possible_keys
1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3))
-
-BUG#37120 optimizer_switch allowable values not according to specification
-
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,materialization=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off,semijoin=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,semijoin=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch='default,materialization=off,loosescan=off';
-select @@optimizer_switch;
-@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
-set optimizer_switch=default;
drop table t0, t1, t2;
drop table t10, t11, t12;
=== modified file 'mysql-test/t/index_merge_myisam.test'
--- a/mysql-test/t/index_merge_myisam.test 2009-08-24 19:10:48 +0000
+++ b/mysql-test/t/index_merge_myisam.test 2010-07-16 08:58:24 +0000
@@ -20,78 +20,6 @@ let $merge_table_support= 1;
--source include/index_merge_2sweeps.inc
--source include/index_merge_ror_cpk.inc
---echo #
---echo # Generic @@optimizer_switch tests (move those into a separate file if
---echo # we get another @@optimizer_switch user)
---echo #
-
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='index_merge=off,index_merge_union=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='index_merge_union=on';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,index_merge_sort_union=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch=4;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch=NULL;
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='default,index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=on,but...';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='on';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge=on,index_merge=off';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='index_merge_union=on,index_merge_union=default';
-
---error ER_WRONG_VALUE_FOR_VAR
-set optimizer_switch='default,index_merge=on,index_merge=off,default';
-
-set optimizer_switch=default;
-set optimizer_switch='index_merge=off,index_merge_union=off,default';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-set optimizer_switch=default;
-
-# Check setting defaults for global vars
---replace_regex /,table_elimination=on//
-select @@global.optimizer_switch;
-set @@global.optimizer_switch=default;
---replace_regex /,table_elimination=on//
-select @@global.optimizer_switch;
-
---echo #
---echo # Check index_merge's @@optimizer_switch flags
---echo #
---replace_regex /,table_elimination.on//
-select @@optimizer_switch;
-
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, c int, filler char(100),
@@ -190,8 +118,6 @@ set optimizer_switch='default,index_merg
explain select * from t1 where a=10 and b=10 or c=10;
set optimizer_switch=default;
---replace_regex /,table_elimination.on//
-show variables like 'optimizer_switch';
drop table t0, t1;
=== modified file 'mysql-test/t/myisam_mrr.test'
--- a/mysql-test/t/myisam_mrr.test 2009-12-22 14:43:00 +0000
+++ b/mysql-test/t/myisam_mrr.test 2010-07-16 08:58:24 +0000
@@ -103,8 +103,7 @@ drop table t0, t1;
# Check that optimizer_switch is present
---replace_regex /,table_elimination=o[nf]*//
-select @@optimizer_switch;
+select @@optimizer_switch like '%index_condition_pushdown=on%';
# Check if it affects ICP
create table t0 (a int);
=== added file 'mysql-test/t/optimizer_switch.test'
--- a/mysql-test/t/optimizer_switch.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/optimizer_switch.test 2010-07-16 08:58:24 +0000
@@ -0,0 +1,113 @@
+--echo #
+--echo # Generic @@optimizer_switch tests
+--echo #
+--echo #
+
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='index_merge=off,index_merge_union=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='index_merge_union=on';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,index_merge_sort_union=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch=4;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch=NULL;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='default,index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=on,but...';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='on';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge=on,index_merge=off';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='index_merge_union=on,index_merge_union=default';
+
+--error ER_WRONG_VALUE_FOR_VAR
+set optimizer_switch='default,index_merge=on,index_merge=off,default';
+
+set optimizer_switch=default;
+set optimizer_switch='index_merge=off,index_merge_union=off,default';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+set optimizer_switch=default;
+
+# Check setting defaults for global vars
+--replace_regex /,table_elimination=on//
+select @@global.optimizer_switch;
+set @@global.optimizer_switch=default;
+--replace_regex /,table_elimination=on//
+select @@global.optimizer_switch;
+
+--echo #
+--echo # Check index_merge's @@optimizer_switch flags
+--echo #
+--replace_regex /,table_elimination.on//
+select @@optimizer_switch;
+
+--echo
+--echo BUG#37120 optimizer_switch allowable values not according to specification
+--echo
+
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,semijoin=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,loosescan=off';
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
+set optimizer_switch=default;
+
+
=== modified file 'mysql-test/t/order_by.test'
--- a/mysql-test/t/order_by.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/t/order_by.test 2010-07-15 14:07:01 +0000
@@ -402,7 +402,11 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
EXPLAIN SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal;
SELECT * FROM t1 WHERE FieldKey = '1' ORDER BY LongVal;
-EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+--echo DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because
+--echo DS-MRR: records_in_range/read_time return the same numbers for all three indexes
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal;
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal;
=== modified file 'mysql-test/t/subselect_mat.test'
--- a/mysql-test/t/subselect_mat.test 2010-03-13 20:04:52 +0000
+++ b/mysql-test/t/subselect_mat.test 2010-07-16 11:02:15 +0000
@@ -905,3 +905,19 @@ select * from t1 where t1.i in (select t
set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
+#
+# Test that the contents of the temp table of a materialized subquery is
+# cleaned up between PS re-executions.
+#
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+select a, a in (select a from t1) from t0;
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+update t1 set a=123;
+execute s;
+drop table t0, t1;
=== modified file 'mysql-test/t/subselect_no_mat.test'
--- a/mysql-test/t/subselect_no_mat.test 2010-02-21 07:33:54 +0000
+++ b/mysql-test/t/subselect_no_mat.test 2010-07-16 08:58:24 +0000
@@ -1,13 +1,11 @@
#
# Run subselect.test without semi-join optimization (test materialize)
#
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
+select @@optimizer_switch like '%materialization=on%';
set optimizer_switch='materialization=off';
--source t/subselect.test
set optimizer_switch=default;
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
+select @@optimizer_switch like '%materialization=on%';
=== modified file 'mysql-test/t/subselect_no_opts.test'
--- a/mysql-test/t/subselect_no_opts.test 2010-02-21 07:33:54 +0000
+++ b/mysql-test/t/subselect_no_opts.test 2010-07-16 08:58:24 +0000
@@ -1,13 +1,9 @@
#
# Run subselect.test without semi-join optimization (test materialize)
#
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
set optimizer_switch='materialization=off,semijoin=off';
--source t/subselect.test
set optimizer_switch=default;
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
=== modified file 'mysql-test/t/subselect_no_semijoin.test'
--- a/mysql-test/t/subselect_no_semijoin.test 2010-02-21 07:33:54 +0000
+++ b/mysql-test/t/subselect_no_semijoin.test 2010-07-16 08:58:24 +0000
@@ -1,13 +1,8 @@
#
# Run subselect.test without semi-join optimization (test materialize)
#
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
set optimizer_switch='semijoin=off';
--source t/subselect.test
set optimizer_switch=default;
---replace_regex /,table_elimination=on//
-show variables like 'optimizer_switch';
-
=== modified file 'mysql-test/t/subselect_sj.test'
--- a/mysql-test/t/subselect_sj.test 2010-03-15 06:32:54 +0000
+++ b/mysql-test/t/subselect_sj.test 2010-07-16 08:58:24 +0000
@@ -92,46 +92,6 @@ execute s1;
insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B;
explain extended select * from t1 where a in (select pk from t10 where pk<3);
---echo
---echo BUG#37120 optimizer_switch allowable values not according to specification
---echo
-
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,materialization=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,semijoin=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,loosescan=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,semijoin=off,materialization=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,materialization=off,semijoin=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,semijoin=off,loosescan=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-
-set optimizer_switch='default,materialization=off,loosescan=off';
---replace_regex /,table_elimination=on//
-select @@optimizer_switch;
-set optimizer_switch=default;
-
drop table t0, t1, t2;
drop table t10, t11, t12;
=== modified file 'mysys/queues.c'
--- a/mysys/queues.c 2008-02-18 22:29:39 +0000
+++ b/mysys/queues.c 2010-07-16 07:33:01 +0000
@@ -1,25 +1,42 @@
-/* Copyright (C) 2000, 2005 MySQL AB
+/* Copyright (C) 2010 Monty Program Ab
+ 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
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
/*
+ This code originates from the Unireg project.
+
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
- An optimisation of _downheap suggested in Exercise 7.51 in "Data
- Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition
- was implemented by Mikael Ronstrom 2005. Also the O(N) algorithm
- of queue_fix was implemented.
+
+ The queue can optionally store the position in queue in the element
+ that is in the queue. This allows one to remove any element from the queue
+ in O(1) time.
+
+ Optimisation of _downheap() and queue_fix() is inspired by code done
+ by Mikael Ronström, based on an optimisation of _downheap from
+ Exercise 7.51 in "Data Structures & Algorithms in C++" by Mark Allen
+ Weiss, Second Edition.
*/
#include "mysys_priv.h"
@@ -39,6 +56,10 @@
max_at_top Set to 1 if you want biggest element on top.
compare Compare function for elements, takes 3 arguments.
first_cmp_arg First argument to compare function
+ offset_to_queue_pos If <> 0, then offset+1 in element to store position
+ in queue (for fast delete of element in queue)
+ auto_extent When the queue is full and there is insert operation
+ extend the queue.
NOTES
Will allocate max_element pointers for queue array
@@ -50,74 +71,33 @@
int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent)
+
{
DBUG_ENTER("init_queue");
- if ((queue->root= (uchar **) my_malloc((max_elements+1)*sizeof(void*),
+ if ((queue->root= (uchar **) my_malloc((max_elements + 1) * sizeof(void*),
MYF(MY_WME))) == 0)
DBUG_RETURN(1);
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->max_elements=max_elements;
- queue->offset_to_key=offset_to_key;
+ queue->elements= 0;
+ queue->compare= compare;
+ queue->first_cmp_arg= first_cmp_arg;
+ queue->max_elements= max_elements;
+ queue->offset_to_key= offset_to_key;
+ queue->offset_to_queue_pos= offset_to_queue_pos;
+ queue->auto_extent= auto_extent;
queue_set_max_at_top(queue, max_at_top);
DBUG_RETURN(0);
}
-
-/*
- Init queue, uses init_queue internally for init work but also accepts
- auto_extent as parameter
-
- SYNOPSIS
- init_queue_ex()
- queue Queue to initialise
- max_elements Max elements that will be put in queue
- offset_to_key Offset to key in element stored in queue
- Used when sending pointers to compare function
- max_at_top Set to 1 if you want biggest element on top.
- compare Compare function for elements, takes 3 arguments.
- first_cmp_arg First argument to compare function
- auto_extent When the queue is full and there is insert operation
- extend the queue.
-
- NOTES
- Will allocate max_element pointers for queue array
-
- RETURN
- 0 ok
- 1 Could not allocate memory
-*/
-
-int init_queue_ex(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg, uint auto_extent)
-{
- int ret;
- DBUG_ENTER("init_queue_ex");
-
- if ((ret= init_queue(queue, max_elements, offset_to_key, max_at_top, compare,
- first_cmp_arg)))
- DBUG_RETURN(ret);
-
- queue->auto_extent= auto_extent;
- DBUG_RETURN(0);
-}
-
/*
Reinitialize queue for other usage
SYNOPSIS
reinit_queue()
queue Queue to initialise
- max_elements Max elements that will be put in queue
- offset_to_key Offset to key in element stored in queue
- Used when sending pointers to compare function
- max_at_top Set to 1 if you want biggest element on top.
- compare Compare function for elements, takes 3 arguments.
- first_cmp_arg First argument to compare function
+ For rest of arguments, see init_queue() above
NOTES
This will delete all elements from the queue. If you don't want this,
@@ -125,21 +105,23 @@ int init_queue_ex(QUEUE *queue, uint max
RETURN
0 ok
- EE_OUTOFMEMORY Wrong max_elements
+ 1 Wrong max_elements; Queue has old size
*/
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
+ void *first_cmp_arg, uint offset_to_queue_pos,
+ uint auto_extent)
{
DBUG_ENTER("reinit_queue");
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->offset_to_key=offset_to_key;
+ queue->elements= 0;
+ queue->compare= compare;
+ queue->first_cmp_arg= first_cmp_arg;
+ queue->offset_to_key= offset_to_key;
+ queue->offset_to_queue_pos= offset_to_queue_pos;
+ queue->auto_extent= auto_extent;
queue_set_max_at_top(queue, max_at_top);
- resize_queue(queue, max_elements);
- DBUG_RETURN(0);
+ DBUG_RETURN(resize_queue(queue, max_elements));
}
@@ -167,8 +149,8 @@ int resize_queue(QUEUE *queue, uint max_
if (queue->max_elements == max_elements)
DBUG_RETURN(0);
if ((new_root= (uchar **) my_realloc((void *)queue->root,
- (max_elements+1)*sizeof(void*),
- MYF(MY_WME))) == 0)
+ (max_elements + 1)* sizeof(void*),
+ MYF(MY_WME))) == 0)
DBUG_RETURN(1);
set_if_smaller(queue->elements, max_elements);
queue->max_elements= max_elements;
@@ -197,39 +179,58 @@ void delete_queue(QUEUE *queue)
if (queue->root)
{
my_free((uchar*) queue->root,MYF(0));
- queue->root=0;
+ queue->root=0; /* Allow multiple calls */
}
DBUG_VOID_RETURN;
}
- /* Code for insert, search and delete of elements */
+/*
+ Insert element in queue
+
+ SYNOPSIS
+ queue_insert()
+ queue Queue to use
+ element Element to insert
+*/
void queue_insert(register QUEUE *queue, uchar *element)
{
reg2 uint idx, next;
+ uint offset_to_queue_pos= queue->offset_to_queue_pos;
DBUG_ASSERT(queue->elements < queue->max_elements);
- queue->root[0]= element;
+
idx= ++queue->elements;
/* max_at_top swaps the comparison if we want to order by desc */
- while ((queue->compare(queue->first_cmp_arg,
+ while (idx > 1 &&
+ (queue->compare(queue->first_cmp_arg,
element + queue->offset_to_key,
queue->root[(next= idx >> 1)] +
queue->offset_to_key) * queue->max_at_top) < 0)
{
queue->root[idx]= queue->root[next];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next;
}
queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element+ offset_to_queue_pos-1))= idx;
}
+
/*
- Does safe insert. If no more space left on the queue resize it.
- Return codes:
- 0 - OK
- 1 - Cannot allocate more memory
- 2 - auto_extend is 0, the operation would
-
+ Like queue_insert, but resize queue if queue is full
+
+ SYNOPSIS
+ queue_insert_safe()
+ queue Queue to use
+ element Element to insert
+
+ RETURN
+ 0 OK
+ 1 Cannot allocate more memory
+ 2 auto_extend is 0; No insertion done
*/
int queue_insert_safe(register QUEUE *queue, uchar *element)
@@ -239,7 +240,7 @@ int queue_insert_safe(register QUEUE *qu
{
if (!queue->auto_extent)
return 2;
- else if (resize_queue(queue, queue->max_elements + queue->auto_extent))
+ if (resize_queue(queue, queue->max_elements + queue->auto_extent))
return 1;
}
@@ -248,40 +249,48 @@ int queue_insert_safe(register QUEUE *qu
}
- /* Remove item from queue */
- /* Returns pointer to removed element */
+/*
+ Remove item from queue
+
+ SYNOPSIS
+ queue_remove()
+ queue Queue to use
+ element Index of element to remove.
+ First element in queue is 'queue_first_element(queue)'
+
+ RETURN
+ pointer to removed element
+*/
uchar *queue_remove(register QUEUE *queue, uint idx)
{
uchar *element;
- DBUG_ASSERT(idx < queue->max_elements);
- element= queue->root[++idx]; /* Intern index starts from 1 */
- queue->root[idx]= queue->root[queue->elements--];
- _downheap(queue, idx);
+ DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
+ element= queue->root[idx];
+ _downheap(queue, idx, queue->root[queue->elements--]);
return element;
}
- /* Fix when element on top has been replaced */
-#ifndef queue_replaced
-void queue_replaced(QUEUE *queue)
-{
- _downheap(queue,1);
-}
-#endif
+/*
+ Add element to fixed position and update heap
-#ifndef OLD_VERSION
+ SYNOPSIS
+ _downheap()
+ queue Queue to use
+ idx Index of element to change
+ element Element to store at 'idx'
+*/
-void _downheap(register QUEUE *queue, uint idx)
+void _downheap(register QUEUE *queue, uint start_idx, uchar *element)
{
- uchar *element;
- uint elements,half_queue,offset_to_key, next_index;
+ uint elements,half_queue,offset_to_key, next_index, offset_to_queue_pos;
+ register uint idx= start_idx;
my_bool first= TRUE;
- uint start_idx= idx;
offset_to_key=queue->offset_to_key;
- element=queue->root[idx];
- half_queue=(elements=queue->elements) >> 1;
+ offset_to_queue_pos= queue->offset_to_queue_pos;
+ half_queue= (elements= queue->elements) >> 1;
while (idx <= half_queue)
{
@@ -298,393 +307,49 @@ void _downheap(register QUEUE *queue, ui
element+offset_to_key) * queue->max_at_top) >= 0)))
{
queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
return;
}
- queue->root[idx]=queue->root[next_index];
- idx=next_index;
first= FALSE;
- }
-
- next_index= idx >> 1;
- while (next_index > start_idx)
- {
- if ((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) *
- queue->max_at_top) < 0)
- break;
- queue->root[idx]=queue->root[next_index];
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx=next_index;
- next_index= idx >> 1;
}
- queue->root[idx]=element;
-}
-#else
/*
- The old _downheap version is kept for comparisons with the benchmark
- suit or new benchmarks anyone wants to run for comparisons.
+ Insert the element into the right position. This is the same code
+ as we have in queue_insert()
*/
- /* Fix heap when index have changed */
-void _downheap(register QUEUE *queue, uint idx)
-{
- uchar *element;
- uint elements,half_queue,next_index,offset_to_key;
-
- offset_to_key=queue->offset_to_key;
- element=queue->root[idx];
- half_queue=(elements=queue->elements) >> 1;
-
- while (idx <= half_queue)
- {
- next_index=idx+idx;
- if (next_index < elements &&
- (queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- queue->root[next_index+1]+offset_to_key) *
- queue->max_at_top) > 0)
- next_index++;
- if ((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) * queue->max_at_top) >= 0)
- break;
- queue->root[idx]=queue->root[next_index];
- idx=next_index;
+ while ((next_index= (idx >> 1)) > start_idx &&
+ queue->compare(queue->first_cmp_arg,
+ element+offset_to_key,
+ queue->root[next_index]+offset_to_key)*
+ queue->max_at_top < 0)
+ {
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
+ idx= next_index;
}
- queue->root[idx]=element;
+ queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
}
-#endif
-
/*
Fix heap when every element was changed.
+
+ SYNOPSIS
+ queue_fix()
+ queue Queue to use
*/
void queue_fix(QUEUE *queue)
{
uint i;
for (i= queue->elements >> 1; i > 0; i--)
- _downheap(queue, i);
-}
-
-#ifdef MAIN
- /*
- A test program for the priority queue implementation.
- It can also be used to benchmark changes of the implementation
- Build by doing the following in the directory mysys
- make test_priority_queue
- ./test_priority_queue
-
- Written by Mikael Ronström, 2005
- */
-
-static uint num_array[1025];
-static uint tot_no_parts= 0;
-static uint tot_no_loops= 0;
-static uint expected_part= 0;
-static uint expected_num= 0;
-static bool max_ind= 0;
-static bool fix_used= 0;
-static ulonglong start_time= 0;
-
-static bool is_divisible_by(uint num, uint divisor)
-{
- uint quotient= num / divisor;
- if (quotient * divisor == num)
- return TRUE;
- return FALSE;
-}
-
-void calculate_next()
-{
- uint part= expected_part, num= expected_num;
- uint no_parts= tot_no_parts;
- if (max_ind)
- {
- do
- {
- while (++part <= no_parts)
- {
- if (is_divisible_by(num, part) &&
- (num <= ((1 << 21) + part)))
- {
- expected_part= part;
- expected_num= num;
- return;
- }
- }
- part= 0;
- } while (--num);
- }
- else
- {
- do
- {
- while (--part > 0)
- {
- if (is_divisible_by(num, part))
- {
- expected_part= part;
- expected_num= num;
- return;
- }
- }
- part= no_parts + 1;
- } while (++num);
- }
-}
-
-void calculate_end_next(uint part)
-{
- uint no_parts= tot_no_parts, num;
- num_array[part]= 0;
- if (max_ind)
- {
- expected_num= 0;
- for (part= no_parts; part > 0 ; part--)
- {
- if (num_array[part])
- {
- num= num_array[part] & 0x3FFFFF;
- if (num >= expected_num)
- {
- expected_num= num;
- expected_part= part;
- }
- }
- }
- if (expected_num == 0)
- expected_part= 0;
- }
- else
- {
- expected_num= 0xFFFFFFFF;
- for (part= 1; part <= no_parts; part++)
- {
- if (num_array[part])
- {
- num= num_array[part] & 0x3FFFFF;
- if (num <= expected_num)
- {
- expected_num= num;
- expected_part= part;
- }
- }
- }
- if (expected_num == 0xFFFFFFFF)
- expected_part= 0;
- }
- return;
-}
-static int test_compare(void *null_arg, uchar *a, uchar *b)
-{
- uint a_num= (*(uint*)a) & 0x3FFFFF;
- uint b_num= (*(uint*)b) & 0x3FFFFF;
- uint a_part, b_part;
- if (a_num > b_num)
- return +1;
- if (a_num < b_num)
- return -1;
- a_part= (*(uint*)a) >> 22;
- b_part= (*(uint*)b) >> 22;
- if (a_part < b_part)
- return +1;
- if (a_part > b_part)
- return -1;
- return 0;
-}
-
-bool check_num(uint num_part)
-{
- uint part= num_part >> 22;
- uint num= num_part & 0x3FFFFF;
- if (part == expected_part)
- if (num == expected_num)
- return FALSE;
- printf("Expect part %u Expect num 0x%x got part %u num 0x%x max_ind %u fix_used %u \n",
- expected_part, expected_num, part, num, max_ind, fix_used);
- return TRUE;
-}
-
-
-void perform_insert(QUEUE *queue)
-{
- uint i= 1, no_parts= tot_no_parts;
- uint backward_start= 0;
-
- expected_part= 1;
- expected_num= 1;
-
- if (max_ind)
- backward_start= 1 << 21;
-
- do
- {
- uint num= (i + backward_start);
- if (max_ind)
- {
- while (!is_divisible_by(num, i))
- num--;
- if (max_ind && (num > expected_num ||
- (num == expected_num && i < expected_part)))
- {
- expected_num= num;
- expected_part= i;
- }
- }
- num_array[i]= num + (i << 22);
- if (fix_used)
- queue_element(queue, i-1)= (uchar*)&num_array[i];
- else
- queue_insert(queue, (uchar*)&num_array[i]);
- } while (++i <= no_parts);
- if (fix_used)
- {
- queue->elements= no_parts;
- queue_fix(queue);
- }
-}
-
-bool perform_ins_del(QUEUE *queue, bool max_ind)
-{
- uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
- do
- {
- uint num_part= *(uint*)queue_top(queue);
- uint part= num_part >> 22;
- if (check_num(num_part))
- return TRUE;
- if (j++ >= no_loops)
- {
- calculate_end_next(part);
- queue_remove(queue, (uint) 0);
- }
- else
- {
- calculate_next();
- if (max_ind)
- num_array[part]-= part;
- else
- num_array[part]+= part;
- queue_top(queue)= (uchar*)&num_array[part];
- queue_replaced(queue);
- }
- } while (++i < no_loops);
- return FALSE;
-}
-
-bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used)
-{
- QUEUE queue;
- bool result;
- max_ind= l_max_ind;
- fix_used= l_fix_used;
- init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
- tot_no_parts= no_parts;
- tot_no_loops= 1024;
- perform_insert(&queue);
- if ((result= perform_ins_del(&queue, max_ind)))
- delete_queue(&queue);
- if (result)
- {
- printf("Error\n");
- return TRUE;
- }
- return FALSE;
-}
-
-static void start_measurement()
-{
- start_time= my_getsystime();
-}
-
-static void stop_measurement()
-{
- ulonglong stop_time= my_getsystime();
- uint time_in_micros;
- stop_time-= start_time;
- stop_time/= 10; /* Convert to microseconds */
- time_in_micros= (uint)stop_time;
- printf("Time expired is %u microseconds \n", time_in_micros);
-}
-
-static void benchmark_test()
-{
- QUEUE queue_real;
- QUEUE *queue= &queue_real;
- uint i, add;
- fix_used= TRUE;
- max_ind= FALSE;
- tot_no_parts= 1024;
- init_queue(queue, tot_no_parts, 0, max_ind, test_compare, NULL);
- /*
- First benchmark whether queue_fix is faster than using queue_insert
- for sizes of 16 partitions.
- */
- for (tot_no_parts= 2, add=2; tot_no_parts < 128;
- tot_no_parts+= add, add++)
- {
- printf("Start benchmark queue_fix, tot_no_parts= %u \n", tot_no_parts);
- start_measurement();
- for (i= 0; i < 128; i++)
- {
- perform_insert(queue);
- queue_remove_all(queue);
- }
- stop_measurement();
-
- fix_used= FALSE;
- printf("Start benchmark queue_insert\n");
- start_measurement();
- for (i= 0; i < 128; i++)
- {
- perform_insert(queue);
- queue_remove_all(queue);
- }
- stop_measurement();
- }
- /*
- Now benchmark insertion and deletion of 16400 elements.
- Used in consecutive runs this shows whether the optimised _downheap
- is faster than the standard implementation.
- */
- printf("Start benchmarking _downheap \n");
- start_measurement();
- perform_insert(queue);
- for (i= 0; i < 65536; i++)
- {
- uint num, part;
- num= *(uint*)queue_top(queue);
- num+= 16;
- part= num >> 22;
- num_array[part]= num;
- queue_top(queue)= (uchar*)&num_array[part];
- queue_replaced(queue);
- }
- for (i= 0; i < 16; i++)
- queue_remove(queue, (uint) 0);
- queue_remove_all(queue);
- stop_measurement();
-}
-
-int main()
-{
- int i, add= 1;
- for (i= 1; i < 1024; i+=add, add++)
- {
- printf("Start test for priority queue of size %u\n", i);
- if (do_test(i, 0, 1))
- return -1;
- if (do_test(i, 1, 1))
- return -1;
- if (do_test(i, 0, 0))
- return -1;
- if (do_test(i, 1, 0))
- return -1;
- }
- benchmark_test();
- printf("OK\n");
- return 0;
+ _downheap(queue, i, queue_element(queue, i));
}
-#endif
=== modified file 'mysys/thr_alarm.c'
--- a/mysys/thr_alarm.c 2008-10-10 15:28:41 +0000
+++ b/mysys/thr_alarm.c 2010-07-16 07:33:01 +0000
@@ -41,6 +41,19 @@ volatile my_bool alarm_thread_running= 0
time_t next_alarm_expire_time= ~ (time_t) 0;
static sig_handler process_alarm_part2(int sig);
+#ifdef DBUG_OFF
+#define reset_index_in_queue(alarm_data)
+#else
+#define reset_index_in_queue(alarm_data) alarm_data->index_in_queue= 0;
+#endif /* DBUG_OFF */
+
+#ifndef USE_ONE_SIGNAL_HAND
+#define one_signal_hand_sigmask(A,B,C) pthread_sigmask((A), (B), (C))
+#else
+#define one_signal_hand_sigmask(A,B,C)
+#endif
+
+
#if !defined(__WIN__)
static pthread_mutex_t LOCK_alarm;
@@ -72,8 +85,8 @@ void init_thr_alarm(uint max_alarms)
DBUG_ENTER("init_thr_alarm");
alarm_aborted=0;
next_alarm_expire_time= ~ (time_t) 0;
- init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
- compare_ulong,NullS);
+ init_queue(&alarm_queue, max_alarms+1, offsetof(ALARM,expire_time), 0,
+ compare_ulong, NullS, offsetof(ALARM, index_in_queue)+1, 0);
sigfillset(&full_signal_set); /* Neaded to block signals */
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_alarm,NULL);
@@ -151,7 +164,7 @@ void resize_thr_alarm(uint max_alarms)
my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
{
- time_t now;
+ time_t now, next;
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
@@ -161,79 +174,68 @@ my_bool thr_alarm(thr_alarm_t *alrm, uin
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
now= my_time(0);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
+ if (!alarm_data)
+ {
+ if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
+ goto abort_no_unlock;
+ alarm_data->malloced= 1;
+ }
+ else
+ alarm_data->malloced= 0;
+ next= now + sec;
+ alarm_data->expire_time= next;
+ alarm_data->alarmed= 0;
+ alarm_data->thread= current_my_thread_var->pthread_self;
+ alarm_data->thread_id= current_my_thread_var->id;
+
+ one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
- if (alarm_aborted > 0)
+ if (unlikely(alarm_aborted))
{ /* No signal thread */
DBUG_PRINT("info", ("alarm aborted"));
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- if (alarm_aborted < 0)
+ if (alarm_aborted > 0)
+ goto abort;
sec= 1; /* Abort mode */
-
+ }
if (alarm_queue.elements >= max_used_alarms)
{
if (alarm_queue.elements == alarm_queue.max_elements)
{
DBUG_PRINT("info", ("alarm queue full"));
fprintf(stderr,"Warning: thr_alarm queue is full\n");
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
+ goto abort;
}
max_used_alarms=alarm_queue.elements+1;
}
- reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
- if (!alarm_data)
- {
- if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
- {
- DBUG_PRINT("info", ("failed my_malloc()"));
- *alrm= 0; /* No alarm */
- pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- alarm_data->malloced=1;
- }
- else
- alarm_data->malloced=0;
- alarm_data->expire_time=now+sec;
- alarm_data->alarmed=0;
- alarm_data->thread= current_my_thread_var->pthread_self;
- alarm_data->thread_id= current_my_thread_var->id;
+ reschedule= (ulong) next_alarm_expire_time > (ulong) next;
queue_insert(&alarm_queue,(uchar*) alarm_data);
+ assert(alarm_data->index_in_queue > 0);
/* Reschedule alarm if the current one has more than sec left */
- if (reschedule)
+ if (unlikely(reschedule))
{
DBUG_PRINT("info", ("reschedule"));
if (pthread_equal(pthread_self(),alarm_thread))
{
alarm(sec); /* purecov: inspected */
- next_alarm_expire_time= now + sec;
+ next_alarm_expire_time= next;
}
else
reschedule_alarms(); /* Reschedule alarms */
}
pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
(*alrm)= &alarm_data->alarmed;
DBUG_RETURN(0);
+
+abort:
+ if (alarm_data->malloced)
+ my_free(alarm_data, MYF(0));
+ pthread_mutex_unlock(&LOCK_alarm);
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
+abort_no_unlock:
+ *alrm= 0; /* No alarm */
+ DBUG_RETURN(1);
}
@@ -247,41 +249,18 @@ void thr_end_alarm(thr_alarm_t *alarmed)
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
- uint i, found=0;
DBUG_ENTER("thr_end_alarm");
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
- pthread_mutex_lock(&LOCK_alarm);
-
+ one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
- {
- queue_remove(&alarm_queue,i),MYF(0);
- if (alarm_data->malloced)
- my_free((uchar*) alarm_data,MYF(0));
- found++;
-#ifdef DBUG_OFF
- break;
-#endif
- }
- }
- DBUG_ASSERT(!*alarmed || found == 1);
- if (!found)
- {
- if (*alarmed)
- fprintf(stderr,"Warning: Didn't find alarm 0x%lx in queue of %d alarms\n",
- (long) *alarmed, alarm_queue.elements);
- DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n",
- (long) *alarmed));
- }
+ pthread_mutex_lock(&LOCK_alarm);
+ DBUG_ASSERT(alarm_data->index_in_queue != 0);
+ DBUG_ASSERT(queue_element(&alarm_queue, alarm_data->index_in_queue) ==
+ alarm_data);
+ queue_remove(&alarm_queue, alarm_data->index_in_queue);
pthread_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
+ one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
+ reset_index_in_queue(alarm_data);
DBUG_VOID_RETURN;
}
@@ -344,12 +323,13 @@ static sig_handler process_alarm_part2(i
#if defined(MAIN) && !defined(__bsdi__)
printf("process_alarm\n"); fflush(stdout);
#endif
- if (alarm_queue.elements)
+ if (likely(alarm_queue.elements))
{
- if (alarm_aborted)
+ if (unlikely(alarm_aborted))
{
uint i;
- for (i=0 ; i < alarm_queue.elements ;)
+ for (i= queue_first_element(&alarm_queue) ;
+ i <= queue_last_element(&alarm_queue) ;)
{
alarm_data=(ALARM*) queue_element(&alarm_queue,i);
alarm_data->alarmed=1; /* Info to thread */
@@ -360,6 +340,7 @@ static sig_handler process_alarm_part2(i
printf("Warning: pthread_kill couldn't find thread!!!\n");
#endif
queue_remove(&alarm_queue,i); /* No thread. Remove alarm */
+ reset_index_in_queue(alarm_data);
}
else
i++; /* Signal next thread */
@@ -371,8 +352,8 @@ static sig_handler process_alarm_part2(i
}
else
{
- ulong now=(ulong) my_time(0);
- ulong next=now+10-(now%10);
+ time_t now= my_time(0);
+ time_t next= now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
alarm_data->alarmed=1; /* Info to thread */
@@ -382,15 +363,16 @@ static sig_handler process_alarm_part2(i
{
#ifdef MAIN
printf("Warning: pthread_kill couldn't find thread!!!\n");
-#endif
- queue_remove(&alarm_queue,0); /* No thread. Remove alarm */
+#endif /* MAIN */
+ queue_remove_top(&alarm_queue); /* No thread. Remove alarm */
+ reset_index_in_queue(alarm_data);
if (!alarm_queue.elements)
break;
}
else
{
alarm_data->expire_time=next;
- queue_replaced(&alarm_queue);
+ queue_replace_top(&alarm_queue);
}
}
#ifndef USE_ALARM_THREAD
@@ -486,13 +468,15 @@ void thr_alarm_kill(my_thread_id thread_
if (alarm_aborted)
return;
pthread_mutex_lock(&LOCK_alarm);
- for (i=0 ; i < alarm_queue.elements ; i++)
+ for (i= queue_first_element(&alarm_queue) ;
+ i <= queue_last_element(&alarm_queue);
+ i++)
{
- if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
+ ALARM *element= (ALARM*) queue_element(&alarm_queue,i);
+ if (element->thread_id == thread_id)
{
- ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
- tmp->expire_time=0;
- queue_insert(&alarm_queue,(uchar*) tmp);
+ element->expire_time= 0;
+ queue_replace(&alarm_queue, i);
reschedule_alarms();
break;
}
@@ -508,7 +492,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
- ulong now=(ulong) my_time(0);
+ time_t now= my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
@@ -556,7 +540,7 @@ static void *alarm_handler(void *arg __a
{
if (alarm_queue.elements)
{
- ulong sleep_time,now= my_time(0);
+ time_t sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
@@ -792,20 +776,6 @@ static void *test_thread(void *arg)
return 0;
}
-#ifdef USE_ONE_SIGNAL_HAND
-static sig_handler print_signal_warning(int sig)
-{
- printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
- fflush(stdout);
-#ifdef DONT_REMEMBER_SIGNAL
- my_sigset(sig,print_signal_warning); /* int. thread system calls */
-#endif
- if (sig == SIGALRM)
- alarm(2); /* reschedule alarm */
-}
-#endif /* USE_ONE_SIGNAL_HAND */
-
-
static void *signal_hand(void *arg __attribute__((unused)))
{
sigset_t set;
=== modified file 'sql/create_options.cc'
--- a/sql/create_options.cc 2010-05-12 17:56:05 +0000
+++ b/sql/create_options.cc 2010-07-16 07:33:01 +0000
@@ -583,9 +583,9 @@ my_bool engine_table_options_frm_read(co
}
if (buff < buff_end)
- sql_print_warning("Table %`s was created in a later MariaDB version - "
+ sql_print_warning("Table '%s' was created in a later MariaDB version - "
"unknown table attributes were ignored",
- share->table_name);
+ share->table_name.str);
DBUG_RETURN(buff > buff_end);
}
=== modified file 'sql/event_queue.cc'
--- a/sql/event_queue.cc 2008-12-02 22:02:52 +0000
+++ b/sql/event_queue.cc 2010-07-16 07:33:01 +0000
@@ -136,9 +136,9 @@ Event_queue::init_queue(THD *thd)
LOCK_QUEUE_DATA();
- if (init_queue_ex(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/,
- 0 /*max_on_top*/, event_queue_element_compare_q,
- NULL, EVENT_QUEUE_EXTENT))
+ if (::init_queue(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/,
+ 0 /*max_on_top*/, event_queue_element_compare_q,
+ NullS, 0, EVENT_QUEUE_EXTENT))
{
sql_print_error("Event Scheduler: Can't initialize the execution queue");
goto err;
@@ -325,11 +325,13 @@ void
Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
bool (*comparator)(LEX_STRING, Event_basic *))
{
- uint i= 0;
+ uint i;
DBUG_ENTER("Event_queue::drop_matching_events");
DBUG_PRINT("enter", ("pattern=%s", pattern.str));
- while (i < queue.elements)
+ for (i= queue_first_element(&queue) ;
+ i <= queue_last_element(&queue) ;
+ )
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
DBUG_PRINT("info", ("[%s.%s]?", et->dbname.str, et->name.str));
@@ -339,7 +341,8 @@ Event_queue::drop_matching_events(THD *t
The queue is ordered. If we remove an element, then all elements
after it will shift one position to the left, if we imagine it as
an array from left to the right. In this case we should not
- increment the counter and the (i < queue.elements) condition is ok.
+ increment the counter and the (i <= queue_last_element() condition
+ is ok.
*/
queue_remove(&queue, i);
delete et;
@@ -403,7 +406,9 @@ Event_queue::find_n_remove_event(LEX_STR
uint i;
DBUG_ENTER("Event_queue::find_n_remove_event");
- for (i= 0; i < queue.elements; ++i)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?", db.str, name.str,
@@ -441,7 +446,9 @@ Event_queue::recalculate_activation_time
LOCK_QUEUE_DATA();
DBUG_PRINT("info", ("%u loaded events to be recalculated", queue.elements));
- for (i= 0; i < queue.elements; i++)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
((Event_queue_element*)queue_element(&queue, i))->compute_next_execution_time();
((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd);
@@ -454,16 +461,19 @@ Event_queue::recalculate_activation_time
have removed all. The queue has been ordered in a way the disabled
events are at the end.
*/
- for (i= queue.elements; i > 0; i--)
+ for (i= queue_last_element(&queue);
+ (int) i >= (int) queue_first_element(&queue);
+ i--)
{
- Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1);
+ Event_queue_element *element=
+ (Event_queue_element*)queue_element(&queue, i);
if (element->status != Event_parse_data::DISABLED)
break;
/*
This won't cause queue re-order, because we remove
always the last element.
*/
- queue_remove(&queue, i - 1);
+ queue_remove(&queue, i);
delete element;
}
UNLOCK_QUEUE_DATA();
@@ -499,7 +509,9 @@ Event_queue::empty_queue()
sql_print_information("Event Scheduler: Purging the queue. %u events",
queue.elements);
/* empty the queue */
- for (i= 0; i < queue.elements; ++i)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
delete et;
@@ -525,7 +537,9 @@ Event_queue::dbug_dump_queue(time_t now)
uint i;
DBUG_ENTER("Event_queue::dbug_dump_queue");
DBUG_PRINT("info", ("Dumping queue . Elements=%u", queue.elements));
- for (i = 0; i < queue.elements; i++)
+ for (i= queue_first_element(&queue);
+ i <= queue_last_element(&queue);
+ i++)
{
et= ((Event_queue_element*)queue_element(&queue, i));
DBUG_PRINT("info", ("et: 0x%lx name: %s.%s", (long) et,
@@ -592,7 +606,7 @@ Event_queue::get_top_for_execution_if_ti
continue;
}
- top= ((Event_queue_element*) queue_element(&queue, 0));
+ top= (Event_queue_element*) queue_top(&queue);
thd->set_current_time(); /* Get current time */
@@ -634,10 +648,10 @@ Event_queue::get_top_for_execution_if_ti
top->dbname.str, top->name.str,
top->dropped? "Dropping.":"");
delete top;
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
}
else
- queue_replaced(&queue);
+ queue_replace_top(&queue);
dbug_dump_queue(thd->query_start());
break;
=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc 2010-06-01 19:52:20 +0000
+++ b/sql/filesort.cc 2010-07-16 07:33:01 +0000
@@ -1151,7 +1151,9 @@ uint read_to_buffer(IO_CACHE *fromfile,
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
{
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
- for (uint i= 0; i < queue->elements; ++i)
+ for (uint i= queue_first_element(queue);
+ i <= queue_last_element(queue);
+ i++)
{
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
if (bp->base + bp->max_keys * key_length == reuse->base)
@@ -1240,7 +1242,7 @@ int merge_buffers(SORTPARAM *param, IO_C
first_cmp_arg= (void*) &sort_length;
}
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
- (queue_compare) cmp, first_cmp_arg))
+ (queue_compare) cmp, first_cmp_arg, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
@@ -1277,7 +1279,7 @@ int merge_buffers(SORTPARAM *param, IO_C
error= 0; /* purecov: inspected */
goto end; /* purecov: inspected */
}
- queue_replaced(&queue); // Top element has been used
+ queue_replace_top(&queue); // Top element has been used
}
else
cmp= 0; // Not unique
@@ -1325,14 +1327,14 @@ int merge_buffers(SORTPARAM *param, IO_C
if (!(error= (int) read_to_buffer(from_file,buffpek,
rec_length)))
{
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
reuse_freed_buff(&queue, buffpek, rec_length);
break; /* One buffer have been removed */
}
else if (error == -1)
goto err; /* purecov: inspected */
}
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek= (BUFFPEK*) queue_top(&queue);
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-06-05 14:53:36 +0000
+++ b/sql/ha_partition.cc 2010-07-16 07:33:01 +0000
@@ -2567,7 +2567,7 @@ int ha_partition::open(const char *name,
Initialize priority queue, initialized to reading forward.
*/
if ((error= init_queue(&m_queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS,
- 0, key_rec_cmp, (void*)this)))
+ 0, key_rec_cmp, (void*)this, 0, 0)))
goto err_handler;
/*
@@ -4622,7 +4622,7 @@ int ha_partition::handle_unordered_scan_
int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
{
uint i;
- uint j= 0;
+ uint j= queue_first_element(&m_queue);
bool found= FALSE;
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
@@ -4716,7 +4716,7 @@ int ha_partition::handle_ordered_index_s
*/
queue_set_max_at_top(&m_queue, reverse_order);
queue_set_cmp_arg(&m_queue, (void*)m_curr_key_info);
- m_queue.elements= j;
+ m_queue.elements= j - queue_first_element(&m_queue);
queue_fix(&m_queue);
return_top_record(buf);
table->status= 0;
@@ -4787,7 +4787,7 @@ int ha_partition::handle_ordered_next(uc
if (error == HA_ERR_END_OF_FILE)
{
/* Return next buffered row */
- queue_remove(&m_queue, (uint) 0);
+ queue_remove_top(&m_queue);
if (m_queue.elements)
{
DBUG_PRINT("info", ("Record returned from partition %u (2)",
@@ -4799,7 +4799,7 @@ int ha_partition::handle_ordered_next(uc
}
DBUG_RETURN(error);
}
- queue_replaced(&m_queue);
+ queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %u", m_top_entry));
DBUG_RETURN(0);
@@ -4830,7 +4830,7 @@ int ha_partition::handle_ordered_prev(uc
{
if (error == HA_ERR_END_OF_FILE)
{
- queue_remove(&m_queue, (uint) 0);
+ queue_remove_top(&m_queue);
if (m_queue.elements)
{
return_top_record(buf);
@@ -4842,7 +4842,7 @@ int ha_partition::handle_ordered_prev(uc
}
DBUG_RETURN(error);
}
- queue_replaced(&m_queue);
+ queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
DBUG_RETURN(0);
=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h 2010-06-05 14:53:36 +0000
+++ b/sql/ha_partition.h 2010-07-16 07:33:01 +0000
@@ -1129,7 +1129,7 @@ public:
virtual handlerton *partition_ht() const
{
handlerton *h= m_file[0]->ht;
- for (int i=1; i < m_tot_parts; i++)
+ for (uint i=1; i < m_tot_parts; i++)
DBUG_ASSERT(h == m_file[i]->ht);
return h;
}
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-07-10 10:37:30 +0000
+++ b/sql/item_cmpfunc.cc 2010-07-16 07:33:01 +0000
@@ -1778,10 +1778,12 @@ Item *Item_in_optimizer::expr_cache_inse
if (args[0]->cols() == 1)
depends_on.push_front((Item**)args);
else
- for (int i= 0; i < args[0]->cols(); i++)
+ {
+ for (uint i= 0; i < args[0]->cols(); i++)
{
depends_on.push_front(args[0]->addr(i));
}
+ }
if (args[1]->expr_cache_is_needed(thd))
DBUG_RETURN(set_expr_cache(thd, depends_on));
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-07-16 10:52:02 +0000
+++ b/sql/item_subselect.cc 2010-07-16 12:10:55 +0000
@@ -4880,7 +4880,8 @@ subselect_rowid_merge_engine::init(MY_BI
merge_keys[i]->sort_keys();
if (init_queue(&pq, keys_count, 0, FALSE,
- subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL))
+ subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
+ 0, 0))
return TRUE;
return FALSE;
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-07-10 10:37:30 +0000
+++ b/sql/mysqld.cc 2010-07-16 08:58:24 +0000
@@ -409,6 +409,12 @@ static const char *optimizer_switch_str=
"index_merge_sort_union=on,"
"index_merge_intersection=on,"
"index_condition_pushdown=on,"
+ "firstmatch=on,"
+ "loosescan=on,"
+ "materialization=on,"
+ "semijoin=on,"
+ "partial_match_rowid_merge=on,"
+ "partial_match_table_scan=on,"
"subquery_cache=on"
#ifndef DBUG_OFF
",table_elimination=on";
@@ -7227,7 +7233,9 @@ The minimum value for this variable is 4
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
"index_merge_union, index_merge_sort_union, index_merge_intersection, "
- "index_condition_pushdown, subquery_cache"
+ "index_condition_pushdown, firstmatch, loosescan, materialization, "
+ "semijoin, partial_match_rowid_merge, partial_match_table_scan, "
+ "subquery_cache"
#ifndef DBUG_OFF
", table_elimination"
#endif
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-05-26 18:55:40 +0000
+++ b/sql/net_serv.cc 2010-07-16 07:33:01 +0000
@@ -262,18 +262,20 @@ static int net_data_is_ready(my_socket s
#endif /* EMBEDDED_LIBRARY */
/**
- Remove unwanted characters from connection
- and check if disconnected.
+ Intialize NET handler for new reads:
- Read from socket until there is nothing more to read. Discard
- what is read.
-
- If there is anything when to read 'net_clear' is called this
- normally indicates an error in the protocol.
-
- When connection is properly closed (for TCP it means with
- a FIN packet), then select() considers a socket "ready to read",
- in the sense that there's EOF to read, but read() returns 0.
+ - Read from socket until there is nothing more to read. Discard
+ what is read.
+ - Initialize net for new net_read/net_write calls.
+
+ If there is anything when to read 'net_clear' is called this
+ normally indicates an error in the protocol. Normally one should not
+ need to do clear the communication buffer. If one compiles without
+ -DUSE_NET_CLEAR then one wins one read call / query.
+
+ When connection is properly closed (for TCP it means with
+ a FIN packet), then select() considers a socket "ready to read",
+ in the sense that there's EOF to read, but read() returns 0.
@param net NET handler
@param clear_buffer if <> 0, then clear all data from comm buff
@@ -281,20 +283,18 @@ static int net_data_is_ready(my_socket s
void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
-#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
- size_t count;
- int ready;
-#endif
DBUG_ENTER("net_clear");
/*
- We don't do a clear in case of DBUG_OFF to catch bugs
- in the protocol handling
+ We don't do a clear in case of not DBUG_OFF to catch bugs in the
+ protocol handling.
*/
-#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
+#if (!defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)) || defined(USE_NET_CLEAR)
if (clear_buffer)
{
+ size_t count;
+ int ready;
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
{
/* The socket is ready */
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2010-07-10 10:37:30 +0000
+++ b/sql/opt_range.cc 2010-07-16 07:33:01 +0000
@@ -1155,10 +1155,7 @@ QUICK_SELECT_I::QUICK_SELECT_I()
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
bool no_alloc, MEM_ROOT *parent_alloc,
bool *create_error)
- :dont_free(0),doing_key_read(0),/*error(0),*/free_file(0),/*in_range(0),*/cur_range(NULL),last_range(0)
- //psergey3-merge: check whether we need doing_key_read and last_range
- // was:
- // :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
+ :doing_key_read(0),/*error(0),*/free_file(0),/*in_range(0),*/cur_range(NULL),last_range(0),dont_free(0)
{
my_bitmap_map *bitmap;
DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
@@ -1594,7 +1591,7 @@ int QUICK_ROR_UNION_SELECT::init()
DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
if (init_queue(&queue, quick_selects.elements, 0,
FALSE , QUICK_ROR_UNION_SELECT::queue_cmp,
- (void*) this))
+ (void*) this, 0, 0))
{
bzero(&queue, sizeof(QUEUE));
DBUG_RETURN(1);
@@ -8293,12 +8290,12 @@ int QUICK_ROR_UNION_SELECT::get_next()
{
if (error != HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
}
else
{
quick->save_last_pos();
- queue_replaced(&queue);
+ queue_replace_top(&queue);
}
if (!have_prev_rowid)
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-07-16 10:52:02 +0000
+++ b/sql/sql_class.cc 2010-07-16 12:10:55 +0000
@@ -2994,14 +2994,28 @@ create_result_table(THD *thd_arg, List<I
if (!stat)
return TRUE;
- cleanup();
-
+ reset();
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
return FALSE;
}
+void select_materialize_with_stats::reset()
+{
+ memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
+ max_nulls_in_row= 0;
+ count_rows= 0;
+}
+
+
+void select_materialize_with_stats::cleanup()
+{
+ reset();
+ select_union::cleanup();
+}
+
+
/**
Override select_union::send_data to analyze each row for NULLs and to
update null_statistics before sending data to the client.
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-07-16 10:52:02 +0000
+++ b/sql/sql_class.h 2010-07-16 12:10:55 +0000
@@ -2907,11 +2907,11 @@ public:
bool send_data(List<Item> &items);
bool send_eof();
bool flush();
- TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
-
+ void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
const char *alias, bool bit_fields_as_long);
+ TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
};
/* Base subselect interface class */
@@ -2971,6 +2971,9 @@ protected:
*/
ha_rows count_rows;
+protected:
+ void reset();
+
public:
select_materialize_with_stats() { tmp_table_param.init(); }
virtual bool create_result_table(THD *thd, List<Item> *column_types,
@@ -2978,12 +2981,7 @@ public:
const char *alias, bool bit_fields_as_long);
bool init_result_table(ulonglong select_options);
bool send_data(List<Item> &items);
- void cleanup()
- {
- memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
- max_nulls_in_row= 0;
- count_rows= 0;
- }
+ void cleanup();
ha_rows get_null_count_of_col(uint idx)
{
DBUG_ASSERT(idx < table->s->fields);
=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc 2010-07-10 10:37:30 +0000
+++ b/sql/sql_union.cc 2010-07-16 11:02:15 +0000
@@ -136,6 +136,22 @@ select_union::create_result_table(THD *t
}
+/**
+ Reset and empty the temporary table that stores the materialized query result.
+
+ @note The cleanup performed here is exactly the same as for the two temp
+ tables of JOIN - exec_tmp_table_[1 | 2].
+*/
+
+void select_union::cleanup()
+{
+ table->file->extra(HA_EXTRA_RESET_STATE);
+ table->file->ha_delete_all_rows();
+ free_io_cache(table);
+ filesort_free_buffers(table,0);
+}
+
+
/*
initialization procedures before fake_select_lex preparation()
=== modified file 'sql/uniques.cc'
--- a/sql/uniques.cc 2009-09-07 20:50:10 +0000
+++ b/sql/uniques.cc 2010-07-16 07:33:01 +0000
@@ -423,7 +423,7 @@ static bool merge_walk(uchar *merge_buff
if (end <= begin ||
merge_buffer_size < (ulong) (key_length * (end - begin + 1)) ||
init_queue(&queue, (uint) (end - begin), offsetof(BUFFPEK, key), 0,
- buffpek_compare, &compare_context))
+ buffpek_compare, &compare_context, 0, 0))
return 1;
/* we need space for one key when a piece of merge buffer is re-read */
merge_buffer_size-= key_length;
@@ -468,7 +468,7 @@ static bool merge_walk(uchar *merge_buff
*/
top->key+= key_length;
if (--top->mem_count)
- queue_replaced(&queue);
+ queue_replace_top(&queue);
else /* next piece should be read */
{
/* save old_key not to overwrite it in read_to_buffer */
@@ -478,14 +478,14 @@ static bool merge_walk(uchar *merge_buff
if (bytes_read == (uint) (-1))
goto end;
else if (bytes_read > 0) /* top->key, top->mem_count are reset */
- queue_replaced(&queue); /* in read_to_buffer */
+ queue_replace_top(&queue); /* in read_to_buffer */
else
{
/*
Tree for old 'top' element is empty: remove it from the queue and
give all its memory to the nearest tree.
*/
- queue_remove(&queue, 0);
+ queue_remove_top(&queue);
reuse_freed_buff(&queue, top, key_length);
}
}
=== modified file 'storage/maria/ma_ft_boolean_search.c'
--- a/storage/maria/ma_ft_boolean_search.c 2010-01-06 19:20:16 +0000
+++ b/storage/maria/ma_ft_boolean_search.c 2010-07-16 07:33:01 +0000
@@ -473,14 +473,15 @@ static void _ftb_init_index_search(FT_IN
int i;
FTB_WORD *ftbw;
- if ((ftb->state != READY && ftb->state !=INDEX_DONE) ||
- ftb->keynr == NO_SUCH_KEY)
+ if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
- for (i=ftb->queue.elements; i; i--)
+ for (i= queue_last_element(&ftb->queue);
+ (int) i >= (int) queue_first_element(&ftb->queue);
+ i--)
{
- ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+ ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
@@ -585,7 +586,7 @@ FT_INFO * maria_ft_init_boolean_search(M
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
- (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
+ (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
@@ -828,7 +829,7 @@ int maria_ft_boolean_read_next(FT_INFO *
/* update queue */
_ft2_search(ftb, ftbw, 0);
- queue_replaced(& ftb->queue);
+ queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
=== modified file 'storage/maria/ma_ft_nlq_search.c'
--- a/storage/maria/ma_ft_nlq_search.c 2009-11-30 13:36:06 +0000
+++ b/storage/maria/ma_ft_nlq_search.c 2010-07-16 07:33:01 +0000
@@ -253,12 +253,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
- 0);
+ 0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
- my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
+ my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info, record, docid))
{
info->update|= HA_STATE_AKTIV;
=== modified file 'storage/maria/ma_sort.c'
--- a/storage/maria/ma_sort.c 2009-11-29 23:08:56 +0000
+++ b/storage/maria/ma_sort.c 2010-07-16 07:33:01 +0000
@@ -933,7 +933,7 @@ merge_buffers(MARIA_SORT_PARAM *info, ui
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
- (void*) info))
+ (void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -982,7 +982,7 @@ merge_buffers(MARIA_SORT_PARAM *info, ui
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
@@ -1007,7 +1007,7 @@ merge_buffers(MARIA_SORT_PARAM *info, ui
}
else if (error == -1)
goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
=== modified file 'storage/maria/maria_pack.c'
--- a/storage/maria/maria_pack.c 2009-02-19 09:01:25 +0000
+++ b/storage/maria/maria_pack.c 2010-07-16 07:33:01 +0000
@@ -590,7 +590,7 @@ static int compress(PACK_MRG_INFO *mrg,c
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
- if (init_queue(&queue,256,0,0,compare_huff_elements,0))
+ if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
@@ -1521,7 +1521,7 @@ static int make_huff_tree(HUFF_TREE *huf
if (queue.max_elements < found)
{
delete_queue(&queue);
- if (init_queue(&queue,found,0,0,compare_huff_elements,0))
+ if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
@@ -1625,8 +1625,7 @@ static int make_huff_tree(HUFF_TREE *huf
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=found/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
@@ -1637,12 +1636,9 @@ static int make_huff_tree(HUFF_TREE *huf
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
- a=(HUFF_ELEMENT*) queue_remove(&queue,0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b=(HUFF_ELEMENT*) queue.root[1];
+ a=(HUFF_ELEMENT*) queue_remove_top(&queue);
+ /* Copy the next least incidence element */
+ b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1664,8 +1660,8 @@ static int make_huff_tree(HUFF_TREE *huf
Replace the copied top element by the new element and re-order the
queue.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
@@ -1796,8 +1792,7 @@ static my_off_t calc_packed_length(HUFF_
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=(found+1)/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
@@ -1811,12 +1806,9 @@ static my_off_t calc_packed_length(HUFF_
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
- a= (my_off_t*) queue_remove(&queue, 0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b= (my_off_t*) queue.root[1];
+ a= (my_off_t*) queue_remove_top(&queue);
+ /* Copy the next least incidence element. */
+ b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1836,8 +1828,8 @@ static my_off_t calc_packed_length(HUFF_
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
=== modified file 'storage/myisam/ft_boolean_search.c'
--- a/storage/myisam/ft_boolean_search.c 2010-06-01 19:52:20 +0000
+++ b/storage/myisam/ft_boolean_search.c 2010-07-16 07:33:01 +0000
@@ -482,16 +482,18 @@ static int _ft2_search(FTB *ftb, FTB_WOR
static void _ftb_init_index_search(FT_INFO *ftb)
{
- int i;
+ uint i;
FTB_WORD *ftbw;
if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
- for (i=ftb->queue.elements; i; i--)
+ for (i= queue_last_element(&ftb->queue);
+ (int) i >= (int) queue_first_element(&ftb->queue);
+ i--)
{
- ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+ ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
@@ -595,12 +597,12 @@ FT_INFO * ft_init_boolean_search(MI_INFO
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
- (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
+ (int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
sizeof(FTB_WORD *)*ftb->queue.elements);
- memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements);
+ memcpy(ftb->list, &queue_top(&ftb->queue), sizeof(FTB_WORD *)*ftb->queue.elements);
my_qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *),
(qsort2_cmp)FTB_WORD_cmp_list, (void*) ftb->charset);
if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC;
@@ -839,7 +841,7 @@ int ft_boolean_read_next(FT_INFO *ftb, c
/* update queue */
_ft2_search(ftb, ftbw, 0);
- queue_replaced(& ftb->queue);
+ queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
=== modified file 'storage/myisam/ft_nlq_search.c'
--- a/storage/myisam/ft_nlq_search.c 2010-01-27 21:53:08 +0000
+++ b/storage/myisam/ft_nlq_search.c 2010-07-16 07:33:01 +0000
@@ -250,12 +250,12 @@ FT_INFO *ft_init_nlq_search(MI_INFO *inf
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
- 0);
+ 0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
- my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
+ my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info,docid,record))
{
info->update|= HA_STATE_AKTIV;
=== modified file 'storage/myisam/mi_test_all.sh'
--- a/storage/myisam/mi_test_all.sh 2007-07-28 11:36:20 +0000
+++ b/storage/myisam/mi_test_all.sh 2010-07-16 07:33:01 +0000
@@ -5,6 +5,7 @@
valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
+rm -f test1.TMD
if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
./mi_test1$suffix $silent
=== modified file 'storage/myisam/myisampack.c'
--- a/storage/myisam/myisampack.c 2009-02-19 09:01:25 +0000
+++ b/storage/myisam/myisampack.c 2010-07-16 07:33:01 +0000
@@ -576,7 +576,7 @@ static int compress(PACK_MRG_INFO *mrg,c
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
- if (init_queue(&queue,256,0,0,compare_huff_elements,0))
+ if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
@@ -1511,7 +1511,7 @@ static int make_huff_tree(HUFF_TREE *huf
if (queue.max_elements < found)
{
delete_queue(&queue);
- if (init_queue(&queue,found,0,0,compare_huff_elements,0))
+ if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
@@ -1615,8 +1615,7 @@ static int make_huff_tree(HUFF_TREE *huf
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=found/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
@@ -1627,12 +1626,9 @@ static int make_huff_tree(HUFF_TREE *huf
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
- a=(HUFF_ELEMENT*) queue_remove(&queue,0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b=(HUFF_ELEMENT*) queue.root[1];
+ a=(HUFF_ELEMENT*) queue_remove_top(&queue);
+ /* Copy the next least incidence element */
+ b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1654,8 +1650,8 @@ static int make_huff_tree(HUFF_TREE *huf
Replace the copied top element by the new element and re-order the
queue.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
@@ -1786,8 +1782,7 @@ static my_off_t calc_packed_length(HUFF_
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
- for (i=(found+1)/2 ; i > 0 ; i--)
- _downheap(&queue,i);
+ queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
@@ -1801,12 +1796,9 @@ static my_off_t calc_packed_length(HUFF_
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
- a= (my_off_t*) queue_remove(&queue, 0);
- /*
- Copy the next least incidence element. The queue implementation
- reserves root[0] for temporary purposes. root[1] is the top.
- */
- b= (my_off_t*) queue.root[1];
+ a= (my_off_t*) queue_remove_top(&queue);
+ /* Copy the next least incidence element. */
+ b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
@@ -1826,8 +1818,8 @@ static my_off_t calc_packed_length(HUFF_
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
- queue.root[1]=(uchar*) new_huff_el;
- queue_replaced(&queue);
+ queue_top(&queue)= (uchar*) new_huff_el;
+ queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
=== modified file 'storage/myisam/sort.c'
--- a/storage/myisam/sort.c 2010-04-28 12:52:24 +0000
+++ b/storage/myisam/sort.c 2010-07-16 07:33:01 +0000
@@ -920,7 +920,7 @@ merge_buffers(MI_SORT_PARAM *info, uint
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
- (void*) info))
+ (void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -969,7 +969,7 @@ merge_buffers(MI_SORT_PARAM *info, uint
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
- VOID(queue_remove(&queue,0));
+ VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
@@ -994,7 +994,7 @@ merge_buffers(MI_SORT_PARAM *info, uint
}
else if (error == -1)
goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
=== modified file 'storage/myisammrg/myrg_queue.c'
--- a/storage/myisammrg/myrg_queue.c 2007-05-10 09:59:39 +0000
+++ b/storage/myisammrg/myrg_queue.c 2010-07-16 07:33:01 +0000
@@ -52,7 +52,7 @@ int _myrg_init_queue(MYRG_INFO *info,int
if (init_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
- info->open_tables->table->s->keyinfo[inx].seg))
+ info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
else
@@ -60,7 +60,7 @@ int _myrg_init_queue(MYRG_INFO *info,int
if (reinit_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
- info->open_tables->table->s->keyinfo[inx].seg))
+ info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
}
=== modified file 'storage/myisammrg/myrg_rnext.c'
--- a/storage/myisammrg/myrg_rnext.c 2007-05-10 09:59:39 +0000
+++ b/storage/myisammrg/myrg_rnext.c 2010-07-16 07:33:01 +0000
@@ -32,7 +32,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *b
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -43,7 +43,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *b
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
=== modified file 'storage/myisammrg/myrg_rnext_same.c'
--- a/storage/myisammrg/myrg_rnext_same.c 2007-05-10 09:59:39 +0000
+++ b/storage/myisammrg/myrg_rnext_same.c 2010-07-16 07:33:01 +0000
@@ -29,7 +29,7 @@ int myrg_rnext_same(MYRG_INFO *info, uch
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -40,7 +40,7 @@ int myrg_rnext_same(MYRG_INFO *info, uch
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
=== modified file 'storage/myisammrg/myrg_rprev.c'
--- a/storage/myisammrg/myrg_rprev.c 2007-05-10 09:59:39 +0000
+++ b/storage/myisammrg/myrg_rprev.c 2010-07-16 07:33:01 +0000
@@ -32,7 +32,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *b
{
if (err == HA_ERR_END_OF_FILE)
{
- queue_remove(&(info->by_key),0);
+ queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
@@ -43,7 +43,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *b
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
- queue_replaced(&(info->by_key));
+ queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_prev is as simple as one queue_top */
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: timour@xxxxxxxxxxxx-20100716121055-6pesx07gvsmivwm3
# target_branch: file:///home/tsk/mprog/src/5.3-mwl89/
# testament_sha1: f461345ea517df5d339f6dbbe2e7c6502d7bfd77
# timestamp: 2010-07-16 15:11:15 +0300
# source_branch: file:///home/tsk/mprog/src/5.3/
# base_revision_id: timour@xxxxxxxxxxxx-20100716105202-\
# 8narq4tzhka2n1a5
#
# Begin bundle
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