Commit 4c576fd4 authored by Michael Widenius's avatar Michael Widenius

Merge with 5.1

parents e6ba9d28 d0e8dbc4
...@@ -535,3 +535,34 @@ HAVING ...@@ -535,3 +535,34 @@ HAVING
field4 != 6; field4 != 6;
field1 field2 field3 field4 field5 field6 field1 field2 field3 field4 field5 field6
drop table t0,t1,t2,t3,t4,t5,t6; drop table t0,t1,t2,t3,t4,t5,t6;
#
# BUG#675118: Elimination of a table results in an invalid execution plan
#
CREATE TABLE t1 (f1 int(11), PRIMARY KEY (f1)) ;
CREATE TABLE t2 (f4 varchar(1024), KEY (f4)) ;
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
INSERT IGNORE INTO t2 VALUES ('xcddwntkbxyorzdv'),
('cnxxcddwntkbxyor'),('r'),('r'), ('did'),('I'),('when'),
('hczkfqjeggivdvac'),('e'),('okay'),('up');
CREATE TABLE t3 (f4 varchar(1024), f1 int(11), f2 int(11)) ;
INSERT IGNORE INTO t3 VALUES ('f','4','0'),('n','5','-996540416');
CREATE TABLE t4 (f1 int(11), f3 varchar(10)) ;
INSERT IGNORE INTO t4 VALUES ('8','n'),('9','nwzcerzsgx'),('10','c');
CREATE TABLE t5 (f5 int(11), KEY (f5)) ;
EXPLAIN
SELECT t3.f2
FROM t2
LEFT JOIN t3
LEFT JOIN t4
LEFT JOIN t1 ON t4.f1 = t1.f1
JOIN t5 ON t4.f3 ON t3.f1 = t5.f5 ON t2.f4 = t3.f4
WHERE t3.f2 ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t5 ref f5 f5 5 test.t3.f1 2 Using index
1 SIMPLE t4 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL f4 NULL NULL NULL 11 Using where; Using join buffer
# ^^ The above must not produce a QEP of t3,t5,t2,t4
# as that violates the "no interleaving of outer join nests" rule.
DROP TABLE t1,t2,t3,t4,t5;
...@@ -560,3 +560,13 @@ HANDLER t1 READ a NEXT; ...@@ -560,3 +560,13 @@ HANDLER t1 READ a NEXT;
a a
HANDLER t1 CLOSE; HANDLER t1 CLOSE;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 integer, f2 integer, primary key (f1), key (f2)) engine=innodb;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
HANDLER t1 OPEN;
HANDLER t1 READ FIRST WHERE f2 <= 1;
f1 f2
1 1
HANDLER t1 READ `PRIMARY` PREV;
f1 f2
3 3
DROP TABLE t1;
...@@ -15,3 +15,14 @@ let $engine_type= InnoDB; ...@@ -15,3 +15,14 @@ let $engine_type= InnoDB;
--source init.inc --source init.inc
--source handler.inc --source handler.inc
#
# LP#697610 ha_index_prev(uchar*): Assertion `inited==INDEX'
#
CREATE TABLE t1 (f1 integer, f2 integer, primary key (f1), key (f2)) engine=innodb;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
HANDLER t1 OPEN;
HANDLER t1 READ FIRST WHERE f2 <= 1;
HANDLER t1 READ `PRIMARY` PREV;
DROP TABLE t1;
...@@ -467,3 +467,35 @@ HAVING ...@@ -467,3 +467,35 @@ HAVING
field4 != 6; field4 != 6;
drop table t0,t1,t2,t3,t4,t5,t6; drop table t0,t1,t2,t3,t4,t5,t6;
--echo #
--echo # BUG#675118: Elimination of a table results in an invalid execution plan
--echo #
CREATE TABLE t1 (f1 int(11), PRIMARY KEY (f1)) ;
CREATE TABLE t2 (f4 varchar(1024), KEY (f4)) ;
INSERT IGNORE INTO t2 VALUES ('xcddwntkbxyorzdv'),
('cnxxcddwntkbxyor'),('r'),('r'), ('did'),('I'),('when'),
('hczkfqjeggivdvac'),('e'),('okay'),('up');
CREATE TABLE t3 (f4 varchar(1024), f1 int(11), f2 int(11)) ;
INSERT IGNORE INTO t3 VALUES ('f','4','0'),('n','5','-996540416');
CREATE TABLE t4 (f1 int(11), f3 varchar(10)) ;
INSERT IGNORE INTO t4 VALUES ('8','n'),('9','nwzcerzsgx'),('10','c');
CREATE TABLE t5 (f5 int(11), KEY (f5)) ;
EXPLAIN
SELECT t3.f2
FROM t2
LEFT JOIN t3
LEFT JOIN t4
LEFT JOIN t1 ON t4.f1 = t1.f1
JOIN t5 ON t4.f3 ON t3.f1 = t5.f5 ON t2.f4 = t3.f4
WHERE t3.f2 ;
--echo # ^^ The above must not produce a QEP of t3,t5,t2,t4
--echo # as that violates the "no interleaving of outer join nests" rule.
DROP TABLE t1,t2,t3,t4,t5;
...@@ -1321,14 +1321,18 @@ public: ...@@ -1321,14 +1321,18 @@ public:
DBUG_ENTER("ha_index_init"); DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE); DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted))) if (!(result= index_init(idx, sorted)))
inited=INDEX; {
inited= INDEX;
active_index= idx;
}
DBUG_RETURN(result); DBUG_RETURN(result);
} }
int ha_index_end() int ha_index_end()
{ {
DBUG_ENTER("ha_index_end"); DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX); DBUG_ASSERT(inited==INDEX);
inited=NONE; inited= NONE;
active_index= MAX_KEY;
DBUG_RETURN(index_end()); DBUG_RETURN(index_end());
} }
/* This is called after index_init() if we need to do a index scan */ /* This is called after index_init() if we need to do a index scan */
...@@ -1511,7 +1515,12 @@ public: ...@@ -1511,7 +1515,12 @@ public:
as there may be several calls to this routine. as there may be several calls to this routine.
*/ */
virtual void column_bitmaps_signal(); virtual void column_bitmaps_signal();
uint get_index(void) const { return active_index; } /*
We have to check for inited as some engines, like innodb, sets
active_index during table scan.
*/
uint get_index(void) const
{ return inited == INDEX ? active_index : MAX_KEY; }
virtual int close(void)=0; virtual int close(void)=0;
/** /**
...@@ -1997,8 +2006,8 @@ private: ...@@ -1997,8 +2006,8 @@ private:
*/ */
virtual int open(const char *name, int mode, uint test_if_locked)=0; virtual int open(const char *name, int mode, uint test_if_locked)=0;
virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; } virtual int index_init(uint idx, bool sorted) { return 0; }
virtual int index_end() { active_index= MAX_KEY; return 0; } virtual int index_end() { return 0; }
/** /**
rnd_init() can be called two times without rnd_end() in between rnd_init() can be called two times without rnd_end() in between
(it only makes sense if scan=1). (it only makes sense if scan=1).
......
...@@ -1781,7 +1781,7 @@ typedef struct st_nested_join ...@@ -1781,7 +1781,7 @@ typedef struct st_nested_join
2. All child join nest nodes are fully covered. 2. All child join nest nodes are fully covered.
*/ */
bool is_fully_covered() const { return join_list.elements == counter; } bool is_fully_covered() const { return n_tables == counter; }
} NESTED_JOIN; } NESTED_JOIN;
......
...@@ -2453,7 +2453,6 @@ int ha_federated::index_init(uint keynr, bool sorted) ...@@ -2453,7 +2453,6 @@ int ha_federated::index_init(uint keynr, bool sorted)
{ {
DBUG_ENTER("ha_federated::index_init"); DBUG_ENTER("ha_federated::index_init");
DBUG_PRINT("info", ("table: '%s' key: %u", table->s->table_name.str, keynr)); DBUG_PRINT("info", ("table: '%s' key: %u", table->s->table_name.str, keynr));
active_index= keynr;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2589,7 +2588,6 @@ int ha_federated::index_end(void) ...@@ -2589,7 +2588,6 @@ int ha_federated::index_end(void)
{ {
DBUG_ENTER("ha_federated::index_end"); DBUG_ENTER("ha_federated::index_end");
free_result(); free_result();
active_index= MAX_KEY;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -228,7 +228,7 @@ static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size, ...@@ -228,7 +228,7 @@ static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size,
"The size of the buffer used for index blocks for Aria tables. " "The size of the buffer used for index blocks for Aria tables. "
"Increase this to get better index handling (for all reads and " "Increase this to get better index handling (for all reads and "
"multiple writes) to as much as you can afford.", 0, 0, "multiple writes) to as much as you can afford.", 0, 0,
KEY_CACHE_SIZE, 0, ~(ulong) 0, 1); KEY_CACHE_SIZE, 8192*16L, ~(ulong) 0, 1);
static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit, static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
......
/* Copyright (C) 2000-2008 MySQL AB /* Copyright (C) 2000-2008 MySQL AB, 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -760,6 +760,8 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, ...@@ -760,6 +760,8 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
{ {
if (blocks < 8) if (blocks < 8)
{ {
my_message(ENOMEM, "Not enough memory to allocate 8 pagecache pages",
MYF(0));
my_errno= ENOMEM; my_errno= ENOMEM;
goto err; goto err;
} }
...@@ -4214,6 +4216,7 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) ...@@ -4214,6 +4216,7 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
DBUG_ASSERT(block->rlocks == 0); DBUG_ASSERT(block->rlocks == 0);
DBUG_ASSERT(block->rlocks_queue == 0); DBUG_ASSERT(block->rlocks_queue == 0);
DBUG_ASSERT(block->pins == 0); DBUG_ASSERT(block->pins == 0);
DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED)) == 0);
block->status= 0; block->status= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE; block->type= PAGECACHE_EMPTY_PAGE;
...@@ -4542,6 +4545,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -4542,6 +4545,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
KEYCACHE_DBUG_ASSERT(count<= pagecache->blocks_used); KEYCACHE_DBUG_ASSERT(count<= pagecache->blocks_used);
} }
} }
count++; /* Allocate one extra for easy end-of-buffer test */
/* Allocate a new buffer only if its bigger than the one we have */ /* Allocate a new buffer only if its bigger than the one we have */
if (count > FLUSH_CACHE && if (count > FLUSH_CACHE &&
!(cache= !(cache=
...@@ -4578,6 +4582,13 @@ restart: ...@@ -4578,6 +4582,13 @@ restart:
break; break;
DBUG_ASSERT(filter_res == FLUSH_FILTER_OK); DBUG_ASSERT(filter_res == FLUSH_FILTER_OK);
} }
{
DBUG_ASSERT(!(block->status & PCBLOCK_IN_FLUSH));
/*
We care only for the blocks for which flushing was not
initiated by other threads as a result of page swapping
*/
if (! (block->status & PCBLOCK_IN_SWITCH))
{ {
/* /*
Mark the block with BLOCK_IN_FLUSH in order not to let Mark the block with BLOCK_IN_FLUSH in order not to let
...@@ -4586,15 +4597,10 @@ restart: ...@@ -4586,15 +4597,10 @@ restart:
*/ */
block->status|= PCBLOCK_IN_FLUSH; block->status|= PCBLOCK_IN_FLUSH;
if (! (block->status & PCBLOCK_IN_SWITCH))
{
/*
We care only for the blocks for which flushing was not
initiated by other threads as a result of page swapping
*/
reg_requests(pagecache, block, 1); reg_requests(pagecache, block, 1);
if (type != FLUSH_IGNORE_CHANGED) if (type != FLUSH_IGNORE_CHANGED)
{ {
*pos++= block;
/* It's not a temporary file */ /* It's not a temporary file */
if (pos == end) if (pos == end)
{ {
...@@ -4614,7 +4620,6 @@ restart: ...@@ -4614,7 +4620,6 @@ restart:
*/ */
goto restart; goto restart;
} }
*pos++= block;
} }
else else
{ {
......
...@@ -192,14 +192,18 @@ static struct my_option my_long_options[] = ...@@ -192,14 +192,18 @@ static struct my_option my_long_options[] =
{"display-only", 'd', "display brief info read from records' header", {"display-only", 'd', "display brief info read from records' header",
&opt_display_only, &opt_display_only, 0, GET_BOOL, &opt_display_only, &opt_display_only, 0, GET_BOOL,
NO_ARG,0, 0, 0, 0, 0, 0}, NO_ARG,0, 0, 0, 0, 0, 0},
{ "end-lsn", 'e', "Stop applying at this lsn. If end-lsn is used, UNDO:s "
"will not be applied", &opt_end_lsn, &opt_end_lsn,
0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 },
{"aria-log-dir-path", 'l', {"aria-log-dir-path", 'l',
"Path to the directory where to store transactional log", "Path to the directory where to store transactional log",
(uchar **) &maria_data_root, (uchar **) &maria_data_root, 0, (uchar **) &maria_data_root, (uchar **) &maria_data_root, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "page-buffer-size", 'P', "", { "page-buffer-size", 'P',
"The size of the buffer used for index blocks for Maria tables",
&opt_page_buffer_size, &opt_page_buffer_size, 0, &opt_page_buffer_size, &opt_page_buffer_size, 0,
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
(long) USE_BUFFER_INIT, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD, 1024L*1024L, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
(long) IO_SIZE, 0}, (long) IO_SIZE, 0},
{ "start-from-lsn", 'o', "Start reading log from this lsn", { "start-from-lsn", 'o', "Start reading log from this lsn",
&opt_start_from_lsn, &opt_start_from_lsn, &opt_start_from_lsn, &opt_start_from_lsn,
...@@ -207,18 +211,12 @@ static struct my_option my_long_options[] = ...@@ -207,18 +211,12 @@ static struct my_option my_long_options[] =
{"start-from-checkpoint", 'C', "Start applying from last checkpoint", {"start-from-checkpoint", 'C', "Start applying from last checkpoint",
&opt_start_from_checkpoint, &opt_start_from_checkpoint, 0, &opt_start_from_checkpoint, &opt_start_from_checkpoint, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "end-lsn", 'e', "Stop applying at this lsn. If end-lsn is used, UNDO:s "
"will not be applied", &opt_end_lsn, &opt_end_lsn,
0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 },
{"silent", 's', "Print less information during apply/undo phase", {"silent", 's', "Print less information during apply/undo phase",
&opt_silent, &opt_silent, 0, &opt_silent, &opt_silent, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"tables-to-redo", 'T', {"tables-to-redo", 'T',
"List of tables sepearated with , that we should apply REDO on. Use this if you only want to recover some tables", "List of tables sepearated with , that we should apply REDO on. Use this if you only want to recover some tables",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Print more information during apply/undo phase",
&maria_recovery_verbose, &maria_recovery_verbose, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, " {"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, "
"separated by " "separated by "
#if defined( __WIN__) || defined(__NETWARE__) #if defined( __WIN__) || defined(__NETWARE__)
...@@ -230,6 +228,9 @@ static struct my_option my_long_options[] = ...@@ -230,6 +228,9 @@ static struct my_option my_long_options[] =
{"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)", {"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)",
(uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0, (uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"verbose", 'v', "Print more information during apply/undo phase",
&maria_recovery_verbose, &maria_recovery_verbose, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Print version and exit.", {"version", 'V', "Print version and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment